Browse Source

Initialize ALPN only if the required function are available in OpenSSL DLLs

bel2125 5 years ago
parent
commit
8f621bdfcb
1 changed files with 196 additions and 163 deletions
  1. 196 163
      src/civetweb.c

+ 196 - 163
src/civetweb.c

@@ -1894,9 +1894,21 @@ typedef struct x509 X509;
 #define SSL_TLSEXT_ERR_ALERT_FATAL (2)
 #define SSL_TLSEXT_ERR_ALERT_FATAL (2)
 #define SSL_TLSEXT_ERR_NOACK (3)
 #define SSL_TLSEXT_ERR_NOACK (3)
 
 
+enum ssl_func_category {
+	TLS_Mandatory, /* required for HTTPS */
+	TLS_ALPN,      /* required for Application Layer Protocol Negotiation */
+	TLS_END_OF_LIST
+};
+
+/* Check if all TLS functions/features are available */
+static int tls_feature_missing[TLS_END_OF_LIST] = {0};
+
 struct ssl_func {
 struct ssl_func {
-	const char *name;  /* SSL function name */
-	void (*ptr)(void); /* Function pointer */
+	const char *name; /* SSL function name */
+	union {
+		enum ssl_func_category required; /* Mandatory or optional */
+		void (*ptr)(void);               /* Function pointer */
+	};
 };
 };
 
 
 
 
