|
@@ -1248,7 +1248,10 @@ typedef struct SSL_CTX SSL_CTX;
|
|
|
#include <openssl/engine.h>
|
|
|
#include <openssl/conf.h>
|
|
|
#include <openssl/dh.h>
|
|
|
+#include <openssl/bn.h>
|
|
|
+#include <openssl/opensslv.h>
|
|
|
#else
|
|
|
+
|
|
|
/* SSL loaded dynamically from DLL.
|
|
|
* I put the prototypes here to be independent from OpenSSL source
|
|
|
* installation. */
|
|
@@ -1259,6 +1262,8 @@ typedef struct ssl_ctx_st SSL_CTX;
|
|
|
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
|
|
typedef struct x509_name X509_NAME;
|
|
|
typedef struct asn1_integer ASN1_INTEGER;
|
|
|
+typedef struct bignum BIGNUM;
|
|
|
+typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS;
|
|
|
typedef struct evp_md EVP_MD;
|
|
|
typedef struct x509 X509;
|
|
|
|
|
@@ -1267,6 +1272,10 @@ typedef struct x509 X509;
|
|
|
#define SSL_CTRL_CLEAR_OPTIONS (77)
|
|
|
#define SSL_CTRL_SET_ECDH_AUTO (94)
|
|
|
|
|
|
+#define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0x00100000L
|
|
|
+#define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L
|
|
|
+#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L
|
|
|
+
|
|
|
#define SSL_VERIFY_NONE (0)
|
|
|
#define SSL_VERIFY_PEER (1)
|
|
|
#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT (2)
|
|
@@ -1297,6 +1306,147 @@ struct ssl_func {
|
|
|
void (*ptr)(void); /* Function pointer */
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+
|
|
|
+#define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr)
|
|
|
+#define SSL_accept (*(int (*)(SSL *))ssl_sw[1].ptr)
|
|
|
+#define SSL_connect (*(int (*)(SSL *))ssl_sw[2].ptr)
|
|
|
+#define SSL_read (*(int (*)(SSL *, void *, int))ssl_sw[3].ptr)
|
|
|
+#define SSL_write (*(int (*)(SSL *, const void *, int))ssl_sw[4].ptr)
|
|
|
+#define SSL_get_error (*(int (*)(SSL *, int))ssl_sw[5].ptr)
|
|
|
+#define SSL_set_fd (*(int (*)(SSL *, SOCKET))ssl_sw[6].ptr)
|
|
|
+#define SSL_new (*(SSL * (*)(SSL_CTX *))ssl_sw[7].ptr)
|
|
|
+#define SSL_CTX_new (*(SSL_CTX * (*)(SSL_METHOD *))ssl_sw[8].ptr)
|
|
|
+#define TLS_server_method (*(SSL_METHOD * (*)(void))ssl_sw[9].ptr)
|
|
|
+#define OPENSSL_init_ssl (*(int (*)(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings))ssl_sw[10].ptr)
|
|
|
+#define SSL_CTX_use_PrivateKey_file \
|
|
|
+ (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[11].ptr)
|
|
|
+#define SSL_CTX_use_certificate_file \
|
|
|
+ (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[12].ptr)
|
|
|
+#define SSL_CTX_set_default_passwd_cb \
|
|
|
+ (*(void (*)(SSL_CTX *, mg_callback_t))ssl_sw[13].ptr)
|
|
|
+#define SSL_CTX_free (*(void (*)(SSL_CTX *))ssl_sw[14].ptr)
|
|
|
+#define SSL_CTX_use_certificate_chain_file \
|
|
|
+ (*(int (*)(SSL_CTX *, const char *))ssl_sw[15].ptr)
|
|
|
+#define TLS_client_method (*(SSL_METHOD * (*)(void))ssl_sw[16].ptr)
|
|
|
+#define SSL_pending (*(int (*)(SSL *))ssl_sw[17].ptr)
|
|
|
+#define SSL_CTX_set_verify \
|
|
|
+ (*(void (*)(SSL_CTX *, \
|
|
|
+ int, \
|
|
|
+ int (*verify_callback)(int, X509_STORE_CTX *)))ssl_sw[18].ptr)
|
|
|
+#define SSL_shutdown (*(int (*)(SSL *))ssl_sw[19].ptr)
|
|
|
+#define SSL_CTX_load_verify_locations \
|
|
|
+ (*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[20].ptr)
|
|
|
+#define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))ssl_sw[21].ptr)
|
|
|
+#define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[22].ptr)
|
|
|
+#define SSL_get_peer_certificate (*(X509 * (*)(SSL *))ssl_sw[23].ptr)
|
|
|
+#define SSL_get_version (*(const char *(*)(SSL *))ssl_sw[24].ptr)
|
|
|
+#define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *))ssl_sw[25].ptr)
|
|
|
+#define SSL_CIPHER_get_name \
|
|
|
+ (*(const char *(*)(const SSL_CIPHER *))ssl_sw[26].ptr)
|
|
|
+#define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))ssl_sw[27].ptr)
|
|
|
+#define SSL_CTX_set_session_id_context \
|
|
|
+ (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))ssl_sw[28].ptr)
|
|
|
+#define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))ssl_sw[29].ptr)
|
|
|
+#define SSL_CTX_set_cipher_list \
|
|
|
+ (*(int (*)(SSL_CTX *, const char *))ssl_sw[30].ptr)
|
|
|
+#define SSL_CTX_set_options (*(unsigned long (*)(SSL_CTX *, unsigned long))ssl_sw[31].ptr)
|
|
|
+
|
|
|
+
|
|
|
+#define SSL_CTX_clear_options(ctx, op) \
|
|
|
+ SSL_CTX_ctrl((ctx), SSL_CTRL_CLEAR_OPTIONS, (op), NULL)
|
|
|
+#define SSL_CTX_set_ecdh_auto(ctx, onoff) \
|
|
|
+ SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, onoff, NULL)
|
|
|
+
|
|
|
+#define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
|
|
|
+#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
|
|
|
+
|
|
|
+
|
|
|
+#define ERR_get_error (*(unsigned long (*)(void))crypto_sw[0].ptr)
|
|
|
+#define ERR_error_string (*(char *(*)(unsigned long, char *))crypto_sw[1].ptr)
|
|
|
+#define ERR_remove_state (*(void (*)(unsigned long))crypto_sw[2].ptr)
|
|
|
+#define CONF_modules_unload (*(void (*)(int))crypto_sw[3].ptr)
|
|
|
+#define X509_free (*(void (*)(X509 *))crypto_sw[4].ptr)
|
|
|
+#define X509_get_subject_name (*(X509_NAME * (*)(X509 *))crypto_sw[5].ptr)
|
|
|
+#define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))crypto_sw[6].ptr)
|
|
|
+#define X509_NAME_oneline \
|
|
|
+ (*(char *(*)(X509_NAME *, char *, int))crypto_sw[7].ptr)
|
|
|
+#define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))crypto_sw[8].ptr)
|
|
|
+#define EVP_get_digestbyname \
|
|
|
+ (*(const EVP_MD *(*)(const char *))crypto_sw[9].ptr)
|
|
|
+#define ASN1_digest \
|
|
|
+ (*(int (*)(int (*)(), \
|
|
|
+ const EVP_MD *, \
|
|
|
+ char *, \
|
|
|
+ unsigned char *, \
|
|
|
+ unsigned int *))crypto_sw[10].ptr)
|
|
|
+#define i2d_X509 (*(int (*)(X509 *, unsigned char **))crypto_sw[11].ptr)
|
|
|
+#define BN_bn2hex (*(char *(*)(const BIGNUM *a))crypto_sw[12].ptr)
|
|
|
+#define ASN1_INTEGER_to_BN (*(BIGNUM *(*)(const ASN1_INTEGER *ai, BIGNUM *bn))crypto_sw[13].ptr)
|
|
|
+#define BN_free (*(void(*)(const BIGNUM *a))crypto_sw[14].ptr)
|
|
|
+
|
|
|
+
|
|
|
+/* set_ssl_option() function updates this array.
|
|
|
+ * It loads SSL library dynamically and changes NULLs to the actual addresses
|
|
|
+ * of respective functions. The macros above (like SSL_connect()) are really
|
|
|
+ * 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},
|
|
|
+ {NULL, NULL}};
|
|
|
+
|
|
|
+
|
|
|
+/* Similar array as ssl_sw. These functions could be located in different
|
|
|
+ * lib. */
|
|
|
+static struct ssl_func crypto_sw[] = {
|
|
|
+ {"ERR_get_error", NULL},
|
|
|
+ {"ERR_error_string", NULL},
|
|
|
+ {"ERR_remove_state", 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},
|
|
|
+ {"ASN1_digest", NULL},
|
|
|
+ {"i2d_X509", NULL},
|
|
|
+ {"BN_bn2hex", NULL},
|
|
|
+ {"ASN1_INTEGER_to_BN", NULL},
|
|
|
+ {"BN_free", NULL},
|
|
|
+ {NULL, NULL}};
|
|
|
+#else
|
|
|
+
|
|
|
#define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr)
|
|
|
#define SSL_accept (*(int (*)(SSL *))ssl_sw[1].ptr)
|
|
|
#define SSL_connect (*(int (*)(SSL *))ssl_sw[2].ptr)
|
|
@@ -1383,6 +1533,9 @@ struct ssl_func {
|
|
|
unsigned char *, \
|
|
|
unsigned int *))crypto_sw[18].ptr)
|
|
|
#define i2d_X509 (*(int (*)(X509 *, unsigned char **))crypto_sw[19].ptr)
|
|
|
+#define BN_bn2hex (*(char *(*)(const BIGNUM *a))crypto_sw[20].ptr)
|
|
|
+#define ASN1_INTEGER_to_BN (*(BIGNUM *(*)(const ASN1_INTEGER *ai, BIGNUM *bn))crypto_sw[21].ptr)
|
|
|
+#define BN_free (*(void(*)(const BIGNUM *a))crypto_sw[22].ptr)
|
|
|
|
|
|
|
|
|
/* set_ssl_option() function updates this array.
|
|
@@ -1446,7 +1599,11 @@ static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
|
|
|
{"EVP_get_digestbyname", NULL},
|
|
|
{"ASN1_digest", NULL},
|
|
|
{"i2d_X509", NULL},
|
|
|
+ {"BN_bn2hex", NULL},
|
|
|
+ {"ASN1_INTEGER_to_BN", NULL},
|
|
|
+ {"BN_free", NULL},
|
|
|
{NULL, NULL}};
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
#endif /* NO_SSL_DL */
|
|
|
#endif /* NO_SSL */
|
|
|
|
|
@@ -6714,6 +6871,18 @@ connect_socket(struct mg_context *ctx /* may be NULL */,
|
|
|
}
|
|
|
|
|
|
#if !defined(NO_SSL)
|
|
|
+#if !defined(NO_SSL_DL)
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+ if (use_ssl && (TLS_client_method == NULL)) {
|
|
|
+ mg_snprintf(NULL,
|
|
|
+ NULL, /* No truncation check for ebuf */
|
|
|
+ ebuf,
|
|
|
+ ebuf_len,
|
|
|
+ "%s",
|
|
|
+ "SSL is not initialized");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+#else
|
|
|
if (use_ssl && (SSLv23_client_method == NULL)) {
|
|
|
mg_snprintf(NULL,
|
|
|
NULL, /* No truncation check for ebuf */
|
|
@@ -6723,9 +6892,14 @@ connect_socket(struct mg_context *ctx /* may be NULL */,
|
|
|
"SSL is not initialized");
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
#else
|
|
|
(void)use_ssl;
|
|
|
-#endif
|
|
|
+#endif /* NO_SSL_DL */
|
|
|
+#else
|
|
|
+ (void)use_ssl;
|
|
|
+#endif /* !defined(NO_SSL) */
|
|
|
|
|
|
if (mg_inet_pton(AF_INET, host, &sa->sin, sizeof(sa->sin))) {
|
|
|
sa->sin.sin_port = htons((uint16_t)port);
|
|
@@ -9393,15 +9567,17 @@ mg_unlock_context(struct mg_context *ctx)
|
|
|
|
|
|
#if defined(USE_WEBSOCKET)
|
|
|
|
|
|
+#if !defined(NO_SSL_DL)
|
|
|
#define SHA_API static
|
|
|
#include "sha1.inl"
|
|
|
+#endif
|
|
|
|
|
|
static int
|
|
|
send_websocket_handshake(struct mg_connection *conn, const char *websock_key)
|
|
|
{
|
|
|
static const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
|
char buf[100], sha[20], b64_sha[sizeof(sha) * 2];
|
|
|
- SHA1_CTX sha_ctx;
|
|
|
+ SHA_CTX sha_ctx;
|
|
|
int truncated;
|
|
|
|
|
|
/* Calculate Sec-WebSocket-Accept reply from Sec-WebSocket-Key. */
|
|
@@ -9413,7 +9589,7 @@ send_websocket_handshake(struct mg_connection *conn, const char *websock_key)
|
|
|
|
|
|
SHA1_Init(&sha_ctx);
|
|
|
SHA1_Update(&sha_ctx, (unsigned char *)buf, (uint32_t)strlen(buf));
|
|
|
- SHA1_Final(&sha_ctx, (unsigned char *)sha);
|
|
|
+ SHA1_Final((unsigned char *)sha, &sha_ctx);
|
|
|
base64_encode((unsigned char *)sha, sizeof(sha), b64_sha);
|
|
|
mg_printf(conn,
|
|
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
|
@@ -11698,9 +11874,10 @@ refresh_trust(struct mg_connection *conn)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+#else
|
|
|
static pthread_mutex_t *ssl_mutexes;
|
|
|
-
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
|
|
|
static int
|
|
|
sslize(struct mg_connection *conn,
|
|
@@ -11740,7 +11917,9 @@ sslize(struct mg_connection *conn,
|
|
|
conn->ssl = NULL;
|
|
|
/* Avoid CRYPTO_cleanup_all_ex_data(); See discussion:
|
|
|
* https://wiki.openssl.org/index.php/Talk:Library_Initialization */
|
|
|
+#ifndef OPENSSL_API_1_1
|
|
|
ERR_remove_state(0);
|
|
|
+#endif
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -11786,7 +11965,9 @@ sslize(struct mg_connection *conn,
|
|
|
conn->ssl = NULL;
|
|
|
/* Avoid CRYPTO_cleanup_all_ex_data(); See discussion:
|
|
|
* https://wiki.openssl.org/index.php/Talk:Library_Initialization */
|
|
|
+#ifndef OPENSSL_API_1_1
|
|
|
ERR_remove_state(0);
|
|
|
+#endif
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -11837,10 +12018,9 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
|
if (cert) {
|
|
|
char str_subject[1024];
|
|
|
char str_issuer[1024];
|
|
|
- char str_serial[1024];
|
|
|
char str_finger[1024];
|
|
|
unsigned char buf[256];
|
|
|
- int len;
|
|
|
+ char *str_serial = NULL;
|
|
|
unsigned int ulen;
|
|
|
|
|
|
/* Handle to algorithm used for fingerprint */
|
|
@@ -11858,17 +12038,9 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
|
(void)X509_NAME_oneline(iss, str_issuer, (int)sizeof(str_issuer));
|
|
|
|
|
|
/* Translate serial number to a hex string */
|
|
|
- len = i2c_ASN1_INTEGER(serial, NULL);
|
|
|
- if ((len > 0) && ((unsigned)len < (unsigned)sizeof(buf))) {
|
|
|
- unsigned char *pbuf = buf;
|
|
|
- int len2 = i2c_ASN1_INTEGER(serial, &pbuf);
|
|
|
- if (!hexdump2string(
|
|
|
- buf, len2, str_serial, (int)sizeof(str_serial))) {
|
|
|
- *str_serial = 0;
|
|
|
- }
|
|
|
- } else {
|
|
|
- *str_serial = 0;
|
|
|
- }
|
|
|
+ BIGNUM *serial_bn = ASN1_INTEGER_to_BN(serial, NULL);
|
|
|
+ str_serial = BN_bn2hex(serial_bn);
|
|
|
+ BN_free(serial_bn);
|
|
|
|
|
|
/* Calculate SHA1 fingerprint and store as a hex string */
|
|
|
ulen = 0;
|
|
@@ -11889,11 +12061,14 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
|
/* TODO: write some OOM message */
|
|
|
}
|
|
|
|
|
|
+ mg_free(str_serial);
|
|
|
X509_free(cert);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+#else
|
|
|
static void
|
|
|
ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
|
|
|
{
|
|
@@ -11907,6 +12082,7 @@ ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
|
|
|
(void)pthread_mutex_unlock(&ssl_mutexes[mutex_num]);
|
|
|
}
|
|
|
}
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
|
|
|
|
|
|
#if !defined(NO_SSL_DL)
|
|
@@ -11968,6 +12144,24 @@ static int cryptolib_users = 0; /* Reference counter for crypto library. */
|
|
|
static int
|
|
|
initialize_ssl(struct mg_context *ctx)
|
|
|
{
|
|
|
+
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+#if !defined(NO_SSL_DL)
|
|
|
+ if (!cryptolib_dll_handle) {
|
|
|
+ cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw);
|
|
|
+ if (!cryptolib_dll_handle) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#else
|
|
|
+ (void)ctx;
|
|
|
+#endif /* NO_SSL_DL */
|
|
|
+
|
|
|
+ if (mg_atomic_inc(&cryptolib_users) > 1) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+#else
|
|
|
int i;
|
|
|
size_t size;
|
|
|
|
|
@@ -11978,6 +12172,8 @@ initialize_ssl(struct mg_context *ctx)
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
+#else
|
|
|
+ (void)ctx;
|
|
|
#endif /* NO_SSL_DL */
|
|
|
|
|
|
if (mg_atomic_inc(&cryptolib_users) > 1) {
|
|
@@ -12006,6 +12202,7 @@ initialize_ssl(struct mg_context *ctx)
|
|
|
|
|
|
CRYPTO_set_locking_callback(&ssl_locking_callback);
|
|
|
CRYPTO_set_id_callback(&mg_current_thread_id);
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
@@ -12053,6 +12250,22 @@ ssl_use_pem_file(struct mg_context *ctx, const char *pem)
|
|
|
}
|
|
|
|
|
|
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+static unsigned long
|
|
|
+ssl_get_protocol(int version_id)
|
|
|
+{
|
|
|
+ long unsigned ret = SSL_OP_ALL;
|
|
|
+ if (version_id > 0)
|
|
|
+ ret |= SSL_OP_NO_SSLv2;
|
|
|
+ if (version_id > 1)
|
|
|
+ ret |= SSL_OP_NO_SSLv3;
|
|
|
+ if (version_id > 2)
|
|
|
+ ret |= SSL_OP_NO_TLSv1;
|
|
|
+ if (version_id > 3)
|
|
|
+ ret |= SSL_OP_NO_TLSv1_1;
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+#else
|
|
|
static long
|
|
|
ssl_get_protocol(int version_id)
|
|
|
{
|
|
@@ -12067,6 +12280,7 @@ ssl_get_protocol(int version_id)
|
|
|
ret |= SSL_OP_NO_TLSv1_1;
|
|
|
return ret;
|
|
|
}
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
|
|
|
|
|
|
/* Dynamically load SSL library. Set up ctx->ssl_ctx pointer. */
|
|
@@ -12109,6 +12323,17 @@ set_ssl_option(struct mg_context *ctx)
|
|
|
}
|
|
|
#endif /* NO_SSL_DL */
|
|
|
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+ /* Initialize SSL library */
|
|
|
+ OPENSSL_init_ssl(0, NULL);
|
|
|
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
|
|
|
+ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
|
|
+
|
|
|
+ if ((ctx->ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) {
|
|
|
+ mg_cry(fc(ctx), "SSL_CTX_new (server) error: %s", ssl_error());
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+#else
|
|
|
/* Initialize SSL library */
|
|
|
SSL_library_init();
|
|
|
SSL_load_error_strings();
|
|
@@ -12117,6 +12342,7 @@ set_ssl_option(struct mg_context *ctx)
|
|
|
mg_cry(fc(ctx), "SSL_CTX_new (server) error: %s", ssl_error());
|
|
|
return 0;
|
|
|
}
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
|
|
|
SSL_CTX_clear_options(ctx->ssl_ctx,
|
|
|
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1
|
|
@@ -12125,7 +12351,9 @@ set_ssl_option(struct mg_context *ctx)
|
|
|
SSL_CTX_set_options(ctx->ssl_ctx, ssl_get_protocol(protocol_ver));
|
|
|
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_SINGLE_DH_USE);
|
|
|
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
|
|
+#if !defined(NO_SSL_DL)
|
|
|
SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1);
|
|
|
+#endif /* NO_SSL_DL */
|
|
|
|
|
|
/* If a callback has been specified, call it. */
|
|
|
callback_ret =
|
|
@@ -12223,6 +12451,17 @@ set_ssl_option(struct mg_context *ctx)
|
|
|
static void
|
|
|
uninitialize_ssl(struct mg_context *ctx)
|
|
|
{
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+ (void)ctx;
|
|
|
+
|
|
|
+ if (mg_atomic_dec(&cryptolib_users) == 0) {
|
|
|
+
|
|
|
+ /* Shutdown according to
|
|
|
+ * https://wiki.openssl.org/index.php/Library_Initialization#Cleanup
|
|
|
+ * http://stackoverflow.com/questions/29845527/how-to-properly-uninitialize-openssl
|
|
|
+ */
|
|
|
+ CONF_modules_unload(1);
|
|
|
+#else
|
|
|
int i;
|
|
|
(void)ctx;
|
|
|
|
|
@@ -12246,6 +12485,8 @@ uninitialize_ssl(struct mg_context *ctx)
|
|
|
}
|
|
|
mg_free(ssl_mutexes);
|
|
|
ssl_mutexes = NULL;
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
#endif /* !NO_SSL */
|
|
@@ -12494,7 +12735,9 @@ close_connection(struct mg_connection *conn)
|
|
|
SSL_free(conn->ssl);
|
|
|
/* Avoid CRYPTO_cleanup_all_ex_data(); See discussion:
|
|
|
* https://wiki.openssl.org/index.php/Talk:Library_Initialization */
|
|
|
+#ifndef OPENSSL_API_1_1
|
|
|
ERR_remove_state(0);
|
|
|
+#endif
|
|
|
conn->ssl = NULL;
|
|
|
}
|
|
|
#endif
|
|
@@ -12589,6 +12832,19 @@ mg_connect_client_impl(const struct mg_client_options *client_options,
|
|
|
strerror(ERRNO));
|
|
|
closesocket(sock);
|
|
|
#ifndef NO_SSL
|
|
|
+#ifdef OPENSSL_API_1_1
|
|
|
+ } else if (use_ssl
|
|
|
+ && (conn->client_ssl_ctx = SSL_CTX_new(TLS_client_method()))
|
|
|
+ == NULL) {
|
|
|
+ mg_snprintf(NULL,
|
|
|
+ NULL, /* No truncation check for ebuf */
|
|
|
+ ebuf,
|
|
|
+ ebuf_len,
|
|
|
+ "SSL_CTX_new error");
|
|
|
+ closesocket(sock);
|
|
|
+ mg_free(conn);
|
|
|
+ conn = NULL;
|
|
|
+#else
|
|
|
} else if (use_ssl
|
|
|
&& (conn->client_ssl_ctx = SSL_CTX_new(SSLv23_client_method()))
|
|
|
== NULL) {
|
|
@@ -12600,6 +12856,7 @@ mg_connect_client_impl(const struct mg_client_options *client_options,
|
|
|
closesocket(sock);
|
|
|
mg_free(conn);
|
|
|
conn = NULL;
|
|
|
+#endif /* OPENSSL_API_1_1 */
|
|
|
#endif /* NO_SSL */
|
|
|
|
|
|
} else {
|