diff --git a/src/plugins/SSLPlugin/my_ssl.c b/src/plugins/SSLPlugin/my_ssl.c index 1f0a0a6..5ffb11c 100644 --- a/src/plugins/SSLPlugin/my_ssl.c +++ b/src/plugins/SSLPlugin/my_ssl.c @@ -114,7 +114,6 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config) err = X509_digest(src_cert, EVP_sha1(), hash_sha1, NULL); if(!err){ - X509_free(dst_cert); return NULL; } @@ -226,8 +225,39 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CTX *srv_ctx, SS return conn; } -SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CERT server_cert, EVP_PKEY *server_key, char** errSSL) -{ + +SSL_CTX * ssl_cli_ctx(SSL_CERT 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; + } + return ctx; +} + +SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CTX *cli_ctx, SSL_CERT server_cert, EVP_PKEY *server_key, char** errSSL){ int err = 0; X509 *cert; ssl_conn *conn; @@ -238,46 +268,20 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CERT server_cert, EVP_PKEY *serve if ( conn == NULL ) return NULL; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - conn->ctx = SSL_CTX_new(SSLv23_server_method()); -#else - conn->ctx = SSL_CTX_new(TLS_server_method()); -#endif - if ( conn->ctx == NULL ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); - free(conn); + conn->ctx = NULL; + conn->ssl = NULL; + if(!cli_ctx){ + conn->ctx = ssl_cli_ctx(server_cert, server_key, errSSL); + if(!conn->ctx){ + ssl_conn_free(conn); return NULL; + } } - err = SSL_CTX_use_certificate(conn->ctx, (X509 *) server_cert); - if ( err <= 0 ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); - SSL_CTX_free(conn->ctx); - free(conn); - return NULL; - } - - err = SSL_CTX_use_PrivateKey(conn->ctx, server_key); - if ( err <= 0 ) { - *errSSL = ERR_error_string(ERR_get_error(), errbuf); - SSL_CTX_free(conn->ctx); - free(conn); - return NULL; - } -/* - err = SSL_CTX_load_verify_locations(conn->ctx, "3proxy.pem", - NULL); - if ( err <= 0 ) { - SSL_CTX_free(conn->ctx); - free(conn); - return NULL; - } -*/ - - conn->ssl = SSL_new(conn->ctx); + conn->ssl = SSL_new(cli_ctx?cli_ctx : conn->ctx); if ( conn->ssl == NULL ) { *errSSL = ERR_error_string(ERR_get_error(), errbuf); - SSL_CTX_free(conn->ctx); + if(conn->ctx)SSL_CTX_free(conn->ctx); free(conn); return NULL; } diff --git a/src/plugins/SSLPlugin/my_ssl.h b/src/plugins/SSLPlugin/my_ssl.h index d266ce4..c87f43b 100644 --- a/src/plugins/SSLPlugin/my_ssl.h +++ b/src/plugins/SSLPlugin/my_ssl.h @@ -33,8 +33,9 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config); // // SSL/TLS handshakes // +SSL_CTX * ssl_cli_ctx(SSL_CERT server_cert, EVP_PKEY *server_key, char** errSSL); SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CTX *srv_ctx, SSL_CERT *server_cert, char **errSSL); -SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CERT server_cert, EVP_PKEY *server_key, char **errSSL); +SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CTX *cli_ctx, SSL_CERT server_cert, EVP_PKEY *server_key, char **errSSL); // // SSL/TLS Read/Write diff --git a/src/plugins/SSLPlugin/ssl_plugin.c b/src/plugins/SSLPlugin/ssl_plugin.c index 48f8c1f..cd6590f 100644 --- a/src/plugins/SSLPlugin/ssl_plugin.c +++ b/src/plugins/SSLPlugin/ssl_plugin.c @@ -92,9 +92,9 @@ void delSSL(void *state, SOCKET s){ STATE->cli.s = INVALID_SOCKET; } else if(STATE->srv.s == s) { - ssl_conn_free(STATE->cli.conn); - STATE->cli.conn = NULL; - STATE->cli.s = INVALID_SOCKET; + ssl_conn_free(STATE->srv.conn); + STATE->srv.conn = NULL; + STATE->srv.s = INVALID_SOCKET; } } @@ -216,7 +216,7 @@ static int WINAPI ssl_poll(void *state, struct pollfd *fds, unsigned int nfds, i #define PCONF (((struct SSLstate *)param->sostate)->config) -int domitm(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientConnp){ +int domitm(struct clientparam* param){ SSL_CERT ServerCert=NULL, FakeCert=NULL; SSL_CONN ServerConn, ClientConn; char *errSSL=NULL; @@ -240,6 +240,7 @@ int domitm(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientCon } ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, PCONF->srv_ctx, &ServerCert, &errSSL); if ( ServerConn == NULL || ServerCert == NULL ) { + if(ServerConn) ssl_conn_free(ServerConn); param->res = 8011; param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed"); if(ServerConn == NULL) param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL"); @@ -256,7 +257,7 @@ int domitm(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientCon return 2; } - ClientConn = ssl_handshake_to_client(param->clisock, FakeCert, PCONF->server_key?PCONF->server_key:PCONF->CA_key, &errSSL); + ClientConn = ssl_handshake_to_client(param->clisock, NULL, FakeCert, PCONF->server_key?PCONF->server_key:PCONF->CA_key, &errSSL); _ssl_cert_free(FakeCert); if ( ClientConn == NULL ) { @@ -283,8 +284,6 @@ int domitm(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientCon SSL_set_read_ahead((SSL *)((ssl_conn *)ServerConn)->ssl, 0); SSL_set_read_ahead((SSL *)((ssl_conn *)ClientConn)->ssl, 0); addSSL(param->clisock, ClientConn, param->remsock, ServerConn, param); - if(ServerConnp)*ServerConnp = ServerConn; - if(ClientConnp)*ClientConnp = ClientConn; return 0; } @@ -314,6 +313,7 @@ EVP_PKEY * getKey(const char *fname){ static void* ssl_filter_open(void * idata, struct srvparam * srv){ char fname[256]; + char *errSSL; struct ssl_config *sc; sc = malloc(sizeof(struct ssl_config)); if(!sc) return NULL; @@ -360,6 +360,10 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){ fprintf(stderr, "failed to read: %s\n", srvkey); return sc; } + if(!(sc->cli_ctx = ssl_cli_ctx(sc->server_cert, sc->server_key, &errSSL))){ + fprintf(stderr, "failed to create context: %s\n", errSSL); + return sc; + } sc->serv = 1; srv->so._send = ssl_send; srv->so._recv = ssl_recv; @@ -406,7 +410,7 @@ static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, voi fcntl(param->clisock,F_SETFL,0); #endif - ClientConn = ssl_handshake_to_client(param->clisock, ssls->config->server_cert, ssls->config->server_key, &err); + ClientConn = ssl_handshake_to_client(param->clisock, ssls->config->cli_ctx, NULL, NULL, &err); if ( ClientConn == NULL ) { param->res = 8013; param->srv->logfunc(param, (unsigned char *)"Handshake to client failed"); @@ -431,7 +435,7 @@ static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, voi static FILTER_ACTION ssl_filter_predata(void *fc, struct clientparam * param){ if(param->operation != HTTP_CONNECT && param->operation != CONNECT) return PASS; if(!PCONF->mitm) return PASS; - if(domitm(param, NULL, NULL)) { + if(domitm(param)) { return REJECT; } if(!param->redirectfunc) param->redirectfunc = proxyfunc;