@@ -2035,71 +2047,73 @@ typedef int (*tSSL_next_protos_advertised_cb)(SSL *ssl,
  * It loads SSL library dynamically and changes NULLs to the actual addresses
  * It loads SSL library dynamically and changes NULLs to the actual addresses
  * of respective functions. The macros above (like SSL_connect()) are really
  * of respective functions. The macros above (like SSL_connect()) are really
  * just calling these functions indirectly via the pointer. */
  * just calling these functions indirectly via the pointer. */
-static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
-                                   {"SSL_accept", NULL},
-                                   {"SSL_connect", NULL},
-                                   {"SSL_read", NULL},
-                                   {"SSL_write", NULL},
-                                   {"SSL_get_error", NULL},
-                                   {"SSL_set_fd", NULL},
-                                   {"SSL_new", NULL},
-                                   {"SSL_CTX_new", NULL},
-                                   {"TLS_server_method", NULL},
-                                   {"OPENSSL_init_ssl", NULL},
-                                   {"SSL_CTX_use_PrivateKey_file", NULL},
-                                   {"SSL_CTX_use_certificate_file", NULL},
-                                   {"SSL_CTX_set_default_passwd_cb", NULL},
-                                   {"SSL_CTX_free", NULL},
-                                   {"SSL_CTX_use_certificate_chain_file", NULL},
-                                   {"TLS_client_method", NULL},
-                                   {"SSL_pending", NULL},
-                                   {"SSL_CTX_set_verify", NULL},
-                                   {"SSL_shutdown", NULL},
-                                   {"SSL_CTX_load_verify_locations", NULL},
-                                   {"SSL_CTX_set_default_verify_paths", NULL},
-                                   {"SSL_CTX_set_verify_depth", NULL},
-                                   {"SSL_get_peer_certificate", NULL},
-                                   {"SSL_get_version", NULL},
-                                   {"SSL_get_current_cipher", NULL},
-                                   {"SSL_CIPHER_get_name", NULL},
-                                   {"SSL_CTX_check_private_key", NULL},
-                                   {"SSL_CTX_set_session_id_context", NULL},
-                                   {"SSL_CTX_ctrl", NULL},
-                                   {"SSL_CTX_set_cipher_list", NULL},
-                                   {"SSL_CTX_set_options", NULL},
-                                   {"SSL_CTX_set_info_callback", NULL},
-                                   {"SSL_get_ex_data", NULL},
-                                   {"SSL_set_ex_data", NULL},
-                                   {"SSL_CTX_callback_ctrl", NULL},
-                                   {"SSL_get_servername", NULL},
-                                   {"SSL_set_SSL_CTX", NULL},
-                                   {"SSL_ctrl", NULL},
-                                   {"SSL_CTX_set_alpn_protos", NULL},
-                                   {"SSL_CTX_set_alpn_select_cb", NULL},
-                                   {"SSL_CTX_set_next_protos_advertised_cb",
-                                    NULL},
-                                   {NULL, NULL}};
+static struct ssl_func ssl_sw[] = {
+    {"SSL_free", {TLS_Mandatory}},
+    {"SSL_accept", {TLS_Mandatory}},
+    {"SSL_connect", {TLS_Mandatory}},
+    {"SSL_read", {TLS_Mandatory}},
+    {"SSL_write", {TLS_Mandatory}},
+    {"SSL_get_error", {TLS_Mandatory}},
+    {"SSL_set_fd", {TLS_Mandatory}},
+    {"SSL_new", {TLS_Mandatory}},
+    {"SSL_CTX_new", {TLS_Mandatory}},
+    {"TLS_server_method", {TLS_Mandatory}},
+    {"OPENSSL_init_ssl", {TLS_Mandatory}},
+    {"SSL_CTX_use_PrivateKey_file", {TLS_Mandatory}},
+    {"SSL_CTX_use_certificate_file", {TLS_Mandatory}},
+    {"SSL_CTX_set_default_passwd_cb", {TLS_Mandatory}},
+    {"SSL_CTX_free", {TLS_Mandatory}},
+    {"SSL_CTX_use_certificate_chain_file", {TLS_Mandatory}},
+    {"TLS_client_method", {TLS_Mandatory}},
+    {"SSL_pending", {TLS_Mandatory}},
+    {"SSL_CTX_set_verify", {TLS_Mandatory}},
+    {"SSL_shutdown", {TLS_Mandatory}},
+    {"SSL_CTX_load_verify_locations", {TLS_Mandatory}},
+    {"SSL_CTX_set_default_verify_paths", {TLS_Mandatory}},
+    {"SSL_CTX_set_verify_depth", {TLS_Mandatory}},
+    {"SSL_get_peer_certificate", {TLS_Mandatory}},
+    {"SSL_get_version", {TLS_Mandatory}},
+    {"SSL_get_current_cipher", {TLS_Mandatory}},
+    {"SSL_CIPHER_get_name", {TLS_Mandatory}},
+    {"SSL_CTX_check_private_key", {TLS_Mandatory}},
+    {"SSL_CTX_set_session_id_context", {TLS_Mandatory}},
+    {"SSL_CTX_ctrl", {TLS_Mandatory}},
+    {"SSL_CTX_set_cipher_list", {TLS_Mandatory}},
+    {"SSL_CTX_set_options", {TLS_Mandatory}},
+    {"SSL_CTX_set_info_callback", {TLS_Mandatory}},
+    {"SSL_get_ex_data", {TLS_Mandatory}},
+    {"SSL_set_ex_data", {TLS_Mandatory}},
+    {"SSL_CTX_callback_ctrl", {TLS_Mandatory}},
+    {"SSL_get_servername", {TLS_Mandatory}},
+    {"SSL_set_SSL_CTX", {TLS_Mandatory}},
+    {"SSL_ctrl", {TLS_Mandatory}},
+    {"SSL_CTX_set_alpn_protos", {TLS_ALPN}},
+    {"SSL_CTX_set_alpn_select_cb", {TLS_ALPN}},
+    {"SSL_CTX_set_next_protos_advertised_cb", {TLS_ALPN}},
+    {NULL, {TLS_END_OF_LIST}}};
 
 
 
 
 /* Similar array as ssl_sw. These functions could be located in different
 /* Similar array as ssl_sw. These functions could be located in different
  * lib. */
  * lib. */
-static struct ssl_func crypto_sw[] = {{"ERR_get_error", NULL},
-                                      {"ERR_error_string", NULL},
-                                      {"CONF_modules_unload", NULL},
-                                      {"X509_free", NULL},
-                                      {"X509_get_subject_name", NULL},
-                                      {"X509_get_issuer_name", NULL},
-                                      {"X509_NAME_oneline", NULL},
-                                      {"X509_get_serialNumber", NULL},
-                                      {"EVP_get_digestbyname", NULL},
-                                      {"EVP_Digest", NULL},
-                                      {"i2d_X509", NULL},
-                                      {"BN_bn2hex", NULL},
-                                      {"ASN1_INTEGER_to_BN", NULL},
-                                      {"BN_free", NULL},
-                                      {"CRYPTO_free", NULL},
-                                      {"ERR_clear_error", NULL},
-                                      {NULL, NULL}};
+static struct ssl_func crypto_sw[] = {{"ERR_get_error", {TLS_Mandatory}},
+                                      {"ERR_error_string", {TLS_Mandatory}},
+                                      {"CONF_modules_unload", {TLS_Mandatory}},
+                                      {"X509_free", {TLS_Mandatory}},
+                                      {"X509_get_subject_name",
+                                       {TLS_Mandatory}},
+                                      {"X509_get_issuer_name", {TLS_Mandatory}},
+                                      {"X509_NAME_oneline", {TLS_Mandatory}},
+                                      {"X509_get_serialNumber",
+                                       {TLS_Mandatory}},
+                                      {"EVP_get_digestbyname", {TLS_Mandatory}},
+                                      {"EVP_Digest", {TLS_Mandatory}},
+                                      {"i2d_X509", {TLS_Mandatory}},
+                                      {"BN_bn2hex", {TLS_Mandatory}},
+                                      {"ASN1_INTEGER_to_BN", {TLS_Mandatory}},
+                                      {"BN_free", {TLS_Mandatory}},
+                                      {"CRYPTO_free", {TLS_Mandatory}},
+                                      {"ERR_clear_error", {TLS_Mandatory}},
+                                      {NULL, {TLS_END_OF_LIST}}};
 #else
 #else
 
 
 #define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr)
 #define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr)
