changeset 20631:c085a469d8d6

openssl: Fix v1.1 compability
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Tue, 09 Aug 2016 11:48:10 +0300
parents b1831491a9d7
children 6c40ae42ba14
files src/lib-dcrypt/dcrypt-openssl.c src/lib-ssl-iostream/dovecot-openssl-common.c src/lib-ssl-iostream/iostream-openssl-common.c src/lib-ssl-iostream/iostream-openssl.c src/login-common/ssl-proxy-openssl.c
diffstat 5 files changed, 61 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-dcrypt/dcrypt-openssl.c	Mon Aug 08 15:31:50 2016 +0300
+++ b/src/lib-dcrypt/dcrypt-openssl.c	Tue Aug 09 11:48:10 2016 +0300
@@ -67,9 +67,10 @@
   2<tab>key algo oid<tab>1<tab>symmetric algo name<tab>salt<tab>hash algo<tab>rounds<tab>E(RSA = i2d_PrivateKey, EC=Private Point)<tab>key id
 **/
 
-#if SSLEAY_VERSION_NUMBER < 0x1010000fL
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 #define EVP_PKEY_get0_EC_KEY(x) x->pkey.ec
 #define EVP_PKEY_get0_RSA(x) x->pkey.rsa
+#define OBJ_length(o) ((o)->length)
 #endif
 
 struct dcrypt_context_symmetric {
@@ -89,7 +90,7 @@
 struct dcrypt_context_hmac {
 	pool_t pool;
 	const EVP_MD *md;
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	HMAC_CTX *ctx;
 #else
 	HMAC_CTX ctx;
@@ -426,7 +427,7 @@
 void dcrypt_openssl_ctx_hmac_destroy(struct dcrypt_context_hmac **ctx)
 {
 	pool_t pool = (*ctx)->pool;
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	if ((*ctx)->ctx) HMAC_CTX_free((*ctx)->ctx);
 #else
 	HMAC_cleanup(&((*ctx)->ctx));
@@ -469,12 +470,11 @@
 {
 	int ec;
 	i_assert(ctx->md != NULL);
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	ctx->ctx = HMAC_CTX_new();
 	if (ctx->ctx == NULL) return dcrypt_openssl_error(error_r);
 	ec = HMAC_Init_ex(ctx->ctx, ctx->key, ctx->klen, ctx->md, NULL);
 #else
-	HMAC_CTX_init(&ctx->ctx);
 	ec = HMAC_Init_ex(&(ctx->ctx), ctx->key, ctx->klen, ctx->md, NULL);
 #endif
 	if (ec != 1) return dcrypt_openssl_error(error_r);
@@ -484,7 +484,7 @@
 bool dcrypt_openssl_ctx_hmac_update(struct dcrypt_context_hmac *ctx, const unsigned char *data, size_t data_len, const char **error_r)
 {
 	int ec;
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	ec = HMAC_Update(ctx->ctx, data, data_len);
 #else
 	ec = HMAC_Update(&(ctx->ctx), data, data_len);
@@ -498,7 +498,7 @@
 	int ec;
 	unsigned char buf[HMAC_MAX_MD_CBLOCK];
 	unsigned int outl;
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	ec = HMAC_Final(ctx->ctx, buf, &outl);
 	HMAC_CTX_free(ctx->ctx);
 	ctx->ctx = NULL;
@@ -2028,12 +2028,15 @@
 	ASN1_OBJECT *obj = OBJ_txt2obj(name, 0);
 	if (obj == NULL)
 		return dcrypt_openssl_error(error_r);
-	if (obj->length == 0) {
+
+	size_t len =  OBJ_length(obj);
+	if (len == 0)
+	{
 		if (error_r != NULL)
 			*error_r = "Object has no OID assigned";
 		return FALSE;
 	}
-	unsigned char *bufptr = buffer_append_space_unsafe(oid, obj->length + 2);
+	unsigned char *bufptr = buffer_append_space_unsafe(oid, len + 2);
 	i2d_ASN1_OBJECT(obj, &bufptr);
 	ASN1_OBJECT_free(obj);
 	if (bufptr != NULL) {
@@ -2127,7 +2130,7 @@
 	long len = BIO_get_mem_data(b, &ptr);
 	unsigned int hlen = sizeof(buf);
 	/* then hash it */
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	EVP_MD_CTX *ctx = EVP_MD_CTX_new();
 #else
 	EVP_MD_CTX *ctx = EVP_MD_CTX_create();
@@ -2141,7 +2144,7 @@
 		buffer_append(result, buf, hlen);
 		res = TRUE;
 	}
-#if SSLEAY_VERSION_NUMBER >= 0x1010000fL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	EVP_MD_CTX_free(ctx);
 #else
 	EVP_MD_CTX_destroy(ctx);
--- a/src/lib-ssl-iostream/dovecot-openssl-common.c	Mon Aug 08 15:31:50 2016 +0300
+++ b/src/lib-ssl-iostream/dovecot-openssl-common.c	Tue Aug 09 11:48:10 2016 +0300
@@ -10,7 +10,11 @@
 static int openssl_init_refcount = 0;
 static ENGINE *dovecot_openssl_engine;
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static void *dovecot_openssl_malloc(size_t size, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED)
+#else
 static void *dovecot_openssl_malloc(size_t size)
+#endif
 {
 	/* this may be performance critical, so don't use
 	   i_malloc() or calloc() */
@@ -22,7 +26,11 @@
 	return mem;
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static void *dovecot_openssl_realloc(void *ptr, size_t size, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED)
+#else
 static void *dovecot_openssl_realloc(void *ptr, size_t size)
+#endif
 {
 	void *mem = realloc(ptr, size);
 	if (mem == NULL) {
@@ -32,6 +40,15 @@
 	return mem;
 }
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static void dovecot_openssl_free(void *ptr, const char *u0 ATTR_UNUSED, int u1 ATTR_UNUSED)
+#else
+static void dovecot_openssl_free(void *ptr)
+#endif
+{
+	free(ptr);
+}
+
 void dovecot_openssl_common_global_ref(void)
 {
 	unsigned char buf;
@@ -43,7 +60,7 @@
 	   returning NULL. this avoids random failures on out-of-memory
 	   conditions. */
 	if (CRYPTO_set_mem_functions(dovecot_openssl_malloc,
-				     dovecot_openssl_realloc, free) == 0) {
+				     dovecot_openssl_realloc, dovecot_openssl_free) == 0) {
 		/*i_warning("CRYPTO_set_mem_functions() was called too late");*/
 	}
 
@@ -78,7 +95,11 @@
 	ENGINE_cleanup();
 	EVP_cleanup();
 	CRYPTO_cleanup_all_ex_data();
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
 	ERR_remove_state(0);
+#elif OPENSSL_VERSION_NUMBER < 0x10100000L
+	ERR_remove_thread_state(NULL);
+#endif
 	ERR_free_strings();
 	return FALSE;
 }
--- a/src/lib-ssl-iostream/iostream-openssl-common.c	Mon Aug 08 15:31:50 2016 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl-common.c	Tue Aug 09 11:48:10 2016 +0300
@@ -32,11 +32,17 @@
 			name++;
 			neg = TRUE;
 		}
+#ifdef SSL_TXT_SSLV2
 		if (strcasecmp(name, SSL_TXT_SSLV2) == 0)
 			proto = DOVECOT_SSL_PROTO_SSLv2;
-		else if (strcasecmp(name, SSL_TXT_SSLV3) == 0)
+		else
+#endif
+#ifdef SSL_TXT_SSLV3
+		if (strcasecmp(name, SSL_TXT_SSLV3) == 0)
 			proto = DOVECOT_SSL_PROTO_SSLv3;
-		else if (strcasecmp(name, SSL_TXT_TLSV1) == 0)
+		else
+#endif
+		if (strcasecmp(name, SSL_TXT_TLSV1) == 0)
 			proto = DOVECOT_SSL_PROTO_TLSv1;
 #ifdef SSL_TXT_TLSV1_1
 		else if (strcasecmp(name, SSL_TXT_TLSV1_1) == 0)
--- a/src/lib-ssl-iostream/iostream-openssl.c	Mon Aug 08 15:31:50 2016 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl.c	Tue Aug 09 11:48:10 2016 +0300
@@ -115,7 +115,7 @@
 	ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
 	ssl_io->cert_received = TRUE;
 
-	subject = X509_get_subject_name(ctx->current_cert);
+	subject = X509_get_subject_name(X509_STORE_CTX_get_current_cert(ctx));
 	if (subject == NULL ||
 	    X509_NAME_oneline(subject, certname, sizeof(certname)) == NULL)
 		certname[0] = '\0';
@@ -124,7 +124,7 @@
 	if (!preverify_ok) {
 		openssl_iostream_set_error(ssl_io, t_strdup_printf(
 			"Received invalid SSL certificate: %s: %s",
-			X509_verify_cert_error_string(ctx->error), certname));
+			X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), certname));
 		if (ssl_io->verbose_invalid_cert)
 			i_info("%s", ssl_io->last_error);
 	} else if (ssl_io->verbose) {
--- a/src/login-common/ssl-proxy-openssl.c	Mon Aug 08 15:31:50 2016 +0300
+++ b/src/login-common/ssl-proxy-openssl.c	Tue Aug 09 11:48:10 2016 +0300
@@ -826,7 +826,12 @@
 static RSA *ssl_gen_rsa_key(SSL *ssl ATTR_UNUSED,
 			    int is_export ATTR_UNUSED, int keylength)
 {
-	return RSA_generate_key(keylength, RSA_F4, NULL, NULL);
+	RSA *rsa = RSA_new();
+	BIGNUM *e = BN_new();
+	BN_set_word(e, RSA_F4);
+	RSA_generate_key_ex(rsa, keylength, e, NULL);
+	BN_free(e);
+	return rsa;
 }
 
 static DH *ssl_tmp_dh_callback(SSL *ssl ATTR_UNUSED,
@@ -876,6 +881,7 @@
 {
 	SSL *ssl;
         struct ssl_proxy *proxy;
+	int ctxerr;
 	char buf[1024];
 	X509_NAME *subject;
 
@@ -883,23 +889,26 @@
 					 SSL_get_ex_data_X509_STORE_CTX_idx());
 	proxy = SSL_get_ex_data(ssl, extdata_index);
 	proxy->cert_received = TRUE;
+	ctxerr = X509_STORE_CTX_get_error(ctx);
 
 	if (proxy->client_proxy && !proxy->login_set->ssl_require_crl &&
-	    (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL ||
-	     ctx->error == X509_V_ERR_CRL_HAS_EXPIRED)) {
+	    (ctxerr == X509_V_ERR_UNABLE_TO_GET_CRL ||
+	     ctxerr == X509_V_ERR_CRL_HAS_EXPIRED)) {
 		/* no CRL given with the CA list. don't worry about it. */
 		preverify_ok = 1;
 	}
 	if (!preverify_ok)
 		proxy->cert_broken = TRUE;
 
-	subject = X509_get_subject_name(ctx->current_cert);
+	subject = X509_get_subject_name(X509_STORE_CTX_get_current_cert(ctx));
 	(void)X509_NAME_oneline(subject, buf, sizeof(buf));
 	buf[sizeof(buf)-1] = '\0'; /* just in case.. */
 
+	ctxerr = X509_STORE_CTX_get_error(ctx);
+
 	if (proxy->cert_error == NULL) {
 		proxy->cert_error = p_strdup_printf(proxy->client->pool, "%s: %s",
-			X509_verify_cert_error_string(ctx->error), buf);
+			X509_verify_cert_error_string(ctxerr), buf);
 	}
 
 	if (proxy->ssl_set->verbose_ssl ||
@@ -910,7 +919,7 @@
 		} else {
 			client_log(proxy->client, t_strdup_printf(
 				"Invalid certificate: %s: %s",
-				X509_verify_cert_error_string(ctx->error), buf));
+				X509_verify_cert_error_string(ctxerr), buf));
 		}
 	}