]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Working to have good SSL code
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Tue, 6 Aug 2024 13:59:34 +0000 (09:59 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Tue, 6 Aug 2024 13:59:34 +0000 (09:59 -0400)
lib/devsoc.c
lib/subrou.c
lib/unissl.c
lib/unissl.h

index a8baf570c9c037dd53593fc1861600114699bf5e..061178ae2b7acbd52ab8c621e53acfcf11586c1e 100644 (file)
@@ -34,8 +34,7 @@
 typedef struct  {
         PROTYP proto;   //Connexion protocol type
         int handle;     //connexion handle
-        SSL *ssl;       //ssl channel
-        SSL_CTX *ctx;   //encryption context
+        SSLTYP *ssl;    //full SSL channel
         int maxcarin;   //absolute number within carin
         char *EOL;      //End of line marker
         int carin;      //number of char within incpt;
@@ -703,12 +702,11 @@ while (proceed==true) {
           phase=999;            
           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
+          if ((newsoc->ssl=ssl_openssl(newsoc->handle,true))==(SSLTYP *)0) {
             newsoc=soc_release(newsoc); //trouble trouble
+            break;
+            }
+          (void) ssl_check_peer(newsoc->ssl);
           break;
         default                 :       //undefined socket type???
           (void) rou_alert(0,"%s, Undefined socket protocol='%d' (Bug?)",
@@ -835,7 +833,7 @@ while (proceed==true) {
         }
       break;
     case 3      :       //freeing the SSL contaxt
-      soc->ctx=ssl_releasectx(soc->ctx);
+      soc->ssl=ssl_closessl(soc->ssl);
       break;
     case 4      :       //fee memory used by socket
       soc=freesocket(soc);
index fb3543a3ac62f7f69b0f29147d59237fd45dca8e..8e79d90749393e4ee868fd4f1982ffd02aa6eb9f 100644 (file)
@@ -20,7 +20,7 @@
 
 //version definition 
 #define VERSION "0.3"
-#define RELEASE "25"
+#define RELEASE "26"
 
 //Public variables
 PUBLIC  int debug=0;            //debug level
index 744530a6f015c2aaa37461be2a3055baf4f25ae1..208dde0110453bfcd585961c96e09cb3ac6b17f5 100644 (file)
@@ -18,78 +18,157 @@ static  _Bool modopen;        //module open/close status
 */
 /********************************************************/
 /*                                                      */
-/*     Procedure to realease all SSL contaxt           */
+/*     Procedure to report display ALL ssl error queue */
 /*                                                      */
 /********************************************************/
-PUBLIC SSL_CTX *ssl_releasectx(SSL_CTX *ctx)
+static void showerrorstack(char *msg)
 
 {
-(void) SSL_CTX_free(ctx);
-return (SSL_CTX *)0;
+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));
+  }
 }
 /*
 ^L
 */
 /********************************************************/
 /*                                                      */
-/*     Procedure to establish a working SSL context    */
-/*      Return SLL context or a NULL pointer            */
+/*     Procedure to report display all erro queue      */
+/*      after afyer an ssl action. Return true if no    */
+/*      fatal error found.                              */
 /*                                                      */
 /********************************************************/
-PUBLIC SSL_CTX *ssl_getctx(_Bool server_mode)
+static _Bool showsslerror(SSLTYP *ssl,int sslerror,char *msg)
 
 {
-#define OPEP    "unissl.c:ssl_getctx"
+#define OPEP    "unissl.c:showsslerror"
+_Bool good;
 
-SSL_CTX *ctx;
-const SSL_METHOD *(*tls_methode)();
+good=true;
+if (sslerror<=0) {
+  char *detail;
+  int code;
+
+  good=false;
+  detail="Unexpected error";
+  switch (sslerror) {
+    case 0      :
+      (void) showerrorstack(msg);
+      break;
+    default     :
+      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);
+      switch (code) {
+        case SSL_ERROR_ZERO_RETURN      :
+          detail="zero return";
+          break;
+        case SSL_ERROR_WANT_READ        :
+          detail="want read";
+          break;
+        case SSL_ERROR_WANT_WRITE       :
+          detail="want write";
+          break;
+        case SSL_ERROR_WANT_CONNECT     :
+          detail="want connect";
+          break;
+        case SSL_ERROR_WANT_X509_LOOKUP :
+          detail="want X509 lookup";
+          break;
+        case SSL_ERROR_SYSCALL          :
+          if (ERR_get_error()==0)
+            detail="Premature EOF";
+          else
+            detail="syscall error";
+          break;
+        case SSL_ERROR_SSL              :
+          detail=ERR_error_string(ERR_get_error(),(char *)0);
+          break;
+        default                         :
+          (void) rou_alert(0,"%s, caused by <%s>  Unexpected ssl error='%d'",
+                             OPEP,msg,code);
+          detail=(char *)0;
+          break;
+        }
+      break;
+    }
+  if (detail!=(char *)0)
+    (void) rou_alert(4,"%s, caused by <%s>, error=<%s>",OPEP,msg,detail);
+  }
+return good;
+#undef  OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to open an SSL channel                */
+/*                                                      */
+/********************************************************/
+static SSLTYP *freessl(SSLTYP *ssl)
+
+{
+if (ssl!=(SSLTYP *)0) {
+  if (ssl->ctx!=(SSL_CTX *)0)
+    (void) SSL_CTX_free(ssl->ctx);
+  (void) free(ssl);
+  ssl=(SSLTYP *)0;
+  }
+return ssl;
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to open an SSL channel                */
+/*                                                      */
+/********************************************************/
+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;
 
-ctx=(SSL_CTX *)0;
+ssl=(SSLTYP *)0;
+certpub[0]="./kleenex/cert.pem";  //JMPDBG test 
+certpub[1]="./kleenex/key.pem";   //JMPDBG test 
 tls_methode=TLS_client_method;
-if (server_mode==true)
+if (server==true)
   tls_methode=TLS_server_method;
 phase=0;
 proceed=true;
 while (proceed==true) {
   switch (phase) {
-    case 0      :       //Setting inital context
-      if ((ctx=SSL_CTX_new(tls_methode()))==(SSL_CTX *)0) {
-        char reason[200];
-
-        (void) ERR_error_string(ERR_get_error(),reason);
-        (void) rou_core_dump("%s, Unable to set the SSL context err=<%s> (system?)",
-                              OPEP,reason);
-        phase=999;      //Useless, cire dump never return
+    case 0      :       //prepare the structure first;
+      ssl=(SSLTYP *)calloc(1,sizeof(SSLTYP));
+      ssl->server=server;
+      if ((ssl->ctx=SSL_CTX_new(tls_methode()))==(SSL_CTX *)0) {
+        (void) showsslerror(ssl,0,"Get CTX");
+        ssl=freessl(ssl);
+        phase=999;      //no need to go furter
         }
       break;
-    case 1      :       //getting certificat name
-      certpub[0]="./kleenex/cert.pem";  //JMPDBG test 
-      certpub[1]="./kleenex/key.pem";   //JMPDBG test 
-      break;
-    case 2      :       //set certificate
-      if (SSL_CTX_use_certificate_file(ctx,certpub[0],SSL_FILETYPE_PEM)!=1) {
-        char reason[200];
-
-        (void) ERR_error_string(ERR_get_error(),reason);
-        (void) rou_alert(0,"Unable to use certificate <%s> (error=<%s>)",
-                            certpub[0],reason);
-        (void) SSL_CTX_free(ctx);
-        ctx=(SSL_CTX *)0;
-        phase=999;
+    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 3      :       //set key
-      if (SSL_CTX_use_PrivateKey_file(ctx,certpub[1],SSL_FILETYPE_PEM)!=1) {
-        char reason[200];
-
-        (void) ERR_error_string(ERR_get_error(),reason);
-        (void) rou_alert(0,"Unable to use certificate key <%s> (error=<%s>)",
-                            certpub[0],reason);
-        (void) SSL_CTX_free(ctx);
-        ctx=(SSL_CTX *)0;
+    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;
         }
       break;
@@ -99,7 +178,7 @@ while (proceed==true) {
     }
   phase++;
   }
-return ctx;
+return ssl;
 #undef  OPEP
 }
 /*
@@ -107,12 +186,25 @@ return ctx;
 */
 /********************************************************/
 /*                                                      */
+/*     Procedure to close an SSL channel               */
+/*                                                      */
+/********************************************************/
+PUBLIC SSLTYP *ssl_closessl(SSLTYP *ssl)
+
+{
+return ssl;
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to check if remote certificat is a    */
 /*      valide one.                                     */
 /*      return -1if trouble, 0 otherwise                */
 /*                                                      */
 /********************************************************/
-PUBLIC int ssl_check_peer(SSL *ssl)
+PUBLIC int ssl_check_peer(SSLTYP *ssl)
 
 {
 #define OPEP "unissl.c:ssl_check_peer"
@@ -130,27 +222,19 @@ while (proceed==true) {
   (void) printf("JMPDBG phase='%d', check peer\n",phase);
   switch (phase) {
     case 0      :       //check SSL
-      if (ssl==(SSL *)0) {
+      if ((ssl==(SSLTYP *)0)||(ssl->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);
+      if ((peer=SSL_get_peer_certificate(ssl->ssl))==(X509 *)0) {
+        (void) showsslerror(ssl,0,"Get peer Certificate");
         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);
+      if (SSL_get_verify_result(ssl->ssl)!=X509_V_OK) {
+        (void) showsslerror(ssl,0,"Get Verify peer Certificate");
         phase=999;      //trouble trouble
         }
       (void) X509_free(peer);
@@ -213,14 +297,6 @@ while (proceed==true) {
         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;
index 3b38e101ad1b92e7274bceaa1d4e96ad34896138..60a07cbe2e68637d190b8f20b508a08856816f50 100644 (file)
 #include        <stdbool.h>
 #include        <openssl/ssl.h>
 
-//releasing current SSL context;
-extern SSL_CTX *ssl_releasectx(SSL_CTX *ctx);
+typedef struct  {
+        _Bool server;   //SSL server/client mode
+        SSL_CTX *ctx;   //SSL context
+        SSL *ssl;       //SSL link
+        BIO *bio;       //SSL Basic input output
+        }SSLTYP;
 
-//establishing SSL working context
-extern SSL_CTX *ssl_getctx(_Bool server_mode);
+//procedure to open an ssl channel
+extern SSLTYP *ssl_openssl(int handle,_Bool server);
+
+//procedure to close an ssl channel
+extern SSLTYP *ssl_closessl(SSLTYP *ssl);
 
 //check peer certificat
-extern int ssl_check_peer(SSL *ssl);
+extern int ssl_check_peer(SSLTYP *ssl);
 
 //set socket as an ssl socket
 extern SSL *ssl_setsocket(int handle,SSL_CTX *ctx);