@@ -2248,80 +2262,81 @@ typedef int (*tSSL_next_protos_advertised_cb)(SSL *ssl,
  * It loads SSL library dynamically and changes NULLs to the actual addresses
  * It loads SSL library dynamically and changes NULLs to the actual addresses
  * of respective functions. The macros above (like SSL_connect()) are really
  * of respective functions. The macros above (like SSL_connect()) are really
  * just calling these functions indirectly via the pointer. */
  * just calling these functions indirectly via the pointer. */
-static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
-                                   {"SSL_accept", NULL},
-                                   {"SSL_connect", NULL},
-                                   {"SSL_read", NULL},
-                                   {"SSL_write", NULL},
-                                   {"SSL_get_error", NULL},
-                                   {"SSL_set_fd", NULL},
-                                   {"SSL_new", NULL},
-                                   {"SSL_CTX_new", NULL},
-                                   {"SSLv23_server_method", NULL},
-                                   {"SSL_library_init", NULL},
-                                   {"SSL_CTX_use_PrivateKey_file", NULL},
-                                   {"SSL_CTX_use_certificate_file", NULL},
-                                   {"SSL_CTX_set_default_passwd_cb", NULL},
-                                   {"SSL_CTX_free", NULL},
-                                   {"SSL_load_error_strings", NULL},
-                                   {"SSL_CTX_use_certificate_chain_file", NULL},
-                                   {"SSLv23_client_method", NULL},
-                                   {"SSL_pending", NULL},
-                                   {"SSL_CTX_set_verify", NULL},
-                                   {"SSL_shutdown", NULL},
-                                   {"SSL_CTX_load_verify_locations", NULL},
-                                   {"SSL_CTX_set_default_verify_paths", NULL},
-                                   {"SSL_CTX_set_verify_depth", NULL},
-                                   {"SSL_get_peer_certificate", NULL},
-                                   {"SSL_get_version", NULL},
-                                   {"SSL_get_current_cipher", NULL},
-                                   {"SSL_CIPHER_get_name", NULL},
-                                   {"SSL_CTX_check_private_key", NULL},
-                                   {"SSL_CTX_set_session_id_context", NULL},
-                                   {"SSL_CTX_ctrl", NULL},
-                                   {"SSL_CTX_set_cipher_list", NULL},
-                                   {"SSL_CTX_set_info_callback", NULL},
-                                   {"SSL_get_ex_data", NULL},
-                                   {"SSL_set_ex_data", NULL},
-                                   {"SSL_CTX_callback_ctrl", NULL},
-                                   {"SSL_get_servername", NULL},
-                                   {"SSL_set_SSL_CTX", NULL},
-                                   {"SSL_ctrl", NULL},
-                                   {"SSL_CTX_set_alpn_protos", NULL},
-                                   {"SSL_CTX_set_alpn_select_cb", NULL},
-                                   {"SSL_CTX_set_next_protos_advertised_cb",
-                                    NULL},
-                                   {NULL, NULL}};
+static struct ssl_func ssl_sw[] = {
+    {"SSL_free", {TLS_Mandatory}},
+    {"SSL_accept", {TLS_Mandatory}},
+    {"SSL_connect", {TLS_Mandatory}},
+    {"SSL_read", {TLS_Mandatory}},
+    {"SSL_write", {TLS_Mandatory}},
+    {"SSL_get_error", {TLS_Mandatory}},
+    {"SSL_set_fd", {TLS_Mandatory}},
+    {"SSL_new", {TLS_Mandatory}},
+    {"SSL_CTX_new", {TLS_Mandatory}},
+    {"SSLv23_server_method", {TLS_Mandatory}},
+    {"SSL_library_init", {TLS_Mandatory}},
+    {"SSL_CTX_use_PrivateKey_file", {TLS_Mandatory}},
+    {"SSL_CTX_use_certificate_file", {TLS_Mandatory}},
+    {"SSL_CTX_set_default_passwd_cb", {TLS_Mandatory}},
+    {"SSL_CTX_free", {TLS_Mandatory}},
+    {"SSL_load_error_strings", {TLS_Mandatory}},
+    {"SSL_CTX_use_certificate_chain_file", {TLS_Mandatory}},
+    {"SSLv23_client_method", {TLS_Mandatory}},
+    {"SSL_pending", {TLS_Mandatory}},
+    {"SSL_CTX_set_verify", {TLS_Mandatory}},
+    {"SSL_shutdown", {TLS_Mandatory}},
+    {"SSL_CTX_load_verify_locations", {TLS_Mandatory}},
+    {"SSL_CTX_set_default_verify_paths", {TLS_Mandatory}},
+    {"SSL_CTX_set_verify_depth", {TLS_Mandatory}},
+    {"SSL_get_peer_certificate", {TLS_Mandatory}},
+    {"SSL_get_version", {TLS_Mandatory}},
+    {"SSL_get_current_cipher", {TLS_Mandatory}},
+    {"SSL_CIPHER_get_name", {TLS_Mandatory}},
+    {"SSL_CTX_check_private_key", {TLS_Mandatory}},
+    {"SSL_CTX_set_session_id_context", {TLS_Mandatory}},
+    {"SSL_CTX_ctrl", {TLS_Mandatory}},
+    {"SSL_CTX_set_cipher_list", {TLS_Mandatory}},
+    {"SSL_CTX_set_info_callback", {TLS_Mandatory}},
+    {"SSL_get_ex_data", {TLS_Mandatory}},
+    {"SSL_set_ex_data", {TLS_Mandatory}},
+    {"SSL_CTX_callback_ctrl", {TLS_Mandatory}},
+    {"SSL_get_servername", {TLS_Mandatory}},
+    {"SSL_set_SSL_CTX", {TLS_Mandatory}},
+    {"SSL_ctrl", {TLS_Mandatory}},
+    {"SSL_CTX_set_alpn_protos", {TLS_ALPN}},
+    {"SSL_CTX_set_alpn_select_cb", {TLS_ALPN}},
+    {"SSL_CTX_set_next_protos_advertised_cb", {TLS_ALPN}},
+    {NULL, {TLS_END_OF_LIST}}};
 
 
 
 
 /* Similar array as ssl_sw. These functions could be located in different
 /* Similar array as ssl_sw. These functions could be located in different
  * lib. */
  * lib. */
