]> SAFE projects GIT repository - jmp/mailleur/commitdiff
defining a read and write on SSL socket
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 7 Aug 2024 02:26:31 +0000 (22:26 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 7 Aug 2024 02:26:31 +0000 (22:26 -0400)
lib/devsoc.c
lib/subrou.c
lib/unissl.c
lib/unissl.h

index 061178ae2b7acbd52ab8c621e53acfcf11586c1e..9c3235f64690d29c75d39cbcc8817a50d36def36 100644 (file)
@@ -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
index 8e79d90749393e4ee868fd4f1982ffd02aa6eb9f..3ebaa7bc04186e32a165605779c7aa659b1dad5e 100644 (file)
@@ -20,7 +20,7 @@
 
 //version definition 
 #define VERSION "0.3"
-#define RELEASE "26"
+#define RELEASE "27"
 
 //Public variables
 PUBLIC  int debug=0;            //debug level
index 208dde0110453bfcd585961c96e09cb3ac6b17f5..1f2d7425979f8e666998c0599a530e6b541a3574 100644 (file)
@@ -6,12 +6,16 @@
 /*                                                     */
 /********************************************************/
 #include        <openssl/err.h>
+#include        <openssl/x509v3.h>
 #include        <stdio.h>
 
 #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                */
index 60a07cbe2e68637d190b8f20b508a08856816f50..156d1793a749fb1bc1ec6734e7e4f2ed5b8ae095 100644 (file)
@@ -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);