diff options
-rw-r--r-- | accel-pppd/accel-ppp.conf | 9 | ||||
-rw-r--r-- | accel-pppd/ctrl/sstp/sstp.c | 188 | ||||
-rw-r--r-- | accel-pppd/ctrl/sstp/sstp_prot.h | 4 |
3 files changed, 181 insertions, 20 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index ee9f7f5c..a4a4a714 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -110,10 +110,13 @@ verbose=1 [sstp] verbose=1 +#cert-hash-proto=sha1,sha256 +#cert-hash-sha1= +#cert-hash-sha256= #ssl=1 -#ssl_ciphers=HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4 -#ssl_ca_file=/etc/ssl/sstp-ca.crt -#ssl_pemfile=/etc/ssl/sstp.pem +#ssl-ciphers=HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4 +#ssl-ca-file=/etc/ssl/sstp-ca.crt +#ssl-pemfile=/etc/ssl/sstp.pem #timeout=60 #hello-interval=60 #ip-pool=sstp diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index a7c13353..281c3320 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -71,6 +71,13 @@ #define PPP_F_ESCAPE 1 #define PPP_F_TOSS 2 +#ifndef SHA_DIGEST_LENGTH +#define SHA_DIGEST_LENGTH 20 +#endif +#ifndef SHA256_DIGEST_LENGTH +#define SHA256_DIGEST_LENGTH 32 +#endif + enum { STATE_INIT = 0, STATE_STARTING, @@ -78,6 +85,11 @@ enum { STATE_FINISHED, }; +struct hash_t { + unsigned int len; + uint8_t hash[32]; +}; + struct buffer_t { struct list_head entry; size_t len; @@ -139,22 +151,28 @@ struct sstp_conn_t { static struct sstp_serv_t { struct triton_context_t ctx; struct triton_md_handler_t hnd; - - uint8_t certificate_hash[32]; } serv; static int conf_timeout = SSTP_NEGOTIOATION_TIMEOUT; static int conf_hello_interval = SSTP_HELLO_TIMEOUT; static int conf_verbose = 0; static int conf_ppp_max_mtu = 1456; -static int conf_hash_protocol = CERT_HASH_PROTOCOL_SHA256; -//static int conf_bypass_auth = 0; static const char *conf_ip_pool; static const char *conf_ifname; + +static int conf_hash_protocol = CERT_HASH_PROTOCOL_SHA1 | CERT_HASH_PROTOCOL_SHA256; +static struct hash_t conf_hash_sha1 = { .len = 0 }; +static struct hash_t conf_hash_sha256 = { .len = 0 }; +//static int conf_bypass_auth = 0; + +#ifdef CRYPTO_OPENSSL +static X509 *conf_ssl_cert = NULL; +static EVP_PKEY *conf_ssl_pkey = NULL; + +static const char *conf_ssl_ca_file = NULL; +static const char *conf_ssl_ciphers = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"; static int conf_ssl = 1; -static char *conf_ssl_ciphers = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"; -static char *conf_ssl_ca_file = NULL; -static char *conf_ssl_pemfile = NULL; +#endif static mempool_t conn_pool; @@ -1138,6 +1156,21 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct if (conn->nonce && memcmp(msg->attr.nonce, conn->nonce, SSTP_NONCE_SIZE) != 0) return sstp_abort(conn, 0); + switch (msg->attr.hash_protocol_bitmask & conf_hash_protocol) { + case CERT_HASH_PROTOCOL_SHA1: + if (conf_hash_sha1.len == SHA_DIGEST_LENGTH && + memcmp(msg->attr.cert_hash, conf_hash_sha1.hash, SHA_DIGEST_LENGTH) != 0) + return sstp_abort(conn, 0); + break; + case CERT_HASH_PROTOCOL_SHA256: + if (conf_hash_sha256.len == SHA256_DIGEST_LENGTH && + memcmp(msg->attr.cert_hash, conf_hash_sha256.hash, SHA256_DIGEST_LENGTH) != 0) + return sstp_abort(conn, 0); + break; + default: + return sstp_abort(conn, 0); + } + conn->sstp_state = STATE_SERVER_CALL_CONNECTED; _free(conn->nonce); @@ -1660,9 +1693,9 @@ static void sstp_start(struct sstp_conn_t *conn) log_sstp_error(conn, "SSL ca file error: %s\n", ERR_error_string(ERR_get_error(), NULL)); goto error; } - if (!conf_ssl_pemfile || - SSL_CTX_use_certificate_file(conn->ssl_ctx, conf_ssl_pemfile, SSL_FILETYPE_PEM) != 1 || - SSL_CTX_use_PrivateKey_file(conn->ssl_ctx, conf_ssl_pemfile, SSL_FILETYPE_PEM) != 1 || + if (!conf_ssl_cert || !conf_ssl_pkey || + SSL_CTX_use_certificate(conn->ssl_ctx, conf_ssl_cert) != 1 || + SSL_CTX_use_PrivateKey(conn->ssl_ctx, conf_ssl_pkey) != 1 || SSL_CTX_check_private_key(conn->ssl_ctx) != 1) { log_sstp_error(conn, "SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL)); goto error; @@ -1818,21 +1851,148 @@ static void sstp_serv_close(struct triton_context_t *ctx) triton_context_unregister(ctx); #ifdef CRYPTO_OPENSSL + if (conf_ssl_cert) + X509_free(conf_ssl_cert); + conf_ssl_cert = NULL; + + if (conf_ssl_pkey) + EVP_PKEY_free(conf_ssl_pkey); + conf_ssl_pkey = NULL; + CRYPTO_thread_cleanup(); #endif } +static int strhas(const char *s1, const char *s2, int delim) +{ + char *ptr; + int n = strlen(s2); + + while ((ptr = strchr(s1, delim))) { + if (ptr - s1 == n && memcmp(s1, s2, n) == 0) + return 0; + s1 = ++ptr; + } + return strcmp(s1, s2); +} + +static int hex2bin(const char *src, uint8_t *dst, size_t size) +{ + char buf[3], *err; + int n; + + memset(buf, 0, sizeof(buf)); + for (n = 0; n < size && src[0] && src[1]; n++) { + buf[0] = *src++; + buf[1] = *src++; + dst[n] = strtoul(buf, &err, 16); + if (err == buf || *err) + break; + } + return n; +} + static void load_config(void) { char *opt; + opt = conf_get_opt("sstp", "cert-hash-proto"); + if (opt) { + conf_hash_protocol = 0; + if (strhas(opt, "sha1", ',') == 0) + conf_hash_protocol |= CERT_HASH_PROTOCOL_SHA1; + if (strhas(opt, "sha256", ',') == 0) + conf_hash_protocol |= CERT_HASH_PROTOCOL_SHA256; + } + + memset(&conf_hash_sha1, 0, sizeof(conf_hash_sha1)); + memset(&conf_hash_sha256, 0, sizeof(conf_hash_sha256)); + +#ifdef CRYPTO_OPENSSL + if (conf_ssl_cert) { + X509_free(conf_ssl_cert); + conf_ssl_cert = NULL; + } + if (conf_ssl_pkey) { + EVP_PKEY_free(conf_ssl_pkey); + conf_ssl_pkey = NULL; + } + opt = conf_get_opt("sstp", "ssl"); if (opt) conf_ssl = atoi(opt); - conf_ssl_ciphers = conf_get_opt("sstp", "ssl_ciphers"); - conf_ssl_ca_file = conf_get_opt("sstp", "ssl_ca_file"); - conf_ssl_pemfile = conf_get_opt("sstp", "ssl_pemfile"); + conf_ssl_ciphers = conf_get_opt("sstp", "ssl-ciphers"); + + conf_ssl_ca_file = conf_get_opt("sstp", "ssl-ca-file"); + + opt = conf_get_opt("sstp", "ssl-pemfile"); + if (opt) { + BIO *in; + + in = BIO_new(BIO_s_file_internal()); + if (!in) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL)); + goto done; + } + + if (BIO_read_filename(in, opt) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL)); + goto done; + } + + conf_ssl_cert = PEM_read_bio_X509(in, NULL, NULL, NULL); + if (!conf_ssl_cert) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB); + log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL)); + goto done; + } + + if (conf_hash_protocol & CERT_HASH_PROTOCOL_SHA1) { + X509_digest(conf_ssl_cert, EVP_sha1(), + conf_hash_sha1.hash, &conf_hash_sha1.len); + } + + if (conf_hash_protocol & CERT_HASH_PROTOCOL_SHA256) { + X509_digest(conf_ssl_cert, EVP_sha256(), + conf_hash_sha256.hash, &conf_hash_sha256.len); + } + + if (!conf_ssl) + goto done; + + if (BIO_read_filename(in, opt) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL)); + goto done; + } + + conf_ssl_pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); + if (!conf_ssl_pkey) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_PEM_LIB); + log_error("sstp: SSL certificate error: %s\n", ERR_error_string(ERR_get_error(), NULL)); + goto done; + } + + done: + if (in) + BIO_free(in); + } +#endif + + opt = conf_get_opt("sstp", "cert-hash-sha1"); + if (opt) { + conf_hash_sha1.len = hex2bin(opt, + conf_hash_sha1.hash, sizeof(conf_hash_sha1.hash)); + } + + opt = conf_get_opt("sstp", "cert-hash-sha256"); + if (opt) { + conf_hash_sha256.len = hex2bin(opt, + conf_hash_sha256.hash, sizeof(conf_hash_sha256.hash)); + } opt = conf_get_opt("sstp", "timeout"); if (opt && atoi(opt) > 0) @@ -1865,8 +2025,6 @@ static void load_config(void) /* Makes compiler happy */ break; } - - //read(urandom_fd, &serv.certificate_hash, sizeof(serv.certificate_hash)); } static struct sstp_serv_t serv = { diff --git a/accel-pppd/ctrl/sstp/sstp_prot.h b/accel-pppd/ctrl/sstp/sstp_prot.h index 0e5785fd..f9f78d88 100644 --- a/accel-pppd/ctrl/sstp/sstp_prot.h +++ b/accel-pppd/ctrl/sstp/sstp_prot.h @@ -130,8 +130,8 @@ struct sstp_attrib_crypto_binding { uint8_t reserved[3]; uint8_t hash_protocol_bitmask; uint8_t nonce[SSTP_NONCE_SIZE]; - uint8_t cert_hash[SSTP_NONCE_SIZE]; - uint8_t compound_mac[SSTP_NONCE_SIZE]; + uint8_t cert_hash[32]; + uint8_t compound_mac[32]; } __attribute__((packed)); struct sstp_attrib_crypto_binding_request { |