-static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
-                                      {"CRYPTO_set_locking_callback", NULL},
-                                      {"CRYPTO_set_id_callback", NULL},
-                                      {"ERR_get_error", NULL},
-                                      {"ERR_error_string", NULL},
-                                      {"ERR_remove_state", NULL},
-                                      {"ERR_free_strings", NULL},
-                                      {"ENGINE_cleanup", NULL},
-                                      {"CONF_modules_unload", NULL},
-                                      {"CRYPTO_cleanup_all_ex_data", NULL},
-                                      {"EVP_cleanup", NULL},
-                                      {"X509_free", NULL},
-                                      {"X509_get_subject_name", NULL},
-                                      {"X509_get_issuer_name", NULL},
-                                      {"X509_NAME_oneline", NULL},
-                                      {"X509_get_serialNumber", NULL},
-                                      {"i2c_ASN1_INTEGER", NULL},
-                                      {"EVP_get_digestbyname", NULL},
-                                      {"EVP_Digest", NULL},
-                                      {"i2d_X509", NULL},
-                                      {"BN_bn2hex", NULL},
-                                      {"ASN1_INTEGER_to_BN", NULL},
-                                      {"BN_free", NULL},
-                                      {"CRYPTO_free", NULL},
-                                      {"ERR_clear_error", NULL},
-                                      {NULL, NULL}};
+static struct ssl_func crypto_sw[] = {
+    {"CRYPTO_num_locks", {TLS_Mandatory}},
+    {"CRYPTO_set_locking_callback", {TLS_Mandatory}},
+    {"CRYPTO_set_id_callback", {TLS_Mandatory}},
+    {"ERR_get_error", {TLS_Mandatory}},
+    {"ERR_error_string", {TLS_Mandatory}},
+    {"ERR_remove_state", {TLS_Mandatory}},
+    {"ERR_free_strings", {TLS_Mandatory}},
+    {"ENGINE_cleanup", {TLS_Mandatory}},
+    {"CONF_modules_unload", {TLS_Mandatory}},
+    {"CRYPTO_cleanup_all_ex_data", {TLS_Mandatory}},
+    {"EVP_cleanup", {TLS_Mandatory}},
+    {"X509_free", {TLS_Mandatory}},
+    {"X509_get_subject_name", {TLS_Mandatory}},
+    {"X509_get_issuer_name", {TLS_Mandatory}},
+    {"X509_NAME_oneline", {TLS_Mandatory}},
+    {"X509_get_serialNumber", {TLS_Mandatory}},
+    {"i2c_ASN1_INTEGER", {TLS_Mandatory}},
+    {"EVP_get_digestbyname", {TLS_Mandatory}},
+    {"EVP_Digest", {TLS_Mandatory}},
+    {"i2d_X509", {TLS_Mandatory}},
+    {"BN_bn2hex", {TLS_Mandatory}},
+    {"ASN1_INTEGER_to_BN", {TLS_Mandatory}},
+    {"BN_free", {TLS_Mandatory}},
+    {"CRYPTO_free", {TLS_Mandatory}},
+    {"ERR_clear_error", {TLS_Mandatory}},
+    {NULL, {TLS_END_OF_LIST}}};
 #endif /* OPENSSL_API_1_1 */
 #endif /* OPENSSL_API_1_1 */
 #endif /* NO_SSL_DL */
 #endif /* NO_SSL_DL */
 #endif /* NO_SSL */
 #endif /* NO_SSL */
