From 43d48adeb9a42254cce2f50ec1b973d1fb455ce1 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 15 Apr 2025 19:18:14 +0300 Subject: [PATCH] ssl_server_verify, ssl_server_ca_dir, ssl_server_ca_store added, ssl_server / ssl_client aliases added to ssl_serv / ssl_cli --- src/plugins/SSLPlugin/my_ssl.c | 49 +++---------- src/plugins/SSLPlugin/my_ssl.h | 23 +++--- src/plugins/SSLPlugin/ssl_plugin.c | 109 +++++++++++++++++++++++++++-- 3 files changed, 128 insertions(+), 53 deletions(-) diff --git a/src/plugins/SSLPlugin/my_ssl.c b/src/plugins/SSLPlugin/my_ssl.c index 9d24735..546b97c 100644 --- a/src/plugins/SSLPlugin/my_ssl.c +++ b/src/plugins/SSLPlugin/my_ssl.c @@ -45,6 +45,11 @@ static char hexMap[] = { static BIO *bio_err=NULL; + +char * getSSLErr(){ + return ERR_error_string(ERR_get_error(), errbuf); +} + static size_t bin2hex (const unsigned char* bin, size_t bin_length, char* str, size_t str_length) { char *p; @@ -218,13 +223,13 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, if(!SSL_set_fd(conn->ssl, s)){ ssl_conn_free(conn); - *errSSL = ERR_error_string(ERR_get_error(), errbuf); + *errSSL = getSSLErr(); return NULL; } if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname); err = SSL_connect(conn->ssl); if ( err == -1 ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); + *errSSL = getSSLErr(); ssl_conn_free(conn); return NULL; } @@ -250,42 +255,6 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, } -SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_key, char** errSSL){ - SSL_CTX *ctx; - int err = 0; - - -#if OPENSSL_VERSION_NUMBER < 0x10100000L - ctx = SSL_CTX_new(SSLv23_server_method()); -#else - ctx = SSL_CTX_new(TLS_server_method()); -#endif - - if (!ctx) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); - return NULL; - } - - err = SSL_CTX_use_certificate(ctx, (X509 *) server_cert); - if ( err <= 0 ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); - SSL_CTX_free(ctx); - return NULL; - } - - err = SSL_CTX_use_PrivateKey(ctx, server_key); - if ( err <= 0 ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); - SSL_CTX_free(ctx); - return NULL; - } - if(config->server_min_proto_version)SSL_CTX_set_min_proto_version(ctx, config->server_min_proto_version); - if(config->server_max_proto_version)SSL_CTX_set_max_proto_version(ctx, config->server_max_proto_version); - if(config->server_cipher_list)SSL_CTX_set_cipher_list(ctx, config->server_cipher_list); - if(config->server_ciphersuites)SSL_CTX_set_ciphersuites(ctx, config->server_ciphersuites); - return ctx; -} - SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_key, char** errSSL){ int err = 0; X509 *cert; @@ -320,7 +289,7 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert conn->ssl = SSL_new(config->cli_ctx?config->cli_ctx : conn->ctx); if ( conn->ssl == NULL ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); + *errSSL = getSSLErr(); if(conn->ctx)SSL_CTX_free(conn->ctx); free(conn); return NULL; @@ -329,7 +298,7 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert SSL_set_fd(conn->ssl, s); err = SSL_accept(conn->ssl); if ( err <= 0 ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); + *errSSL = getSSLErr(); ssl_conn_free(conn); return NULL; } diff --git a/src/plugins/SSLPlugin/my_ssl.h b/src/plugins/SSLPlugin/my_ssl.h index a9d058c..4cb554c 100644 --- a/src/plugins/SSLPlugin/my_ssl.h +++ b/src/plugins/SSLPlugin/my_ssl.h @@ -11,10 +11,6 @@ typedef void *SSL_CONN; typedef void *SSL_CERT; struct ssl_config { - int mitm; - int serv; - int cli; - char *certcache; X509 *CA_cert; X509 *server_cert; X509 *client_cert; @@ -23,11 +19,7 @@ struct ssl_config { EVP_PKEY *client_key; SSL_CTX *cli_ctx; SSL_CTX *srv_ctx; - int client_min_proto_version; - int client_max_proto_version; - int server_min_proto_version; - int server_max_proto_version; - int client_verify; + char *certcache; char * client_ciphersuites; char * server_ciphersuites; char * client_cipher_list; @@ -35,6 +27,18 @@ struct ssl_config { char * client_ca_file; char * client_ca_dir; char * client_ca_store; + char * server_ca_file; + char * server_ca_dir; + char * server_ca_store; + int mitm; + int serv; + int cli; + int client_min_proto_version; + int client_max_proto_version; + int server_min_proto_version; + int server_max_proto_version; + int client_verify; + int server_verify; }; typedef struct ssl_config SSL_CONFIG; @@ -69,6 +73,7 @@ void _ssl_cert_free(SSL_CERT cert); // Global (de)initialization // void ssl_init(void); +char * getSSLErr(void); #endif // __my_ssl_h__ \ No newline at end of file diff --git a/src/plugins/SSLPlugin/ssl_plugin.c b/src/plugins/SSLPlugin/ssl_plugin.c index a0ceb40..11beaa2 100644 --- a/src/plugins/SSLPlugin/ssl_plugin.c +++ b/src/plugins/SSLPlugin/ssl_plugin.c @@ -38,6 +38,8 @@ char *srvkey = NULL; char *clicert = NULL; char *clikey = NULL; char *server_ca_file = NULL; +char *server_ca_dir = NULL; +char *server_ca_store = NULL; char *server_ca_key = NULL; char *client_ca_file = NULL; char *client_ca_dir = NULL; @@ -51,6 +53,7 @@ int client_max_proto_version = 0; int server_min_proto_version = 0; int server_max_proto_version = 0; int client_verify = 0; +int server_verify = 0; char * client_ciphersuites = NULL; char * server_ciphersuites = NULL; char * client_cipher_list = NULL; @@ -341,6 +344,59 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx){ return preverify_ok; } + +SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_key, char** errSSL){ + SSL_CTX *ctx; + int err = 0; + + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ctx = SSL_CTX_new(SSLv23_server_method()); +#else + ctx = SSL_CTX_new(TLS_server_method()); +#endif + + if (!ctx) { + *errSSL = getSSLErr(); + return NULL; + } + + err = SSL_CTX_use_certificate(ctx, (X509 *) server_cert); + if ( err <= 0 ) { + *errSSL = getSSLErr(); + SSL_CTX_free(ctx); + return NULL; + } + + err = SSL_CTX_use_PrivateKey(ctx, server_key); + if ( err <= 0 ) { + *errSSL = getSSLErr(); + SSL_CTX_free(ctx); + return NULL; + } + if(config->server_min_proto_version)SSL_CTX_set_min_proto_version(ctx, config->server_min_proto_version); + if(config->server_max_proto_version)SSL_CTX_set_max_proto_version(ctx, config->server_max_proto_version); + if(config->server_cipher_list)SSL_CTX_set_cipher_list(ctx, config->server_cipher_list); + if(config->server_ciphersuites)SSL_CTX_set_ciphersuites(ctx, config->server_ciphersuites); + if(config->server_verify){ +fprintf(stderr, "server verify\n"); +fflush(stderr); + if(config->server_ca_file || config->server_ca_dir){ + SSL_CTX_load_verify_locations(ctx, config->server_ca_file, config->server_ca_dir); + } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + else if(config->server_ca_store){ + SSL_CTX_load_verify_store(ctx, config->server_ca_store); + } +#endif + else + SSL_CTX_set_default_verify_paths(ctx); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_CLIENT_ONCE, NULL); + } + return ctx; +} + + static void* ssl_filter_open(void * idata, struct srvparam * srv){ char fname[256]; char *errSSL; @@ -355,6 +411,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){ sc->server_min_proto_version = server_min_proto_version; sc->server_max_proto_version = server_max_proto_version; sc->client_verify = client_verify; + sc->server_verify = server_verify; if(client_ciphersuites) sc->client_ciphersuites = strdup(client_ciphersuites); if(server_ciphersuites) sc->server_ciphersuites = strdup(server_ciphersuites); if(client_cipher_list) sc->client_cipher_list = strdup(client_cipher_list); @@ -375,7 +432,10 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){ } if(client_ca_file)sc->client_ca_file=client_ca_file; if(client_ca_dir)sc->client_ca_dir=client_ca_dir; - if(client_ca_store)sc->client_ca_dir=client_ca_store; + if(client_ca_store)sc->client_ca_store=client_ca_store; + if(server_ca_file)sc->server_ca_file=server_ca_file; + if(server_ca_dir)sc->server_ca_dir=server_ca_dir; + if(server_ca_store)sc->server_ca_store=server_ca_store; if(mitm){ @@ -474,7 +534,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){ #endif else SSL_CTX_set_default_verify_paths(sc->srv_ctx); - SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER, verify_callback); + SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } } #ifdef WIWHSPLICE @@ -770,6 +830,18 @@ static int h_client_ca_store(int argc, unsigned char **argv){ return 0; } +static int h_server_ca_dir(int argc, unsigned char **argv){ + free(server_ca_dir); + server_ca_dir = argc > 1? strdup((char *)argv[1]) : NULL; + return 0; +} + +static int h_server_ca_store(int argc, unsigned char **argv){ + free(server_ca_store); + server_ca_store = argc > 1? strdup((char *)argv[1]) : NULL; + return 0; +} + struct vermap{ char *sver; int iver; @@ -836,6 +908,15 @@ static int h_no_client_verify(int argc, unsigned char **argv){ return 0; } +static int h_server_verify(int argc, unsigned char **argv){ + server_verify = 1; + return 0; +} +static int h_no_server_verify(int argc, unsigned char **argv){ + server_verify = 0; + return 0; +} + static struct commands ssl_commandhandlers[] = { {ssl_commandhandlers+1, "ssl_mitm", h_mitm, 1, 1}, {ssl_commandhandlers+2, "ssl_nomitm", h_nomitm, 1, 1}, @@ -862,6 +943,14 @@ static struct commands ssl_commandhandlers[] = { {ssl_commandhandlers+23, "ssl_nocli", h_nocli, 1, 1}, {ssl_commandhandlers+24, "ssl_client_cert", h_clicert, 1, 2}, {ssl_commandhandlers+25, "ssl_client_key", h_clikey, 1, 2}, + {ssl_commandhandlers+26, "ssl_server", h_serv, 1, 1}, + {ssl_commandhandlers+27, "ssl_noserver", h_noserv, 1, 1}, + {ssl_commandhandlers+28, "ssl_client", h_cli, 1, 1}, + {ssl_commandhandlers+29, "ssl_noclient", h_nocli, 1, 1}, + {ssl_commandhandlers+30, "ssl_server_verify", h_server_verify, 1, 1}, + {ssl_commandhandlers+31, "ssl_server_no_verify", h_no_server_verify, 1, 1}, + {ssl_commandhandlers+32, "ssl_server_ca_dir", h_server_ca_dir, 1, 2}, + {ssl_commandhandlers+33, "ssl_server_ca_store", h_server_ca_store, 1, 2}, {NULL, "ssl_certcache", h_certcache, 2, 2}, }; @@ -875,22 +964,30 @@ static struct commands ssl_commandhandlers[] = { PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink, int argc, char** argv){ + mitm = 0; + serv = 0; + cli = 0; + pl = pluginlink; ssl_connect_timeout = 0; + free(certcache); certcache = NULL; free(srvcert); srvcert = NULL; free(srvkey); srvkey = NULL; - mitm = 0; - serv = 0; + free(clicert); + clicert = NULL; + free(clikey); + clikey = NULL; client_min_proto_version = 0; client_max_proto_version = 0; server_min_proto_version = 0; server_max_proto_version = 0; client_verify = 0; + server_verify = 0; free(client_ciphersuites); client_ciphersuites = NULL; free(server_ciphersuites); @@ -909,6 +1006,10 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink, client_ca_dir = NULL; free(client_ca_store); client_ca_store = NULL; + free(server_ca_dir); + server_ca_dir = NULL; + free(server_ca_store); + server_ca_store = NULL; if(!ssl_loaded){