Keep TLS server context

This commit is contained in:
Vladimir Dubrovin 2024-03-09 18:37:44 +03:00
parent 144af547fb
commit d87241c487
3 changed files with 57 additions and 48 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;