Blob Blame Raw
From: Razvan Crainea <razvan@opensips.org>
Date: Tue, 29 Nov 2016 14:16:11 +0200
Subject: [PATCH] Add support for openssl 1.1.0

Reported by Petr Pisar in issue #996

diff --git a/modules/tls_mgm/tls.h b/modules/tls_mgm/tls.h
index 97ac01ca2..04cb78cfd 100644
--- a/modules/tls_mgm/tls.h
+++ b/modules/tls_mgm/tls.h
@@ -64,41 +64,50 @@
 	#warning ""
 #endif
 
-static int tls_static_locks_no=0;
-static gen_lock_set_t* tls_static_locks=NULL;
-
 static SSL_METHOD     *ssl_methods[TLS_USE_TLSv1_2 + 1];
 
 #define VERIFY_DEPTH_S 3
 
 
-struct CRYPTO_dynlock_value {
-	gen_lock_t lock;
-};
-
-static unsigned long tls_get_id(void)
-{
-	return my_pid();
-}
-
 /*
  * Wrappers around OpenSIPS shared memory functions
  * (which can be macros)
  */
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static void* os_malloc(size_t size, const char *file, int line)
+#else
 static void* os_malloc(size_t size)
+#endif
 {
+#if (defined DBG_MALLOC  && OPENSSL_VERSION_NUMBER >= 0x10100000L)
+	return _shm_malloc(size, file, __FUNCTION__, line);
+#else
 	return shm_malloc(size);
+#endif
 }
 
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static void* os_realloc(void *ptr, size_t size, const char *file, int line)
+#else
 static void* os_realloc(void *ptr, size_t size)
+#endif
 {
+#if (defined DBG_MALLOC  && OPENSSL_VERSION_NUMBER >= 0x10100000L)
+	return _shm_realloc(ptr, size, file, __FUNCTION__, line);
+#else
 	return shm_realloc(ptr, size);
+#endif
 }
 
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static void os_free(void *ptr, const char *file, int line)
+#else
 static void os_free(void *ptr)
+#endif
 {
+	/* TODO: also handle free file and line */
 	if (ptr)
 		shm_free(ptr);
 }
@@ -106,21 +115,17 @@ static void os_free(void *ptr)
 
 
 
