From 451c8e45200aeb67c56d42e5398e7c12466b30d6 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Fri, 2 Dec 2016 12:16:50 +0100 Subject: [PATCH 1/4] configure.ac: adapt to openssl-1.1 openssl-1.1 removed the function CRYPTO_lock() which was used in the configure script to check for openssl availability. This changes CRYPTO_lock() to HMAC_Update(). Fixes: #125 Signed-off-by: Adrian Reber --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index c8a933c5..d38e2904 100644 --- a/configure.ac +++ b/configure.ac @@ -406,9 +406,9 @@ if test "x-$want_ssl" != "x-no" ; then fi AC_CHECK_HEADERS(openssl/crypto.h) if test "x-$ac_cv_header_openssl_crypto_h" = "x-yes" ; then - AC_CHECK_LIB(crypto, CRYPTO_lock) + AC_CHECK_LIB(crypto, HMAC_Update) fi - if test "x-$ac_cv_lib_crypto_CRYPTO_lock" = "x-yes" ; then + if test "x-$ac_cv_lib_crypto_HMAC_Update" = "x-yes" ; then AC_CHECK_HEADERS(openssl/ssl.h) fi if test "x-$ac_cv_header_openssl_ssl_h" = "x-yes" ; then From 28360f3e33f53033343e09e924302c651624d2ca Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Fri, 2 Dec 2016 12:20:29 +0100 Subject: [PATCH 2/4] authreg_ldapfull: adapt to openssl-1.1 Adding #ifdefs to use the new openssl-1.1 API if detected. Fixes: #125 Signed-off-by: Adrian Reber --- storage/authreg_ldapfull.c | 104 ++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 13 deletions(-) diff --git a/storage/authreg_ldapfull.c b/storage/authreg_ldapfull.c index 7b32d48a..543f9c4a 100644 --- a/storage/authreg_ldapfull.c +++ b/storage/authreg_ldapfull.c @@ -39,6 +39,7 @@ #ifdef HAVE_SSL #include +#include #endif #include @@ -228,13 +229,18 @@ int _ldapfull_base64_decode( const char *src, const unsigned char **ret, int *rl int rc, tlen = 0; int i; unsigned char *text; +#if OPENSSL_VERSION_NUMBER < 0x10100005L EVP_ENCODE_CTX EVP_ctx; +#else + EVP_ENCODE_CTX *EVP_ctx; +#endif text = (unsigned char *)malloc(((strlen(src)+3)/4 * 3) + 1); if (text == NULL) { return 0; } +#if OPENSSL_VERSION_NUMBER < 0x10100005L EVP_DecodeInit(&EVP_ctx); rc = EVP_DecodeUpdate(&EVP_ctx, text, &i, (const unsigned char *)src, strlen(src)); if (rc < 0) { @@ -243,40 +249,69 @@ int _ldapfull_base64_decode( const char *src, const unsigned char **ret, int *rl } tlen+=i; EVP_DecodeFinal(&EVP_ctx, (unsigned char*)text, &i); +#else + EVP_ctx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(EVP_ctx); + rc = EVP_DecodeUpdate(EVP_ctx, text, &i, (const unsigned char *)src, strlen(src)); + if (rc < 0) { + free(text); + EVP_ENCODE_CTX_free(EVP_ctx); + return 0; + } + tlen+=i; + EVP_DecodeFinal(EVP_ctx, (unsigned char*)text, &i); +#endif *ret = text; if (rlen != NULL) { *rlen = tlen; } +#if !(OPENSSL_VERSION_NUMBER < 0x10100005L) + EVP_ENCODE_CTX_free(EVP_ctx); +#endif return 1; } static int _ldapfull_base64_encode( const unsigned char *src, int srclen, char **ret, int *rlen ) { int tlen = 0; unsigned char *text; +#if OPENSSL_VERSION_NUMBER < 0x10100005L EVP_ENCODE_CTX EVP_ctx; +#else + EVP_ENCODE_CTX *EVP_ctx; +#endif text = (unsigned char *)malloc((srclen*4/3) + 1 ); if (text == NULL) { return 0; } +#if OPENSSL_VERSION_NUMBER < 0x10100005L EVP_EncodeInit(&EVP_ctx); EVP_EncodeUpdate(&EVP_ctx, text, &tlen, src, srclen); EVP_EncodeFinal(&EVP_ctx, text, &tlen); +#else + EVP_ctx = EVP_ENCODE_CTX_new(); + EVP_EncodeInit(EVP_ctx); + EVP_EncodeUpdate(EVP_ctx, text, &tlen, src, srclen); + EVP_EncodeFinal(EVP_ctx, text, &tlen); +#endif *ret = (char*)text; if (rlen != NULL) { *rlen = tlen; } +#if !(OPENSSL_VERSION_NUMBER < 0x10100005L) + EVP_ENCODE_CTX_free(EVP_ctx); +#endif return 1; } int _ldapfull_chk_hashed(moddata_t data, const char *scheme, int salted, const char *hash, const char *passwd) { const unsigned char *bhash; // binary hash, will get it from base64 - EVP_MD_CTX mdctx; + EVP_MD_CTX *mdctx; const EVP_MD *md; unsigned char digest[EVP_MAX_MD_SIZE]; int bhlen, rc; @@ -289,22 +324,32 @@ int _ldapfull_chk_hashed(moddata_t data, const char *scheme, int salted, const c return 0; } - EVP_DigestInit(&mdctx, md); - EVP_DigestUpdate(&mdctx, passwd, strlen(passwd)); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + mdctx = EVP_MD_CTX_create(); +#else + mdctx = EVP_MD_CTX_new(); +#endif + EVP_DigestInit(mdctx, md); + EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); if (salted) { - EVP_DigestUpdate(&mdctx, &bhash[EVP_MD_size(md)], + EVP_DigestUpdate(mdctx, &bhash[EVP_MD_size(md)], bhlen - EVP_MD_size(md)); } - EVP_DigestFinal(&mdctx, digest, NULL); + EVP_DigestFinal(mdctx, digest, NULL); rc = memcmp((char *)bhash, (char *)digest, EVP_MD_size(md)); free((void*)bhash); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif return !rc; } int _ldapfull_set_hashed(moddata_t data, const char *scheme, const char *prefix, int saltlen, const char *passwd, char *buf, int buflen) { char *hash = 0; // base64 hash - EVP_MD_CTX mdctx; + EVP_MD_CTX *mdctx; const EVP_MD *md; unsigned char *digest; unsigned char *salt; @@ -316,30 +361,48 @@ int _ldapfull_set_hashed(moddata_t data, const char *scheme, const char *prefix, if (!md) { return 0; } - EVP_DigestInit(&mdctx, md); - EVP_DigestUpdate(&mdctx, passwd, strlen(passwd)); + +#if OPENSSL_VERSION_NUMBER < 0x10100005L + mdctx = EVP_MD_CTX_create(); +#else + mdctx = EVP_MD_CTX_new(); +#endif + EVP_DigestInit(mdctx, md); + EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); if (saltlen) { salt = (unsigned char *)malloc(saltlen); if( !salt ) { - EVP_MD_CTX_cleanup(&mdctx); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif return 0; } if( !RAND_bytes(salt,saltlen) ) { - EVP_MD_CTX_cleanup(&mdctx); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif free(salt); return 0; } - EVP_DigestUpdate(&mdctx, salt, saltlen); + EVP_DigestUpdate(mdctx, salt, saltlen); } digest = (unsigned char *)malloc(EVP_MD_size(md) + saltlen); if( !digest ) { if (saltlen) { free(salt); } - EVP_MD_CTX_cleanup(&mdctx); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif return 0; } - EVP_DigestFinal(&mdctx, digest, &dlen); + EVP_DigestFinal(mdctx, digest, &dlen); memcpy(digest+dlen,salt,saltlen); if (saltlen) { @@ -352,6 +415,11 @@ int _ldapfull_set_hashed(moddata_t data, const char *scheme, const char *prefix, free(digest); if( !rc ) { free(hash); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif return 0; } @@ -359,12 +427,22 @@ int _ldapfull_set_hashed(moddata_t data, const char *scheme, const char *prefix, if( hlen + plen >= buflen ) { log_write(data->ar->c2s->log,LOG_ERR,"_ldapfull_set_hashed: buffer is too short (%i bytes)",buflen); free(hash); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif return 0; } memcpy(buf,prefix,plen); memcpy(buf+plen,hash,hlen); buf[hlen+plen]='\0'; free(hash); +#if OPENSSL_VERSION_NUMBER < 0x10100005L + EVP_MD_CTX_destroy(mdctx); +#else + EVP_MD_CTX_free(mdctx); +#endif return 1; } From 3c113ad1da79e76510d22c7ab03ad67c46eb82f1 Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Fri, 2 Dec 2016 15:33:48 +0100 Subject: [PATCH 3/4] sx/ssl.c: adapt to openssl-1.1 Adding #ifdefs to use the new openssl-1.1 API if detected. Fixes: #125 Signed-off-by: Adrian Reber --- sx/ssl.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/sx/ssl.c b/sx/ssl.c index 208ebb62..85fb709d 100644 --- a/sx/ssl.c +++ b/sx/ssl.c @@ -70,7 +70,7 @@ static int _sx_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) */ if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) { - X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); + X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, 256); _sx_debug(ZONE, "issuer= %s\n", buf); } @@ -115,12 +115,27 @@ static DH *sx_ssl_make_dh_params(BIGNUM *(*const get_prime)(BIGNUM *), const cha if (!dh) return NULL; +#if OPENSSL_VERSION_NUMBER < 0x10100005L dh->p = get_prime(NULL); BN_dec2bn(&dh->g, gen); if (!dh->p || !dh->g) { DH_free(dh); return NULL; } +#else + { + BIGNUM *p, *g; + p = get_prime(NULL); + BN_dec2bn(&g, gen); + + if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) { + DH_free(dh); + BN_free(p); + BN_free(g); + return NULL; + } + } +#endif return dh; } @@ -134,7 +149,7 @@ static void sx_ssl_free_dh_params(void) { static DH *_sx_ssl_tmp_dh_callback(SSL *ssl, int export, int keylen) { EVP_PKEY *pkey = SSL_get_privatekey(ssl); - int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE; + int type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE; unsigned i; if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) @@ -351,7 +366,11 @@ static void _sx_ssl_get_external_id(sx_t s, _sx_ssl_conn_t sc) { } else if (altname->type == GEN_DNS) { len = ASN1_STRING_length(altname->d.dNSName); sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1)); +#if OPENSSL_VERSION_NUMBER < 0x10100005L memcpy(sc->external_id[id], ASN1_STRING_data(altname->d.dNSName), len); +#else + memcpy(sc->external_id[id], ASN1_STRING_get0_data(altname->d.dNSName), len); +#endif sc->external_id[id][len] = '\0'; // just to make sure _sx_debug(ZONE, "external_id: Found(%d) subjectAltName/dNSName: '%s'", id, sc->external_id[id]); id++; @@ -728,11 +747,15 @@ static void _sx_ssl_client(sx_t s, sx_plugin_t p) { SSL_set_bio(sc->ssl, sc->rbio, sc->wbio); SSL_set_connect_state(sc->ssl); SSL_set_options(sc->ssl, SSL_OP_NO_TICKET); +#if OPENSSL_VERSION_NUMBER < 0x10100005L #ifdef ENABLE_EXPERIMENTAL SSL_set_ssl_method(sc->ssl, TLSv1_2_client_method()); #else SSL_set_ssl_method(sc->ssl, TLSv1_client_method()); #endif +#else + SSL_set_ssl_method(sc->ssl, TLS_client_method()); +#endif /* empty external_id */ for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++) @@ -761,8 +784,8 @@ static void _sx_ssl_client(sx_t s, sx_plugin_t p) { } /* set callback giving a password for pemfile */ - SSL_CTX_set_default_passwd_cb_userdata(sc->ssl->ctx, (void *)pemfile_password); - SSL_CTX_set_default_passwd_cb(sc->ssl->ctx, &_sx_pem_passwd_callback); + SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *)pemfile_password); + SSL_CTX_set_default_passwd_cb(ctx, &_sx_pem_passwd_callback); /* load the private key */ ret = SSL_use_PrivateKey_file(sc->ssl, pemfile, SSL_FILETYPE_PEM); @@ -977,10 +1000,14 @@ int sx_ssl_server_addcert(sx_plugin_t p, const char *name, const char *pemfile, ERR_clear_error(); /* create the context */ +#if OPENSSL_VERSION_NUMBER < 0x10100005L #ifdef ENABLE_EXPERIMENTAL ctx = SSL_CTX_new(TLSv1_2_method()); #else ctx = SSL_CTX_new(SSLv23_method()); +#endif +#else + ctx = SSL_CTX_new(TLS_method()); #endif if(ctx == NULL) { _sx_debug(ZONE, "ssl context creation failed; %s", ERR_error_string(ERR_get_error(), NULL)); @@ -1063,7 +1090,11 @@ int sx_ssl_server_addcert(sx_plugin_t p, const char *name, const char *pemfile, /* try to read DH params from pem file */ if((dhparams = sx_ssl_get_DHparams(pemfile))) { SSL_CTX_set_tmp_dh(ctx, dhparams); +#if OPENSSL_VERSION_NUMBER < 0x10100005L _sx_debug(ZONE, "custom DH parameters loaded from certificate", BN_num_bits(dhparams->p)); +#else + _sx_debug(ZONE, "custom DH parameters loaded from certificate", DH_bits(dhparams)); +#endif } /* try to read ECDH params from pem file */ From 181e736dcbb19c828266d88837f4343510b4d20e Mon Sep 17 00:00:00 2001 From: Oleg Girko Date: Fri, 22 Sep 2017 22:18:34 +0100 Subject: [PATCH 4/4] sx/ssl.c: fix undefined behaviour with openssl-1.1 BN_dec2bn in OpenSSL 1.1 requires its first argument to point to either pointer to initialised BIGNUM or NULL. Using pointer to uninitialised pointer to BIGNUM is undefined behaviour causing coredumps or other memory corruption. This change fixes missing initialisation overlooked when porting to OpenSSL 1.1 API. Signed-off-by: Oleg Girko --- sx/ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sx/ssl.c b/sx/ssl.c index 85fb709d..476748f1 100644 --- a/sx/ssl.c +++ b/sx/ssl.c @@ -124,7 +124,7 @@ static DH *sx_ssl_make_dh_params(BIGNUM *(*const get_prime)(BIGNUM *), const cha } #else { - BIGNUM *p, *g; + BIGNUM *p, *g = NULL; p = get_prime(NULL); BN_dec2bn(&g, gen);