diff --git a/Makefile b/Makefile index d0b4de31..0972abbe 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,10 @@ ifdef SSL_LIB CFLAGS += -DSSL_LIB=\"$(SSL_LIB)\" endif +ifdef SSL_VERSION_MAJOR + CFLAGS += -DSSL_VERSION_MAJOR=$(SSL_VERSION_MAJOR) +endif + ifdef CRYPTO_LIB CFLAGS += -DCRYPTO_LIB=\"$(CRYPTO_LIB)\" endif @@ -344,8 +348,6 @@ OBJLIST = \ ${OBJDIR}httplib_ssl_error${OBJEXT} \ ${OBJDIR}httplib_ssl_get_client_cert_info${OBJEXT} \ ${OBJDIR}httplib_ssl_get_protocol${OBJEXT} \ - ${OBJDIR}httplib_ssl_id_callback${OBJEXT} \ - ${OBJDIR}httplib_ssl_locking_callback${OBJEXT} \ ${OBJDIR}httplib_ssl_use_pem_file${OBJEXT} \ ${OBJDIR}httplib_sslize${OBJEXT} \ ${OBJDIR}httplib_start${OBJEXT} \ @@ -1190,19 +1192,6 @@ ${OBJDIR}httplib_ssl_get_protocol${OBJEXT} : ${SRCDIR}httplib_ssl_get_protoco ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h -${OBJDIR}httplib_ssl_id_callback${OBJEXT} : ${SRCDIR}httplib_ssl_id_callback.c \ - ${SRCDIR}httplib_pthread.h \ - ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_utils.h \ - ${SRCDIR}httplib_main.h \ - ${INCDIR}libhttp.h - -${OBJDIR}httplib_ssl_locking_callback${OBJEXT} : ${SRCDIR}httplib_ssl_locking_callback.c \ - ${SRCDIR}httplib_pthread.h \ - ${SRCDIR}httplib_ssl.h \ - ${SRCDIR}httplib_main.h \ - ${INCDIR}libhttp.h - ${OBJDIR}httplib_ssl_use_pem_file${OBJEXT} : ${SRCDIR}httplib_ssl_use_pem_file.c \ ${SRCDIR}httplib_ssl.h \ ${SRCDIR}httplib_main.h \ diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 77094a9e..c7d9a8fd 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,6 @@ Release Notes v2.0 (work in progress) === -### Objectives: *Clean up source code, Proper documentation, Restructure embedding API* +### Objectives: *Clean up source code, Proper documentation, Restructure embedding API, Switch to OpenSSL v1.1* Changes ------- @@ -27,6 +27,7 @@ Changes - Removed deprecated function `mg_get_valid_option_names();` - Removed all build scripts except the script for `make` - Added website [`www.libhttp.org`](http://www.libhttp.org) +- Switched OpenSSL support to OpenSSL v1.1 Release Notes v1.9 (will never be released as LibHTTP) === diff --git a/doc/Building.md b/doc/Building.md index 8ed81c03..d4ea6194 100644 --- a/doc/Building.md +++ b/doc/Building.md @@ -73,6 +73,7 @@ make build WITH_IPV6=1 | PORTS=8080 | listening ports override when installing | | SSL_LIB=libssl.so.0 | use versioned SSL library | | CRYPTO_LIB=libcrypto.so.0 | system versioned CRYPTO library | +| SSL_VERSION_MAJOR=3 | spcify major version on SSL library | | PREFIX=/usr/local | sets the install directory | | COPT='-DNO_SSL' | method to insert compile flags | @@ -96,7 +97,6 @@ make build COPT="-DNDEBUG -DNO_CGI" | NO_SSL_DL | link against system libssl library | | NO_FILES | do not serve files from a directory | | SQLITE_DISABLE_LFS | disables large files (Lua only) | -| SSL_ALREADY_INITIALIZED | do not initialize libcrypto | ## Cross Compiling diff --git a/doc/Embedding.md b/doc/Embedding.md index 8899d75e..4fec68e9 100644 --- a/doc/Embedding.md +++ b/doc/Embedding.md @@ -66,10 +66,6 @@ some threads: a master thread, that accepts new connections, and several worker threads, that process accepted connections. The number of worker threads is configurable via `num_threads` configuration option. That number puts a limit on number of simultaneous requests that can be handled by LibHTTP. -If you embed LibHTTP into a program that uses SSL outside LibHTTP as well, -you may need to initialize SSL before calling `httplib_start()`, and set the pre- -processor define SSL_ALREADY_INITIALIZED. This is not required if SSL is used -only within LibHTTP. When master thread accepts new a connection, a new accepted socket (described by `struct socket`) it placed into the accepted sockets queue, diff --git a/src/extern_ssl_lut.c b/src/extern_ssl_lut.c index d3ffb905..70d7d65e 100644 --- a/src/extern_ssl_lut.c +++ b/src/extern_ssl_lut.c @@ -49,22 +49,24 @@ struct ssl_func XX_httplib_ssl_sw[] = { { "SSL_set_fd", NULL }, { "SSL_new", NULL }, { "SSL_CTX_new", NULL }, - { "SSLv23_server_method", NULL }, - { "SSL_library_init", NULL }, + { "TLS_server_method", 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 }, + { "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 }, +#if SSL_VERSION_MAJOR >= 3 + { "SSL_get1_peer_certificate", NULL }, +#else { "SSL_get_peer_certificate", NULL }, +#endif { "SSL_get_version", NULL }, { "SSL_get_current_cipher", NULL }, { "SSL_CIPHER_get_name", NULL }, @@ -75,7 +77,6 @@ struct ssl_func XX_httplib_ssl_sw[] = { { NULL, NULL } }; - /* * struct ssl_func XX_httplib_crypto_sw[]; * @@ -84,27 +85,22 @@ struct ssl_func XX_httplib_ssl_sw[] = { */ struct ssl_func XX_httplib_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 }, - { "ASN1_digest", NULL }, - { "i2d_X509", NULL }, - { NULL, NULL } + { "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 }, + { "ASN1_INTEGER_to_BN", NULL }, + { "BN_bn2hex", NULL }, + { "BN_free", NULL }, + { "CRYPTO_free", NULL }, + { "EVP_get_digestbyname", NULL }, + { "ASN1_digest", NULL }, + { "i2d_X509", NULL }, + { NULL, NULL } }; #endif /* !defined(NO_SSL) && !defined(NO_SSL_DL) */ diff --git a/src/httplib_close_connection.c b/src/httplib_close_connection.c index 2e841789..e7699bea 100644 --- a/src/httplib_close_connection.c +++ b/src/httplib_close_connection.c @@ -60,12 +60,6 @@ void XX_httplib_close_connection( struct lh_ctx_t *ctx, struct lh_con_t *conn ) SSL_shutdown( conn->ssl ); SSL_free( conn->ssl ); - /* - * Avoid CRYPTO_cleanup_all_ex_data(); See discussion: - * https://wiki.openssl.org/index.php/Talk:Library_Initialization - */ - - ERR_remove_state( 0 ); conn->ssl = NULL; } #endif diff --git a/src/httplib_connect_client.c b/src/httplib_connect_client.c index 1464ae9e..36df265d 100644 --- a/src/httplib_connect_client.c +++ b/src/httplib_connect_client.c @@ -93,7 +93,7 @@ static struct lh_con_t *httplib_connect_client_impl( struct lh_ctx_t *ctx, const } #ifndef NO_SSL - else if ( use_ssl && (conn->client_ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL ) { + else if ( use_ssl && (conn->client_ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL ) { httplib_cry( LH_DEBUG_ERROR, ctx, conn, "%s: SSL_CTX_new error", __func__ ); closesocket( sock ); diff --git a/src/httplib_connect_socket.c b/src/httplib_connect_socket.c index d8fae36e..58bc6906 100644 --- a/src/httplib_connect_socket.c +++ b/src/httplib_connect_socket.c @@ -63,9 +63,9 @@ bool XX_httplib_connect_socket( struct lh_ctx_t *ctx, const char *host, int port return false; } -#if !defined(NO_SSL) +#if !defined(NO_SSL) && !defined(NO_SSL_DL) - if ( use_ssl && SSLv23_client_method == NULL ) { + if ( use_ssl && TLS_client_method == NULL ) { httplib_cry( LH_DEBUG_ERROR, ctx, NULL, "%s: SSL is not initialized", __func__ ); return false; diff --git a/src/httplib_initialize_ssl.c b/src/httplib_initialize_ssl.c index a392d0a4..e8af3600 100644 --- a/src/httplib_initialize_ssl.c +++ b/src/httplib_initialize_ssl.c @@ -32,12 +32,6 @@ #include "httplib_ssl.h" #include "httplib_utils.h" -#if defined(SSL_ALREADY_INITIALIZED) -int XX_httplib_cryptolib_users = 1; /* Reference counter for crypto library. */ -#else -int XX_httplib_cryptolib_users = 0; /* Reference counter for crypto library. */ -#endif - #if !defined(NO_SSL_DL) static void *cryptolib_dll_handle; /* Store the crypto library handle. */ #endif /* NO_SSL_DL */ @@ -53,9 +47,6 @@ static void *cryptolib_dll_handle; /* Store the crypto library handle. */ int XX_httplib_initialize_ssl( struct lh_ctx_t *ctx ) { - int i; - size_t size; - #if !defined(NO_SSL_DL) if ( ! cryptolib_dll_handle ) { @@ -64,29 +55,6 @@ int XX_httplib_initialize_ssl( struct lh_ctx_t *ctx ) { } #endif /* NO_SSL_DL */ - if ( httplib_atomic_inc( & XX_httplib_cryptolib_users ) > 1 ) return 1; - - /* - * Initialize locking callbacks, needed for thread safety. - * http://www.openssl.org/support/faq.html#PROG1 - */ - - i = CRYPTO_num_locks(); - if ( i < 0 ) i = 0; - - size = sizeof(pthread_mutex_t) * ((size_t)(i)); - - if ( (XX_httplib_ssl_mutexes = httplib_malloc( size )) == NULL ) { - - httplib_cry( LH_DEBUG_CRASH, ctx, NULL, "%s: cannot allocate mutexes: %s", __func__, XX_httplib_ssl_error() ); - return 0; - } - - for (i=0; iname ); - dlclose( dll_handle ); - - return NULL; + missing_symbols = true; } else fp->ptr = u.fp; } + if( missing_symbols ) { + dlclose( dll_handle ); + + return NULL; + } return dll_handle; } /* XX_httplib_load_dll */ diff --git a/src/httplib_main.h b/src/httplib_main.h index eac1d680..acd800ba 100644 --- a/src/httplib_main.h +++ b/src/httplib_main.h @@ -216,11 +216,19 @@ typedef long off_t; #define NO_SOCKLEN_T #if defined(_WIN64) || defined(__MINGW64__) -#define SSL_LIB "ssleay64.dll" -#define CRYPTO_LIB "libeay64.dll" +#if !defined(SSL_LIB) +#define SSL_LIB "libssl-1_1-x64.dll" +#endif +#if !defined(CRYPTO_LIB) +#define CRYPTO_LIB "libcrypto-1_1-x64.dll" +#endif #else /* _WIN64 || __MINGW64__ */ -#define SSL_LIB "ssleay32.dll" -#define CRYPTO_LIB "libeay32.dll" +#if !defined(SSL_LIB) +#define SSL_LIB "libssl-1_1.dll" +#endif +#if !defined(CRYPTO_LIB) +#define CRYPTO_LIB "libcrypto-1_1.dll" +#endif #endif /* _WIN64 || __MINGW64__ */ #define O_NONBLOCK (0) @@ -318,8 +326,12 @@ typedef unsigned short int in_port_t; #endif #include #if defined(__MACH__) +#if !defined(SSL_LIB) #define SSL_LIB "libssl.dylib" +#endif +#if !defined(CRYPTO_LIB) #define CRYPTO_LIB "libcrypto.dylib" +#endif #else #if !defined(SSL_LIB) #define SSL_LIB "libssl.so" @@ -859,9 +871,7 @@ bool XX_httplib_is_put_or_delete_method( const struct lh_con_t *conn ); bool XX_httplib_is_valid_http_method( const char *method ); int XX_httplib_is_valid_port( unsigned long port ); bool XX_httplib_is_websocket_protocol( const struct lh_con_t *conn ); -#if defined(NO_SSL) -void * XX_httplib_load_dll( struct lh_ctx_t *ctx, const char *dll_name ); -#else /* NO_SSL */ +#if !defined(NO_SSL) && !defined(NO_SSL_DL) void * XX_httplib_load_dll( struct lh_ctx_t *ctx, const char *dll_name, struct ssl_func *sw ); #endif void XX_httplib_log_access( struct lh_ctx_t *ctx, const struct lh_con_t *conn ); diff --git a/src/httplib_pthread.h b/src/httplib_pthread.h index 8737f53f..cd498ff6 100644 --- a/src/httplib_pthread.h +++ b/src/httplib_pthread.h @@ -22,5 +22,4 @@ -extern pthread_mutex_t * XX_httplib_ssl_mutexes; extern int XX_httplib_thread_idx_max; diff --git a/src/httplib_set_ssl_option.c b/src/httplib_set_ssl_option.c index a88bb494..c8da50ff 100644 --- a/src/httplib_set_ssl_option.c +++ b/src/httplib_set_ssl_option.c @@ -30,7 +30,9 @@ #include "httplib_main.h" #include "httplib_ssl.h" +#if !defined(NO_SSL_DL) static void *ssllib_dll_handle; /* Store the ssl library handle. */ +#endif /* NO_SSL_DL */ /* * bool XX_httplib_set_ssl_option( struct lh_ctx_t *ctx ); @@ -72,10 +74,7 @@ bool XX_httplib_set_ssl_option( struct lh_ctx_t *ctx ) { #endif /* NO_SSL_DL */ - SSL_library_init(); - SSL_load_error_strings(); - - ctx->ssl_ctx = SSL_CTX_new( SSLv23_server_method() ); + ctx->ssl_ctx = SSL_CTX_new( TLS_server_method() ); if ( ctx->ssl_ctx == NULL ) { httplib_cry( LH_DEBUG_CRASH, ctx, NULL, "%s: SSL_CTX_new (server) error: %s", __func__, XX_httplib_ssl_error() ); diff --git a/src/httplib_ssl.h b/src/httplib_ssl.h index 34c0b92e..1b1b02a1 100644 --- a/src/httplib_ssl.h +++ b/src/httplib_ssl.h @@ -73,29 +73,27 @@ struct ssl_func { #define SSL_set_fd (*(int (*)(SSL *, SOCKET))XX_httplib_ssl_sw[6].ptr) #define SSL_new (*(SSL * (*)(SSL_CTX *))XX_httplib_ssl_sw[7].ptr) #define SSL_CTX_new (*(SSL_CTX * (*)(SSL_METHOD *))XX_httplib_ssl_sw[8].ptr) -#define SSLv23_server_method (*(SSL_METHOD * (*)(void))XX_httplib_ssl_sw[9].ptr) -#define SSL_library_init (*(int (*)(void))XX_httplib_ssl_sw[10].ptr) -#define SSL_CTX_use_PrivateKey_file (*(int (*)(SSL_CTX *, const char *, int))XX_httplib_ssl_sw[11].ptr) -#define SSL_CTX_use_certificate_file (*(int (*)(SSL_CTX *, const char *, int))XX_httplib_ssl_sw[12].ptr) -#define SSL_CTX_set_default_passwd_cb (*(void (*)(SSL_CTX *, httplib_callback_t))XX_httplib_ssl_sw[13].ptr) -#define SSL_CTX_free (*(void (*)(SSL_CTX *))XX_httplib_ssl_sw[14].ptr) -#define SSL_load_error_strings (*(void (*)(void))XX_httplib_ssl_sw[15].ptr) -#define SSL_CTX_use_certificate_chain_file (*(int (*)(SSL_CTX *, const char *))XX_httplib_ssl_sw[16].ptr) -#define SSLv23_client_method (*(SSL_METHOD * (*)(void))XX_httplib_ssl_sw[17].ptr) -#define SSL_pending (*(int (*)(SSL *))XX_httplib_ssl_sw[18].ptr) -#define SSL_CTX_set_verify (*(void (*)(SSL_CTX *, int, int (*verify_callback)(int, X509_STORE_CTX *)))XX_httplib_ssl_sw[19].ptr) -#define SSL_shutdown (*(int (*)(SSL *))XX_httplib_ssl_sw[20].ptr) -#define SSL_CTX_load_verify_locations (*(int (*)(SSL_CTX *, const char *, const char *))XX_httplib_ssl_sw[21].ptr) -#define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))XX_httplib_ssl_sw[22].ptr) -#define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))XX_httplib_ssl_sw[23].ptr) -#define SSL_get_peer_certificate (*(X509 * (*)(SSL *))XX_httplib_ssl_sw[24].ptr) -#define SSL_get_version (*(const char *(*)(SSL *))XX_httplib_ssl_sw[25].ptr) -#define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *))XX_httplib_ssl_sw[26].ptr) -#define SSL_CIPHER_get_name (*(const char *(*)(const SSL_CIPHER *))XX_httplib_ssl_sw[27].ptr) -#define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))XX_httplib_ssl_sw[28].ptr) -#define SSL_CTX_set_session_id_context (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))XX_httplib_ssl_sw[29].ptr) -#define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))XX_httplib_ssl_sw[30].ptr) -#define SSL_CTX_set_cipher_list (*(int (*)(SSL_CTX *, const char *))XX_httplib_ssl_sw[31].ptr) +#define TLS_server_method (*(SSL_METHOD * (*)(void))XX_httplib_ssl_sw[9].ptr) +#define SSL_CTX_use_PrivateKey_file (*(int (*)(SSL_CTX *, const char *, int))XX_httplib_ssl_sw[10].ptr) +#define SSL_CTX_use_certificate_file (*(int (*)(SSL_CTX *, const char *, int))XX_httplib_ssl_sw[11].ptr) +#define SSL_CTX_set_default_passwd_cb (*(void (*)(SSL_CTX *, httplib_callback_t))XX_httplib_ssl_sw[12].ptr) +#define SSL_CTX_free (*(void (*)(SSL_CTX *))XX_httplib_ssl_sw[13].ptr) +#define SSL_CTX_use_certificate_chain_file (*(int (*)(SSL_CTX *, const char *))XX_httplib_ssl_sw[14].ptr) +#define TLS_client_method (*(SSL_METHOD * (*)(void))XX_httplib_ssl_sw[15].ptr) +#define SSL_pending (*(int (*)(SSL *))XX_httplib_ssl_sw[16].ptr) +#define SSL_CTX_set_verify (*(void (*)(SSL_CTX *, int, int (*verify_callback)(int, X509_STORE_CTX *)))XX_httplib_ssl_sw[17].ptr) +#define SSL_shutdown (*(int (*)(SSL *))XX_httplib_ssl_sw[18].ptr) +#define SSL_CTX_load_verify_locations (*(int (*)(SSL_CTX *, const char *, const char *))XX_httplib_ssl_sw[19].ptr) +#define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))XX_httplib_ssl_sw[20].ptr) +#define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))XX_httplib_ssl_sw[21].ptr) +#define SSL_get_peer_certificate (*(X509 * (*)(SSL *))XX_httplib_ssl_sw[22].ptr) +#define SSL_get_version (*(const char *(*)(SSL *))XX_httplib_ssl_sw[23].ptr) +#define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *))XX_httplib_ssl_sw[24].ptr) +#define SSL_CIPHER_get_name (*(const char *(*)(const SSL_CIPHER *))XX_httplib_ssl_sw[25].ptr) +#define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))XX_httplib_ssl_sw[26].ptr) +#define SSL_CTX_set_session_id_context (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))XX_httplib_ssl_sw[27].ptr) +#define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))XX_httplib_ssl_sw[28].ptr) +#define SSL_CTX_set_cipher_list (*(int (*)(SSL_CTX *, const char *))XX_httplib_ssl_sw[29].ptr) #define SSL_CTX_set_options(ctx, op) SSL_CTX_ctrl((ctx), SSL_CTRL_OPTIONS, (op), NULL) #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) @@ -103,27 +101,30 @@ struct ssl_func { #define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) #define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +typedef struct bignum_st BIGNUM; -#define CRYPTO_num_locks (*(int (*)(void))XX_httplib_crypto_sw[0].ptr) -#define CRYPTO_set_locking_callback (*(void (*)(void (*)(int, int, const char *, int)))XX_httplib_crypto_sw[1].ptr) -#define CRYPTO_set_id_callback (*(void (*)(unsigned long (*)(void)))XX_httplib_crypto_sw[2].ptr) -#define ERR_get_error (*(unsigned long (*)(void))XX_httplib_crypto_sw[3].ptr) -#define ERR_error_string (*(char *(*)(unsigned long, char *))XX_httplib_crypto_sw[4].ptr) -#define ERR_remove_state (*(void (*)(unsigned long))XX_httplib_crypto_sw[5].ptr) -#define ERR_free_strings (*(void (*)(void))XX_httplib_crypto_sw[6].ptr) -#define ENGINE_cleanup (*(void (*)(void))XX_httplib_crypto_sw[7].ptr) -#define CONF_modules_unload (*(void (*)(int))XX_httplib_crypto_sw[8].ptr) -#define CRYPTO_cleanup_all_ex_data (*(void (*)(void))XX_httplib_crypto_sw[9].ptr) -#define EVP_cleanup (*(void (*)(void))XX_httplib_crypto_sw[10].ptr) -#define X509_free (*(void (*)(X509 *))XX_httplib_crypto_sw[11].ptr) -#define X509_get_subject_name (*(X509_NAMEX * (*)(X509 *))XX_httplib_crypto_sw[12].ptr) -#define X509_get_issuer_name (*(X509_NAMEX * (*)(X509 *))XX_httplib_crypto_sw[13].ptr) -#define X509_NAME_oneline (*(char *(*)(X509_NAMEX *, char *, int))XX_httplib_crypto_sw[14].ptr) -#define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))XX_httplib_crypto_sw[15].ptr) -#define i2c_ASN1_INTEGER (*(int (*)(ASN1_INTEGER *, unsigned char **))XX_httplib_crypto_sw[16].ptr) -#define EVP_get_digestbyname (*(const EVP_MD *(*)(const char *))XX_httplib_crypto_sw[17].ptr) -#define ASN1_digest (*(int (*)(int (*)(void *,unsigned char **), const EVP_MD *, char *, unsigned char *, unsigned int *))XX_httplib_crypto_sw[18].ptr) -#define i2d_X509 (*(int (*)(X509 *, unsigned char **))XX_httplib_crypto_sw[19].ptr) +#define ERR_get_error (*(unsigned long (*)(void))XX_httplib_crypto_sw[0].ptr) +#define ERR_error_string (*(char *(*)(unsigned long, char *))XX_httplib_crypto_sw[1].ptr) +#define CONF_modules_unload (*(void (*)(int))XX_httplib_crypto_sw[2].ptr) +#define X509_free (*(void (*)(X509 *))XX_httplib_crypto_sw[3].ptr) +#define X509_get_subject_name (*(X509_NAMEX * (*)(X509 *))XX_httplib_crypto_sw[4].ptr) +#define X509_get_issuer_name (*(X509_NAMEX * (*)(X509 *))XX_httplib_crypto_sw[5].ptr) +#define X509_NAME_oneline (*(char *(*)(X509_NAMEX *, char *, int))XX_httplib_crypto_sw[6].ptr) +#define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))XX_httplib_crypto_sw[7].ptr) +#define ASN1_INTEGER_to_BN (*(BIGNUM *(*)(const ASN1_INTEGER *, BIGNUM *))XX_httplib_crypto_sw[8].ptr) +#define BN_bn2hex (*(char *(*)(const BIGNUM *))XX_httplib_crypto_sw[9].ptr) +#define BN_free (*(void(*)(BIGNUM *))XX_httplib_crypto_sw[10].ptr) +#define CRYPTO_free (*(void(*)(void *, const char *, int))XX_httplib_crypto_sw[11].ptr) +#define EVP_get_digestbyname (*(const EVP_MD *(*)(const char *))XX_httplib_crypto_sw[12].ptr) +#define ASN1_digest (*(int (*)(int (*)(const void *,unsigned char **), const EVP_MD *, char *, unsigned char *, unsigned int *))XX_httplib_crypto_sw[13].ptr) +#define i2d_X509 (*(int (*)(const X509 *, unsigned char **))XX_httplib_crypto_sw[14].ptr) + +#define OPENSSL_free(addr) CRYPTO_free(addr, __FILE__, __LINE__) + + + +extern struct ssl_func XX_httplib_crypto_sw[]; +extern struct ssl_func XX_httplib_ssl_sw[]; #endif /* NO_SSL_DL */ @@ -135,17 +136,10 @@ bool XX_httplib_set_ssl_option( struct lh_ctx_t *ctx ); const char * XX_httplib_ssl_error( void ); void XX_httplib_ssl_get_client_cert_info( struct lh_con_t *conn ); long XX_httplib_ssl_get_protocol( int version_id ); -unsigned long XX_httplib_ssl_id_callback( void ); void XX_httplib_ssl_locking_callback( int mode, int mutex_num, const char *file, int line ); int XX_httplib_ssl_use_pem_file( struct lh_ctx_t *ctx, const char *pem ); int XX_httplib_sslize( struct lh_ctx_t *ctx, struct lh_con_t *conn, SSL_CTX *s, int (*func)(SSL *) ); void XX_httplib_tls_dtor( void *key ); void XX_httplib_uninitialize_ssl( struct lh_ctx_t *ctx ); - - -extern int XX_httplib_cryptolib_users; -extern struct ssl_func XX_httplib_crypto_sw[]; -extern struct ssl_func XX_httplib_ssl_sw[]; - #endif /* NO_SSL */ diff --git a/src/httplib_ssl_get_client_cert_info.c b/src/httplib_ssl_get_client_cert_info.c index 05286935..d24fe139 100644 --- a/src/httplib_ssl_get_client_cert_info.c +++ b/src/httplib_ssl_get_client_cert_info.c @@ -43,17 +43,15 @@ void XX_httplib_ssl_get_client_cert_info( struct lh_con_t *conn ) { char str_subject[1024]; char str_issuer[1024]; - char str_serial[1024]; + char *str_serial = NULL; char str_finger[1024]; unsigned char buf[256]; - unsigned char *pbuf; - int len; - int len2; unsigned int ulen; X509 *cert; X509_NAMEX *subj; X509_NAMEX *iss; ASN1_INTEGER *serial; + BIGNUM *bignum_serial; const EVP_MD *digest; if ( conn == NULL ) return; @@ -81,24 +79,19 @@ void XX_httplib_ssl_get_client_cert_info( struct lh_con_t *conn ) { * Translate serial number to a hex string */ - len = i2c_ASN1_INTEGER( serial, NULL ); + bignum_serial = ASN1_INTEGER_to_BN( serial, NULL ); - if ( len > 0 && (unsigned)len < (unsigned)sizeof(buf) ) { + if ( bignum_serial ) { - pbuf = buf; - len2 = i2c_ASN1_INTEGER( serial, &pbuf ); - - if ( ! hexdump2string( buf, len2, str_serial, (int)sizeof(str_serial) ) ) *str_serial = 0; + str_serial = BN_bn2hex( bignum_serial ); } - - else *str_serial = 0; /* * Calculate SHA1 fingerprint and store as a hex string */ ulen = 0; - ASN1_digest( (int (*)(void *, unsigned char**))i2d_X509, digest, (char *)cert, buf, &ulen ); + ASN1_digest( (int (*)(const void *, unsigned char**))i2d_X509, digest, (char *)cert, buf, &ulen ); if ( ! hexdump2string( buf, (int)ulen, str_finger, (int)sizeof(str_finger) ) ) *str_finger = 0; @@ -108,7 +101,7 @@ void XX_httplib_ssl_get_client_cert_info( struct lh_con_t *conn ) { conn->request_info.client_cert->subject = httplib_strdup( str_subject ); conn->request_info.client_cert->issuer = httplib_strdup( str_issuer ); - conn->request_info.client_cert->serial = httplib_strdup( str_serial ); + conn->request_info.client_cert->serial = httplib_strdup( str_serial ? str_serial : "" ); conn->request_info.client_cert->finger = httplib_strdup( str_finger ); } @@ -116,6 +109,9 @@ void XX_httplib_ssl_get_client_cert_info( struct lh_con_t *conn ) { /* TODO: write some OOM message */ } + BN_free( bignum_serial ); + OPENSSL_free( str_serial ); + X509_free( cert ); } /* XX_httplib_ssl_get_client_cert_info */ diff --git a/src/httplib_ssl_id_callback.c b/src/httplib_ssl_id_callback.c deleted file mode 100644 index 475ee58d..00000000 --- a/src/httplib_ssl_id_callback.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2016-2019 Lammert Bies - * Copyright (c) 2013-2016 the Civetweb developers - * Copyright (c) 2004-2013 Sergey Lyubka - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ============ - * Release: 2.0 - */ - -#if !defined(NO_SSL) - -#include "httplib_main.h" -#include "httplib_pthread.h" -#include "httplib_ssl.h" -#include "httplib_utils.h" - -/* - * unsigned long XX_httplib_ssl_id_callback( void ); - * - * The function XX_httplib_ssl_id_callback() returns a handle representing the - * thread running the SSL callback. - */ - -/* Must be set if sizeof(pthread_t) > sizeof(unsigned long) */ -unsigned long XX_httplib_ssl_id_callback( void ) { - -#ifdef _WIN32 - return GetCurrentThreadId(); -#else /* _WIN32 */ - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunreachable-code" -/* - * For every compiler, either "sizeof(pthread_t) > sizeof(unsigned long)" - * or not, so one of the two conditions will be unreachable by construction. - * Unfortunately the C standard does not define a way to check this at - * compile time, since the #if preprocessor conditions can not use the sizeof - * operator as an argument. - */ - -#endif /* __clang__ */ - - if ( sizeof(pthread_t) > sizeof(unsigned long) ) { - - /* - * This is the problematic case for CRYPTO_set_id_callback: - * The OS pthread_t can not be cast to unsigned long. - */ - - struct httplib_workerTLS *tls = httplib_pthread_getspecific( XX_httplib_sTlsKey ); - - if ( tls == NULL ) { - - /* - * SSL called from an unknown thread: Create some thread index. - */ - - tls = httplib_malloc( sizeof(struct httplib_workerTLS) ); - tls->thread_idx = (unsigned) httplib_atomic_inc( & XX_httplib_thread_idx_max ); - - httplib_pthread_setspecific( XX_httplib_sTlsKey, tls ); - } - - return tls->thread_idx; - } - else { - /* - * pthread_t may be any data type, so a simple cast to unsigned long - * can rise a warning/error, depending on the platform. - * Here memcpy is used as an anything-to-anything cast. - */ - - unsigned long ret = 0; - pthread_t t = httplib_pthread_self(); - memcpy(&ret, &t, sizeof(pthread_t)); - return ret; - } - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif /* __clang */ - -#endif /* _WIN32 */ - -} /* XX_httplib_ssl_id_callback */ - -#endif /* !NO_SSL */ diff --git a/src/httplib_ssl_locking_callback.c b/src/httplib_ssl_locking_callback.c deleted file mode 100644 index 8bbcf87f..00000000 --- a/src/httplib_ssl_locking_callback.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016-2019 Lammert Bies - * Copyright (c) 2013-2016 the Civetweb developers - * Copyright (c) 2004-2013 Sergey Lyubka - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * ============ - * Release: 2.0 - */ - -#if !defined(NO_SSL) - -#include "httplib_main.h" -#include "httplib_pthread.h" -#include "httplib_ssl.h" - -pthread_mutex_t *XX_httplib_ssl_mutexes; - -/* - * void XX_httplib_ssl_locking_callback( int mode, int mutex_num, const char *file, int line ); - * - * The function XX_httplib_ssl_locking_callback() is used for locking and - * unlocking mutexes from the SSL routines. - */ - -void XX_httplib_ssl_locking_callback( int mode, int mutex_num, const char *file, int line ) { - - UNUSED_PARAMETER(line); - UNUSED_PARAMETER(file); - - if ( mode & 0x0001 ) httplib_pthread_mutex_lock( & XX_httplib_ssl_mutexes[mutex_num] ); - else httplib_pthread_mutex_unlock( & XX_httplib_ssl_mutexes[mutex_num] ); - -} /* XX_httplib_ssl_locking_callback */ - -#endif /* !NO_SSL */ diff --git a/src/httplib_sslize.c b/src/httplib_sslize.c index e6ebd621..2dc39fe4 100644 --- a/src/httplib_sslize.c +++ b/src/httplib_sslize.c @@ -62,12 +62,6 @@ int XX_httplib_sslize( struct lh_ctx_t *ctx, struct lh_con_t *conn, SSL_CTX *s, SSL_free( conn->ssl ); conn->ssl = NULL; - /* - * Avoid CRYPTO_cleanup_all_ex_data(); See discussion: - * https://wiki.openssl.org/index.php/Talk:Library_Initialization - */ - - ERR_remove_state( 0 ); return 0; } @@ -96,12 +90,6 @@ int XX_httplib_sslize( struct lh_ctx_t *ctx, struct lh_con_t *conn, SSL_CTX *s, SSL_free( conn->ssl ); conn->ssl = NULL; - /* - * Avoid CRYPTO_cleanup_all_ex_data(); See discussion: - * https://wiki.openssl.org/index.php/Talk:Library_Initialization - */ - - ERR_remove_state( 0 ); return 0; } diff --git a/src/httplib_uninitialize_ssl.c b/src/httplib_uninitialize_ssl.c index 486010e6..382ffff6 100644 --- a/src/httplib_uninitialize_ssl.c +++ b/src/httplib_uninitialize_ssl.c @@ -43,29 +43,7 @@ void XX_httplib_uninitialize_ssl( struct lh_ctx_t *ctx ) { UNUSED_PARAMETER(ctx); - int i; - - if ( httplib_atomic_dec( & XX_httplib_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 - */ - - CRYPTO_set_locking_callback( NULL ); - CRYPTO_set_id_callback( NULL ); - ENGINE_cleanup(); - CONF_modules_unload( 1 ); - ERR_free_strings(); - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); - ERR_remove_state( 0 ); - - for (i=0; i