@@ -2343,8 +2358,7 @@ static const char month_names[][4] = {"Jan",
 #endif /* !NO_CACHING */
 #endif /* !NO_CACHING */
 
 
 /* Unified socket address. For IPv6 support, add IPv6 address structure in
 /* Unified socket address. For IPv6 support, add IPv6 address structure in
- * the
- * union u. */
+ * the union u. */
 union usa {
 union usa {
 	struct sockaddr sa;
 	struct sockaddr sa;
 	struct sockaddr_in sin;
 	struct sockaddr_in sin;
@@ -15899,8 +15913,12 @@ ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
 
 
 
 
 #if !defined(NO_SSL_DL)
 #if !defined(NO_SSL_DL)
+/* Load a DLL/Shared Object with a TLS/SSL implementation. */
 static void *
 static void *
-load_dll(char *ebuf, size_t ebuf_len, const char *dll_name, struct ssl_func *sw)
+load_tls_dll(char *ebuf,
+             size_t ebuf_len,
+             const char *dll_name,
+             struct ssl_func *sw)
 {
 {
 	union {
 	union {
 		void *p;
 		void *p;
@@ -15924,6 +15942,8 @@ load_dll(char *ebuf, size_t ebuf_len, const char *dll_name, struct ssl_func *sw)
 
 
 	ok = 1;
 	ok = 1;
 	for (fp = sw; fp->name != NULL; fp++) {
 	for (fp = sw; fp->name != NULL; fp++) {
+		enum ssl_func_category req = fp->required;
+
 #if defined(_WIN32)
 #if defined(_WIN32)
 		/* GetProcAddress() returns pointer to function */
 		/* GetProcAddress() returns pointer to function */
 		u.fp = (void (*)(void))dlsym(dll_handle, fp->name);
 		u.fp = (void (*)(void))dlsym(dll_handle, fp->name);
@@ -15933,36 +15953,46 @@ load_dll(char *ebuf, size_t ebuf_len, const char *dll_name, struct ssl_func *sw)
 		 * cast. */
 		 * cast. */
 		u.p = dlsym(dll_handle, fp->name);
 		u.p = dlsym(dll_handle, fp->name);
 #endif /* _WIN32 */
 #endif /* _WIN32 */
+
+		/* Set pointer (might be NULL) */
+		fp->ptr = u.fp;
+
 		if (u.fp == NULL) {
 		if (u.fp == NULL) {
-			if (ok) {
-				mg_snprintf(NULL,
-				            &truncated,
-				            ebuf,
-				            ebuf_len,
-				            "%s: %s: cannot find %s",
-				            __func__,
-				            dll_name,
-				            fp->name);
-				ok = 0;
-			} else {
-				size_t cur_len = strlen(ebuf);
-				if (!truncated) {
+			DEBUG_TRACE("Missing function: %s\n", fp->name);
+			tls_feature_missing[req]++;
+
+			if (req == TLS_Mandatory) {
+				/* Mandatory function is missing */
+				if (ok) {
+					/* This is the first missing function.
+					 * Create a new error message. */
 					mg_snprintf(NULL,
 					mg_snprintf(NULL,
 					            &truncated,
 					            &truncated,
-					            ebuf + cur_len,
-					            ebuf_len - cur_len - 3,
-					            ", %s",
+					            ebuf,
+					            ebuf_len,
+					            "%s: %s: cannot find %s",
+					            __func__,
+					            dll_name,
 					            fp->name);
 					            fp->name);
-					if (truncated) {
-						/* If truncated, add "..." */
-						strcat(ebuf, "...");
+					ok = 0;
+				} else {
+					/* This is yet anothermissing function.
+					 * Append existing error message. */
+					size_t cur_len = strlen(ebuf);
+					if (!truncated) {
+						mg_snprintf(NULL,
+						            &truncated,
+						            ebuf + cur_len,
+						            ebuf_len - cur_len - 3,
+						            ", %s",
+						            fp->name);
+						if (truncated) {
+							/* If truncated, add "..." */
+							strcat(ebuf, "...");
+						}
 					}
 					}
 				}
 				}
 			}
 			}
-			/* Debug:
-			 * printf("Missing function: %s\n", fp->name); */
-		} else {
-			fp->ptr = u.fp;
 		}
 		}
 	}
 	}
 
 
@@ -15998,7 +16028,8 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 
 
 #if !defined(NO_SSL_DL)
 #if !defined(NO_SSL_DL)
 	if (!cryptolib_dll_handle) {
 	if (!cryptolib_dll_handle) {
-		cryptolib_dll_handle = load_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
+		cryptolib_dll_handle =
+		    load_tls_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
 		if (!cryptolib_dll_handle) {
 		if (!cryptolib_dll_handle) {
 			mg_snprintf(NULL,
 			mg_snprintf(NULL,
 			            NULL, /* No truncation check for ebuf */
 			            NULL, /* No truncation check for ebuf */
@@ -16027,7 +16058,8 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 
 
 #if !defined(NO_SSL_DL)
 #if !defined(NO_SSL_DL)
 	if (!cryptolib_dll_handle) {
 	if (!cryptolib_dll_handle) {
-		cryptolib_dll_handle = load_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
+		cryptolib_dll_handle =
+		    load_tls_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
 		if (!cryptolib_dll_handle) {
 		if (!cryptolib_dll_handle) {
 			mg_snprintf(NULL,
 			mg_snprintf(NULL,
 			            NULL, /* No truncation check for ebuf */
 			            NULL, /* No truncation check for ebuf */
@@ -16100,7 +16132,7 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 
 
 #if !defined(NO_SSL_DL)
 #if !defined(NO_SSL_DL)
 	if (!ssllib_dll_handle) {
 	if (!ssllib_dll_handle) {
-		ssllib_dll_handle = load_dll(ebuf, ebuf_len, SSL_LIB, ssl_sw);
+		ssllib_dll_handle = load_tls_dll(ebuf, ebuf_len, SSL_LIB, ssl_sw);
 		if (!ssllib_dll_handle) {
 		if (!ssllib_dll_handle) {
 #if !defined(OPENSSL_API_1_1)
 #if !defined(OPENSSL_API_1_1)
 			mg_free(ssl_mutexes);
 			mg_free(ssl_mutexes);
@@ -16615,7 +16647,8 @@ init_ssl_ctx_impl(struct mg_context *phys_ctx,
 		}
 		}
 	}
 	}
 
 
-	if (1 /* TODO */) {
+	/* Initialize ALPN only of TLS library (OpenSSL version) supports ALPN */
+	if (!tls_feature_missing[TLS_ALPN]) {
 		init_alpn(phys_ctx, dom_ctx);
 		init_alpn(phys_ctx, dom_ctx);
 	}
 	}