*/
/********************************************************/
/* */
-/* 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;
}
phase++;
}
-return ctx;
+return ssl;
#undef OPEP
}
/*
*/
/********************************************************/
/* */
+/* 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"
(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);
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;