From 9bb7edc0941536a65ac499299decc3dc5fdb93f7 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Tue, 6 Aug 2024 01:16:55 -0400 Subject: [PATCH] Working on certificate exchange --- lib/devsoc.c | 6 +++ lib/subrou.c | 2 +- lib/unissl.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/unissl.h | 6 +++ 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/lib/devsoc.c b/lib/devsoc.c index bc5b6b4..a8baf57 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -34,6 +34,7 @@ typedef struct { PROTYP proto; //Connexion protocol type int handle; //connexion handle + SSL *ssl; //ssl channel SSL_CTX *ctx; //encryption context int maxcarin; //absolute number within carin char *EOL; //End of line marker @@ -703,6 +704,11 @@ while (proceed==true) { break; case pro_smtps : //set secure socket newsoc->ctx=ssl_getctx(true); //ssl in server mode + newsoc->ssl=ssl_setsocket(newsoc->handle,newsoc->ctx); + if (newsoc->ssl!=(SSL *)0) + (void) SSL_set_accept_state(newsoc->ssl); + else + newsoc=soc_release(newsoc); //trouble trouble break; default : //undefined socket type??? (void) rou_alert(0,"%s, Undefined socket protocol='%d' (Bug?)", diff --git a/lib/subrou.c b/lib/subrou.c index 3c20ea8..fb3543a 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -20,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "24" +#define RELEASE "25" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unissl.c b/lib/unissl.c index 238d6fa..744530a 100644 --- a/lib/unissl.c +++ b/lib/unissl.c @@ -107,6 +107,134 @@ return ctx; */ /********************************************************/ /* */ +/* Procedure to check if remote certificat is a */ +/* valide one. */ +/* return -1if trouble, 0 otherwise */ +/* */ +/********************************************************/ +PUBLIC int ssl_check_peer(SSL *ssl) + +{ +#define OPEP "unissl.c:ssl_check_peer" + +int status; +X509 *peer; +int phase; +int proceed; + +status=-1; +peer=(X509 *)0; +phase=0; +proceed=true; +while (proceed==true) { + (void) printf("JMPDBG phase='%d', check peer\n",phase); + switch (phase) { + case 0 : //check SSL + if (ssl==(SSL *)0) { + phase=999; //trouble trouble (Bug?) + } + break; + case 1 : //get peer + if ((peer=SSL_get_peer_certificate(ssl))==(X509 *)0) { + char reason[200]; + + (void) ERR_error_string(ERR_get_error(),reason); + (void) rou_alert(2,"%s Unable to get peer certificate (error=<%s>)", + OPEP,reason); + phase=999; //trouble trouble + } + break; + case 2 : //is peer valid? + if (SSL_get_verify_result(ssl)!=X509_V_OK) { + char reason[200]; + + (void) ERR_error_string(ERR_get_error(),reason); + (void) rou_alert(2,"%s Unable to verify certificate (error=<%s>)", + OPEP,reason); + phase=999; //trouble trouble + } + (void) X509_free(peer); + break; + case 3 : //everything is right + status=0; + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return status; +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to link a socket reference to an */ +/* crypted (SSL) channel. */ +/* return an SSL pointer or a NULL pointer */ +/* */ +/********************************************************/ +PUBLIC SSL *ssl_setsocket(int handle,SSL_CTX *ctx) + +{ +#define OPEP "unissl.c:ssl_setsocket" + +SSL *ssl; +int phase; +_Bool proceed; + +ssl=(SSL *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Setting inital context + if ((ssl=SSL_new(ctx))==(SSL *)0) { + char reason[200]; + + (void) ERR_error_string(ERR_get_error(),reason); + (void) rou_alert(0,"%S Unable to get a new SSL channel (error=<%s>)", + OPEP,reason); + phase=999; //trouble trouble + } + break; + case 1 : //assign SSL to socket reference + if (SSL_set_fd(ssl,handle)==0) { + char reason[200]; + + (void) ERR_error_string(ERR_get_error(),reason); + (void) rou_alert(0,"%S Unable to set new SSL to socket (error=<%s>)", + OPEP,reason); + (void) free(ssl); + ssl=(SSL *)0; + phase=999; + } + break; + case 2 : //verifying SSL channel + if (ssl_check_peer(ssl)<0) { + (void) rou_alert(0,"%s Unable to check peer certificat",OPEP); + (void) free(ssl); + ssl=(SSL *)0; + phase=999; + } + break; + default : //SAFE guard + proceed=false; + break; + } + phase++; + } +return ssl; +#undef OPEP +} +/* +^L +*/ +/********************************************************/ +/* */ /* Procedure to "open/close" module and do */ /* homework purpose */ /* return zero if everything right */ diff --git a/lib/unissl.h b/lib/unissl.h index 018b6c9..3b38e10 100644 --- a/lib/unissl.h +++ b/lib/unissl.h @@ -16,6 +16,12 @@ extern SSL_CTX *ssl_releasectx(SSL_CTX *ctx); //establishing SSL working context extern SSL_CTX *ssl_getctx(_Bool server_mode); +//check peer certificat +extern int ssl_check_peer(SSL *ssl); + +//set socket as an ssl socket +extern SSL *ssl_setsocket(int handle,SSL_CTX *ctx); + //homework to be done before starting/stopping module. extern int ssl_modeunissl(_Bool mode); -- 2.47.3