From 806e176801ae4840570c538b6604a072a67f96b8 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Tue, 6 Aug 2024 22:26:31 -0400 Subject: [PATCH] defining a read and write on SSL socket --- lib/devsoc.c | 91 +++++++++++++++++--------------- lib/subrou.c | 2 +- lib/unissl.c | 145 +++++++++++++++++++++++++++++++++++++++++++++------ lib/unissl.h | 6 +++ 4 files changed, 186 insertions(+), 58 deletions(-) diff --git a/lib/devsoc.c b/lib/devsoc.c index 061178a..9c3235f 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -34,7 +34,8 @@ typedef struct { PROTYP proto; //Connexion protocol type int handle; //connexion handle - SSLTYP *ssl; //full SSL channel + _Bool modtls; //soc is in TLS mode + SSLTYP *ssl; //full TPS/SSL channel int maxcarin; //absolute number within carin char *EOL; //End of line marker int carin; //number of char within incpt; @@ -466,14 +467,23 @@ PUBLIC int soc_waitforchar(SOCPTR *socptr,TIMESPEC *attend) { register int status; +SOCTYP *soc; status=-1; -if (socptr!=(SOCTYP *)0) { +soc=(SOCTYP *)socptr; +if (soc!=(SOCTYP *)0) { struct pollfd polling[1]; polling[0].events=POLLIN|POLLPRI; polling[0].revents=(short)0; - polling[0].fd=((SOCTYP *)socptr)->handle; + switch (soc->modtls) { + case true : + polling[0].fd=SSL_get_fd(soc->ssl->ssl); + break; + case false : + polling[0].fd=soc->handle; + break; + } status=ppoll(polling,1,attend,(sigset_t *)0); } return status; @@ -555,37 +565,22 @@ return got; PUBLIC int soc_writebuffer(SOCPTR *socptr,char *buffer,int tosend) { -#define OPEP "devsoc.c:soc_writebuffer" - int sent; SOCTYP *soc; sent=-1; soc=(SOCTYP *)socptr; if (soc!=(SOCTYP *)0) { - int got; - - got=recv(soc->handle,(char *)0,0,MSG_PEEK); - switch (got) { - case -1 : - if (errno==EWOULDBLOCK) - errno=EAGAIN; - switch (errno) { - case EAGAIN : - sent=send(soc->handle,buffer,tosend,0); - break; - default : - (void) rou_alert(9,"%s, Unexpected status '%02d' error=<%s> (errno='%d')\n", - OPEP,got,strerror(errno),errno); - break; - } - default : - (void) fprintf(stderr,"Got JMPDBG'%02d'\n",got); + switch (soc->modtls) { + case true : + sent=ssl_write(soc->ssl,buffer,tosend); + break; + case false : + sent=send(soc->handle,buffer,tosend,0); break; } } return sent; -#undef OPEP } /* ^L @@ -599,35 +594,49 @@ return sent; PUBLIC void soc_receive(SOCPTR *socptr) { +#define OPEP "devsoc.c:soc_receive" + SOCTYP *soc; soc=(SOCTYP *)socptr; if (soc!=(SOCTYP *)0) { int got; int limit; + char *buffer; limit=(soc->maxcarin-soc->carin)-1; - got=recv(soc->handle,soc->carpile+soc->carin,limit,MSG_DONTWAIT); - switch (got) { - case -1 : //do not block - if (errno==EWOULDBLOCK) - errno=EAGAIN; - switch (errno) { - case EAGAIN : //no char available - break; - default : - (void) fprintf(stderr,"JMPDBG soc_receive error=<%s>\n",strerror(errno)); - break; + buffer=soc->carpile+soc->carin; + switch (soc->modtls) { + case true : + got=ssl_read(soc->ssl,buffer,limit); + break; + case false : + got=recv(soc->handle,buffer,limit,MSG_DONTWAIT); + switch (got) { + case -1 : //do not block + if (errno==EWOULDBLOCK) + errno=EAGAIN; + switch (errno) { + case EAGAIN : //no char available + break; + default : + (void) rou_alert(0,"%s Unexpected error <%s> (Bug)",strerror(errno)); + break; + } + break; + case 0 : //EOL? + break; + default : //we got some char from remote + break; } break; - case 0 : //EOL? - break; - default : //we got som char from remote - soc->carin+=got; //managing carpile - soc->carpile[soc->carin]='\000'; - break; + } + if (got>0) { //we have recived some character + soc->carin+=got; //managing carpile + soc->carpile[soc->carin]='\000'; } } +#undef OPEP } /* ^L diff --git a/lib/subrou.c b/lib/subrou.c index 8e79d90..3ebaa7b 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -20,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "26" +#define RELEASE "27" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unissl.c b/lib/unissl.c index 208dde0..1f2d742 100644 --- a/lib/unissl.c +++ b/lib/unissl.c @@ -6,12 +6,16 @@ /* */ /********************************************************/ #include +#include #include #include "subrou.h" #include "unissl.h" -static _Bool modopen; //module open/close status +//alternate define SSL_CIPHER_LIST "ALL:!LOW" +#define SSL_CIPHER_LIST "DEFAULT" + +static _Bool modopen; //module open/close status /* ^L @@ -28,7 +32,7 @@ int error; (void) rou_alert(0,"SSL error queue caused by <%s>",msg); while ((error=ERR_get_error())!=0) { - (void) rou_alert(0,"\t%s",ERR_error_string(error,(char *)0)); + (void) rou_alert(0,"\tcode='%d, <%s>",error,ERR_error_string(error,(char *)0)); } } /* @@ -62,6 +66,7 @@ if (sslerror<=0) { if (ssl->ssl==(SSL *)0) //in case of trouble (void) rou_core_dump("%s Unexpected NULL SSL (Bug?)",OPEP); code=SSL_get_error(ssl->ssl,sslerror); + (void) rou_alert(0,"JMPDBG err code='%d'",code); switch (code) { case SSL_ERROR_ZERO_RETURN : detail="zero return"; @@ -125,6 +130,78 @@ return ssl; */ /********************************************************/ /* */ +/* Procedure to set the serevr cerificate */ +/* */ +/********************************************************/ +static int set_server_certificate(SSL_CTX *ctx) + +{ +int done; +const char *certpub[3]; +int phase; +_Bool proceed; + +done=false; +certpub[0]="./kleenex/cert.pem"; //JMPDBG test Trusted file +certpub[1]="./kleenex/cert.pem"; //JMPDBG test +certpub[2]="./kleenex/key.pem"; //JMPDBG test +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //load CA trusted file + if (SSL_CTX_use_certificate_chain_file(ctx,certpub[0])!=1) { + (void) showsslerror((SSLTYP *)0,0,"Get trusted file"); + phase=999; //no need to go furter + } + break; + case 1 : //loading default CA verify dir + if (SSL_CTX_set_default_verify_paths(ctx)==0) { + (void) showsslerror((SSLTYP *)0,0,"Get trusted file"); + phase=999; //no need to go furter + } + break; + case 2 : //set certificate + if (SSL_CTX_use_certificate_file(ctx,certpub[1],SSL_FILETYPE_PEM)!=1) { + (void) showsslerror((SSLTYP *)0,0,"Get local Certificate"); + phase=999; //no need to go furter + } + break; + case 3 : //set key + if (SSL_CTX_use_PrivateKey_file(ctx,certpub[2],SSL_FILETYPE_PEM)!=1) { + (void) showsslerror((SSLTYP *)0,0,"Get Private Key"); + phase=999; + } + break; + case 4 : //verify management + (void) SSL_CTX_set_purpose(ctx,X509_PURPOSE_ANY); + (void) SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,(int(*)())0); + (void) SSL_CTX_set_verify_depth(ctx,5); + (void) SSL_CTX_set_options(ctx,SSL_OP_ALL); + if (SSL_CTX_set_cipher_list(ctx,SSL_CIPHER_LIST)==0) { + (void) showsslerror((SSLTYP *)0,0,"set cipher list"); + phase=999; + } + break; + case 5 : //allowing partial write + (void) SSL_CTX_set_mode(ctx,SSL_MODE_ENABLE_PARTIAL_WRITE); + break; + case 6 : //everything fine + done=true; + break; + default : //SAFE Guard + proceed=false; + break; + } + phase++; + } +return done; +} +/* +^L +*/ +/********************************************************/ +/* */ /* Procedure to open an SSL channel */ /* */ /********************************************************/ @@ -134,14 +211,11 @@ PUBLIC SSLTYP *ssl_openssl(int handle,_Bool server) #define OPEP "unissl.c:ssl_openssl" SSLTYP *ssl; -const char *certpub[2]; const SSL_METHOD *(*tls_methode)(); int phase; _Bool proceed; ssl=(SSLTYP *)0; -certpub[0]="./kleenex/cert.pem"; //JMPDBG test -certpub[1]="./kleenex/key.pem"; //JMPDBG test tls_methode=TLS_client_method; if (server==true) tls_methode=TLS_server_method; @@ -159,17 +233,11 @@ while (proceed==true) { } break; case 1 : //set certificate - if (SSL_CTX_use_certificate_file(ssl->ctx,certpub[0],SSL_FILETYPE_PEM)!=1) { - (void) showsslerror(ssl,0,"Get local Certificate"); - ssl=freessl(ssl); - phase=999; //no need to go furter - } - break; - case 2 : //set key - if (SSL_CTX_use_PrivateKey_file(ssl->ctx,certpub[1],SSL_FILETYPE_PEM)!=1) { - (void) showsslerror(ssl,0,"Get Private Key"); - ssl=freessl(ssl); - phase=999; + if (server==true) { + if (set_server_certificate(ssl->ctx)==false) { + ssl=freessl(ssl); + phase=999; //trouble, trouble no need to go furter + } } break; default : //SAFE guard @@ -199,6 +267,51 @@ return ssl; */ /********************************************************/ /* */ +/* Procedure to write a buffer contents to an SSL */ +/* channel. Retune the number of char written or */ +/* -1 if trouble. */ +/* */ +/********************************************************/ +PUBLIC int ssl_write(SSLTYP *ssl,char *buffer,int tosend) + +{ +int sent; + +sent=-1; +if (ssl!=(SSLTYP *)0) { + if ((sent=SSL_write(ssl->ssl,buffer,tosend))<=0) + (void) showsslerror(ssl,sent,"Trouble to send data"); + } +return sent; +} +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to read up to maxread character from */ +/* an ssl channel and store into a buffer. */ +/* return the number of char read, or -1 if */ +/* trouble. */ +/* */ +/********************************************************/ +PUBLIC int ssl_read(SSLTYP *ssl,char *buffer,int maxread) + +{ +int got; + +got=-1; +if (ssl!=(SSLTYP *)0) { + if ((got=SSL_read(ssl->ssl,buffer,maxread))<=0) + (void) showsslerror(ssl,got,"Trouble to read data"); + } +return got; +} +/* +^L +*/ +/********************************************************/ +/* */ /* Procedure to check if remote certificat is a */ /* valide one. */ /* return -1if trouble, 0 otherwise */ diff --git a/lib/unissl.h b/lib/unissl.h index 60a07cb..156d179 100644 --- a/lib/unissl.h +++ b/lib/unissl.h @@ -23,6 +23,12 @@ extern SSLTYP *ssl_openssl(int handle,_Bool server); //procedure to close an ssl channel extern SSLTYP *ssl_closessl(SSLTYP *ssl); +//write on the SSL channel +extern int ssl_write(SSLTYP *ssl,char *buffer,int tosend); + +//read from the SSL channel +extern int ssl_read(SSLTYP *ssl,char *buffer,int maxread); + //check peer certificat extern int ssl_check_peer(SSLTYP *ssl); -- 2.47.3