-static void tls_static_locks_ops(int mode, int n, const char* file, int line)
-{
-	if (n<0 || n>tls_static_locks_no) {
-		LM_ERR("BUG - SSL Lib attempting to acquire bogus lock\n");
-		abort();
-	}
+/* these locks can not be used in 1.1.0, because the interface has changed */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+struct CRYPTO_dynlock_value {
+	gen_lock_t lock;
+};
 
-	if (mode & CRYPTO_LOCK) {
-		lock_set_get(tls_static_locks,n);
-	} else {
-		lock_set_release(tls_static_locks,n);
-	}
+static unsigned long tls_get_id(void)
+{
+	return my_pid();
 }
 
-
 static struct CRYPTO_dynlock_value* tls_dyn_lock_create(const char* file,
 																	int line)
 {
@@ -158,5 +163,6 @@ static void tls_dyn_lock_destroy(struct CRYPTO_dynlock_value *dyn_lock,
 	lock_destroy(&dyn_lock->lock);
 	shm_free(dyn_lock);
 }
+#endif
 
 #endif /* _PROTO_TLS_H_ */
diff --git a/modules/tls_mgm/tls_conn_ops.h b/modules/tls_mgm/tls_conn_ops.h
index acb5c66fa..ca901bde6 100644
--- a/modules/tls_mgm/tls_conn_ops.h
+++ b/modules/tls_mgm/tls_conn_ops.h
@@ -116,11 +116,13 @@ static int tls_conn_init(struct tcp_connection* c, struct tls_mgm_binds *api)
 		return -1;
 	}
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 #ifndef OPENSSL_NO_KRB5
 	if ( ((SSL *)c->extra_data)->kssl_ctx ) {
 		kssl_ctx_free( ((SSL *)c->extra_data)->kssl_ctx );
 		((SSL *)c->extra_data)->kssl_ctx = 0;
 	}
+#endif
 #endif
 
 	if ( c->proto_flags & F_TLS_DO_ACCEPT ) {
diff --git a/modules/tls_mgm/tls_conn_server.h b/modules/tls_mgm/tls_conn_server.h
index 8812f1db1..af6c2b309 100644
--- a/modules/tls_mgm/tls_conn_server.h
+++ b/modules/tls_mgm/tls_conn_server.h
@@ -148,16 +148,20 @@ static int tls_accept(struct tcp_connection *c, short *poll_events)
 	}
 
 	ssl = (SSL *) c->extra_data;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 #ifndef OPENSSL_NO_KRB5
 	if ( ssl->kssl_ctx==NULL )
 		ssl->kssl_ctx = kssl_ctx_new( );
+#endif
 #endif
 	ret = SSL_accept(ssl);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 #ifndef OPENSSL_NO_KRB5
 	if ( ssl->kssl_ctx ) {
 		kssl_ctx_free( ssl->kssl_ctx );
 		ssl->kssl_ctx = 0;
 	}
+#endif
 #endif
 	if (ret > 0) {
 		LM_INFO("New TLS connection from %s:%d accepted\n",
diff --git a/modules/tls_mgm/tls_mgm.c b/modules/tls_mgm/tls_mgm.c
index 80fccaf86..2427ecddc 100644
--- a/modules/tls_mgm/tls_mgm.c
+++ b/modules/tls_mgm/tls_mgm.c
@@ -557,11 +557,10 @@ int verify_callback(int pre_verify_ok, X509_STORE_CTX *ctx) {
 	LM_NOTICE("subject = %s\n", buf);
 	LM_NOTICE("verify error:num=%d:%s\n",
 			err, X509_verify_cert_error_string(err));
-	LM_NOTICE("error code is %d\n", ctx->error);
 
-	switch (ctx->error) {
+	switch (err) {
 		case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
-			X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
+			X509_NAME_oneline(X509_get_issuer_name(err_cert),
 					buf,sizeof buf);
 			LM_NOTICE("issuer= %s\n",buf);
 			break;
@@ -611,7 +610,7 @@ int verify_callback(int pre_verify_ok, X509_STORE_CTX *ctx) {
 
 		default:
 			LM_NOTICE("something wrong with the cert"
-					" ... error code is %d (check x509_vfy.h)\n", ctx->error);
+					" ... error code is %d (check x509_vfy.h)\n", err);
 			break;
 	}
 
@@ -1155,9 +1154,11 @@ static int init_tls_domains(struct tls_domain **dom, int skip)
 	return 0;
 }
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
 static int check_for_krb(void)
 {
 	SSL_CTX *xx;
+
 	int j;
 
 	xx = SSL_CTX_new(ssl_methods[tls_default_method - 1]);
@@ -1177,6 +1178,27 @@ static int check_for_krb(void)
 	SSL_CTX_free(xx);
 	return 0;
 }
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+static int tls_static_locks_no=0;
+static gen_lock_set_t* tls_static_locks=NULL;
+
+static void tls_static_locks_ops(int mode, int n, const char* file, int line)
+{
+	if (n<0 || n>tls_static_locks_no) {
+		LM_ERR("BUG - SSL Lib attempting to acquire bogus lock\n");
+		abort();
+	}
+
+	if (mode & CRYPTO_LOCK) {
+		lock_set_get(tls_static_locks,n);
+	} else {
+		lock_set_release(tls_static_locks,n);
+	}
+}
+
+
 
 static int tls_init_multithread(void)
 {
@@ -1207,6 +1229,7 @@ static int tls_init_multithread(void)
 
 	return 0;
 }
+#endif
 
 /*
  * initialize ssl methods
@@ -1216,19 +1239,31 @@ init_ssl_methods(void)
 {
 	LM_DBG("entered\n");
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	ssl_methods[TLS_USE_TLSv1_cli-1] = (SSL_METHOD*)TLS_client_method();
+	ssl_methods[TLS_USE_TLSv1_srv-1] = (SSL_METHOD*)TLS_server_method();
+	ssl_methods[TLS_USE_TLSv1-1] = (SSL_METHOD*)TLS_method();
+#else
 	ssl_methods[TLS_USE_TLSv1_cli-1] = (SSL_METHOD*)TLSv1_client_method();
 	ssl_methods[TLS_USE_TLSv1_srv-1] = (SSL_METHOD*)TLSv1_server_method();
 	ssl_methods[TLS_USE_TLSv1-1] = (SSL_METHOD*)TLSv1_method();
+#endif
 
 	ssl_methods[TLS_USE_SSLv23_cli-1] = (SSL_METHOD*)SSLv23_client_method();
 	ssl_methods[TLS_USE_SSLv23_srv-1] = (SSL_METHOD*)SSLv23_server_method();
 	ssl_methods[TLS_USE_SSLv23-1] = (SSL_METHOD*)SSLv23_method();
 
 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	ssl_methods[TLS_USE_TLSv1_2_cli-1] = (SSL_METHOD*)TLS_client_method();
+	ssl_methods[TLS_USE_TLSv1_2_srv-1] = (SSL_METHOD*)TLS_server_method();
+	ssl_methods[TLS_USE_TLSv1_2-1] = (SSL_METHOD*)TLS_method();
+#else
 	ssl_methods[TLS_USE_TLSv1_2_cli-1] = (SSL_METHOD*)TLSv1_2_client_method();
 	ssl_methods[TLS_USE_TLSv1_2_srv-1] = (SSL_METHOD*)TLSv1_2_server_method();
 	ssl_methods[TLS_USE_TLSv1_2-1] = (SSL_METHOD*)TLSv1_2_method();
 #endif
+#endif
 }
 
 /* reloads data from the db */
@@ -1354,9 +1389,10 @@ static int mod_init(void){
 	 */
 	if (!CRYPTO_set_mem_functions(os_malloc, os_realloc, os_free)) {
 		LM_ERR("unable to set the memory allocation functions\n");
-		LM_ERR("NOTE: check if you have openssl 1.0.1e-fips, as this "
-			"version is know to be broken; if so, you need to upgrade or "
-			"downgrade to a differen openssl version !!\n");
+		LM_ERR("NOTE: check if you are using openssl 1.0.1e-fips, (or other "
+			"FIPS version of openssl, as this is known to be broken; if so, "
+			"you need to upgrade or downgrade to a different openssl version!\n");
+		LM_ERR("current version: %s\n", SSLeay_version(SSLEAY_VERSION));
 		return -1;
 	}
 
@@ -1371,15 +1407,18 @@ static int mod_init(void){
 		sk_SSL_COMP_zero(comp_methods);
 	}
 #endif
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
 	if (tls_init_multithread() < 0) {
 		LM_ERR("failed to init multi-threading support\n");
 		return -1;
 	}
+#endif
 
 	SSL_library_init();
 	SSL_load_error_strings();
 	init_ssl_methods();
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
 	n = check_for_krb();
 	if (n==-1) {
 		LM_ERR("kerberos check failed\n");
@@ -1398,6 +1437,7 @@ static int mod_init(void){
 				(n!=1)?"":"no ",(n!=1)?"no ":"");
 		return -1;
 	}
+#endif
 
 	/*
 	 * finish setting up the tls default domains