From edad5cf6e2b7604204d6246be5fe6b6dd8532fa0 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Fri, 27 Aug 2010 13:20:16 +0000 Subject: Tidy up ssl code, move all ssl related stuff to vchat-ssl and clean up some wrinkles in cert verification --- vchat-config.h | 3 +- vchat-protocol.c | 42 +++++++--------- vchat-ssl.c | 144 +++++++++---------------------------------------------- vchat-ssl.h | 8 +--- 4 files changed, 41 insertions(+), 156 deletions(-) diff --git a/vchat-config.h b/vchat-config.h index 3511c68..4409107 100755 --- a/vchat-config.h +++ b/vchat-config.h @@ -23,7 +23,6 @@ #endif /* configuration array with structure as defined in vchat.h */ -extern unsigned int ignssl; extern unsigned int usetime; extern unsigned int hscroll; @@ -41,7 +40,7 @@ static volatile configoption configoptions[] = { {CF_LOGINSCRIPT, CO_STR, "loginscript","~/.vchat/loginscript", NULL, { NULL } }, {CF_ENCODING, CO_STR, "encoding", NULL, NULL, { .pstr = &encoding }}, {CF_USESSL, CO_INT, "usessl", (char *) 1, (char *)-1, { NULL } }, - {CF_IGNSSL, CO_INT, "ignssl", (char *) 0, (char *)-1, { .pint = &ignssl } }, + {CF_IGNSSL, CO_INT, "ignssl", (char *) 0, (char *)-1, { NULL } }, {CF_USECERT, CO_INT, "usecert", (char *) 1, (char *)-1, { NULL } }, {CF_USETIME, CO_INT, "usetime", (char *) 1, (char *)-1, { .pint = &usetime } }, {CF_USETOPIC, CO_INT, "usetopicbar",(char *) 1, (char *)-1, { NULL } }, diff --git a/vchat-protocol.c b/vchat-protocol.c index 700f6c7..ef035fe 100755 --- a/vchat-protocol.c +++ b/vchat-protocol.c @@ -70,7 +70,6 @@ static void pmnotsent (char *message); /* status-variable from vchat-client.c * eventloop is done as long as this is true */ extern int status; -int ignssl = 0; char *encoding; static int connect_socket( char *server, char *port ) { @@ -107,9 +106,6 @@ vcconnect (char *server, char *port) /* vchat connection x509 store */ vc_x509store_t vc_store; - /* SSL-context */ - SSL_CTX *sslctx = NULL; - /* pointer to tilde-expanded certificate/keyfile-names */ char *certfile = NULL, *keyfile = NULL; @@ -164,10 +160,9 @@ vcconnect (char *server, char *port) vc_x509store_set_pkeycb(&vc_store, (vc_askpass_cb_t)passprompt); vc_x509store_setkeyfile(&vc_store, tildex); } - vc_x509store_setignssl(&vc_store, getintoption(CF_IGNSSL)); /* upgrade our plain BIO to ssl */ - if( vc_connect_ssl( &server_conn, &vc_store, &sslctx ) ) + if( vc_connect_ssl( &server_conn, &vc_store ) ) BIO_free_all( server_conn ); } @@ -279,7 +274,7 @@ topicinfo (char *message) { char *channel = NULL, *topic = NULL; int tmpchan = 0; - + /* search start of channel number */ channel = strchr (message, ' '); channel++; @@ -443,7 +438,7 @@ nickerr (char *message) setstroption(CF_NICK,NULL); /* get new nick via vchat-ui.c */ nickprompt (); - + /* form login message and send it to server */ snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", nick, getstroption (CF_FROM), getintoption (CF_CHANNEL)); networkoutput (tmpstr); @@ -455,8 +450,7 @@ nickerr (char *message) * vars: %s - this users registered nick * %s msg - server message */ static void -login (char *message) -{ +login (char *message) { char *msg = NULL; /* mutate message for output */ @@ -465,23 +459,19 @@ login (char *message) writecf (FS_SERV,&message[2]); /* we don't know our nick? */ - if (!nick) - { - /* find message after nick */ - msg = strchr (&message[4], ' '); - if (msg) - { - /* terminate string before message and copy nick */ - msg[0] = '\0'; - setstroption(CF_NICK,&message[4]); - } - else - { - /* no string in servers message (huh?), ask user for nick */ - nickprompt (); - } + if (!nick) { + /* find message after nick */ + msg = strchr (&message[4], ' '); + if (msg) { + /* terminate string before message and copy nick */ + msg[0] = '\0'; + setstroption(CF_NICK,&message[4]); + } else { + /* no string in servers message (huh?), ask user for nick */ + nickprompt (); } - + } + /* form login message and send it to server */ snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", nick, getstroption (CF_FROM), getintoption (CF_CHANNEL)); networkoutput (tmpstr); diff --git a/vchat-ssl.c b/vchat-ssl.c index 1a1ff16..652ca09 100755 --- a/vchat-ssl.c +++ b/vchat-ssl.c @@ -27,13 +27,13 @@ #include #include +#include + #include "vchat.h" #include "vchat-ssl.h" char *vchat_ssl_version = "$Id$"; -static int ignore_ssl; - #define VC_CTX_ERR_EXIT(se, cx) do { \ snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", \ ERR_error_string (ERR_get_error (), NULL)); \ @@ -119,25 +119,16 @@ SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ) return(ctx); } -int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store, SSL_CTX **ctx) +int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store ) { - BIO *ssl_conn = NULL; - int _ctx = 0; - - if(*ctx) { - CRYPTO_add( &((*ctx)->references), 1, CRYPTO_LOCK_SSL_CTX ); - if( vc_store && vc_store != SSL_CTX_get_app_data(*ctx) ) { - SSL_CTX_set_cert_store(*ctx, vc_x509store_create(vc_store)); - SSL_CTX_set_app_data(*ctx, vc_store); - } - } else { - *ctx = vc_create_sslctx(vc_store); - _ctx = 1; - } + BIO *ssl_conn = NULL; + SSL_CTX * ctx = vc_create_sslctx(vc_store); + + if( !ctx ) + return 1; - ssl_conn = BIO_new_ssl(*ctx, 1); - if(_ctx) - SSL_CTX_free(*ctx); + ssl_conn = BIO_new_ssl(ctx, 1); + SSL_CTX_free(ctx); if( ssl_conn ) { BIO_push( ssl_conn, *conn ); @@ -153,88 +144,6 @@ int vc_connect_ssl( BIO **conn, vc_x509store_t *vc_store, SSL_CTX **ctx) return 1; } -int vc_verify_cert_hostname(X509 *cert, char *host) -{ - int i = 0; - int j = 0; - int n = 0; - int extcount = 0; - int ok = 0; - - X509_NAME *subj = NULL; - const char *extstr = NULL; - CONF_VALUE *nval = NULL; - const unsigned char *data = NULL; - X509_EXTENSION *ext = NULL; - X509V3_EXT_METHOD *meth = NULL; - STACK_OF(CONF_VALUE) *val = NULL; - - char name[256]; - memset(&name, 0, sizeof(name)); - - if((extcount = X509_get_ext_count(cert)) > 0) { - - for(i=0; !ok && i < extcount; i++) { - - meth = NULL; - - ext = X509_get_ext(cert, i); - extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); - - if(!strcasecmp(extstr, "subjectAltName")) { - - if( !(meth = X509V3_EXT_get(ext)) ) - break; - - if( !(meth->d2i) ) - break; - - data = ext->value->data; - - val = meth->i2v(meth, meth->d2i(0, &data, ext->value->length), 0); - for( j=0, n=sk_CONF_VALUE_num(val); jname, "DNS") && - !strcasecmp(nval->value, host) ) { - ok = 1; - break; - } - } - } - } - } - - if( !ok && (subj = X509_get_subject_name(cert)) && - X509_NAME_get_text_by_NID(subj, NID_commonName, - name, sizeof(name)) > 0 ) { - name[sizeof(name)-1] = '\0'; - if(!strcasecmp(name, host)) - ok = 1; - } - - //printf("[*] vc_verify_cert_hostname() return: %d\n", ok); - return(ok); -} - -int vc_verify_cert(X509 *cert, vc_x509store_t *vc_store) -{ - int result = -1; - X509_STORE *store = NULL; - X509_STORE_CTX *ctx = NULL; - - if( !(store = vc_x509store_create(vc_store)) ) - return(result); - - if( (ctx = X509_STORE_CTX_new()) != 0 ) { - if(X509_STORE_CTX_init(ctx, store, cert, 0) == 1) - result = (X509_verify_cert(ctx) == 1); - X509_STORE_CTX_free(ctx); - } - - X509_STORE_free(store); - return(result); -} - #define VC_STORE_ERR_EXIT(s) do { \ fprintf(stderr, "[E] SSL_STORE: %s\n", ERR_error_string (ERR_get_error (), NULL)); \ if(s) X509_STORE_free(s); \ @@ -300,7 +209,7 @@ int vc_verify_callback(int ok, X509_STORE_CTX *store) { if(!ok) { /* XXX handle action/abort */ - if(!ignore_ssl) + if(!(ok=getintoption(CF_IGNSSL))) snprintf(tmpstr, TMPSTRSIZE, "[SSL ERROR] %s", X509_verify_cert_error_string(store->error)); else @@ -308,7 +217,6 @@ int vc_verify_callback(int ok, X509_STORE_CTX *store) X509_verify_cert_error_string(store->error)); writecf(FS_ERR, tmpstr); - ok = ignore_ssl; } return(ok); } @@ -318,12 +226,6 @@ void vc_x509store_setflags(vc_x509store_t *store, int flags) store->flags |= flags; } -void vc_x509store_setignssl(vc_x509store_t *store, int ignore) -{ - store->ignore_ssl |= ignore; - ignore_ssl = ignore; -} - void vc_x509store_clearflags(vc_x509store_t *store, int flags) { store->flags &= ~flags; @@ -348,31 +250,31 @@ void vc_x509store_addcert(vc_x509store_t *store, X509 *cert) void vc_x509store_setcafile(vc_x509store_t *store, char *file) { - if( store->cafile) free(store->cafile); + free(store->cafile); store->cafile = ( file ? strdup(file) : 0 ); } void vc_x509store_setcapath(vc_x509store_t *store, char *path) { - if( store->capath) free(store->capath); + free(store->capath); store->capath = ( path ? strdup(path) : 0 ); } void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) { - if( store->crlfile) free(store->crlfile); + free(store->crlfile); store->crlfile = ( file ? strdup(file) : 0 ); } void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) { - if( store->use_keyfile) free(store->use_keyfile); + free(store->use_keyfile); store->use_keyfile = ( file ? strdup(file) : 0 ); } void vc_x509store_setcertfile(vc_x509store_t *store, char *file) { - if( store->use_certfile) free(store->use_certfile); + free(store->use_certfile); store->use_certfile = ( file ? strdup(file) : 0 ); } @@ -391,19 +293,17 @@ void vc_init_x509store(vc_x509store_t *s) s->use_keyfile = NULL; s->use_key = NULL; s->flags = 0; - s->ignore_ssl = 0; } void vc_cleanup_x509store(vc_x509store_t *s) { - if(s->cafile) free(s->cafile); - if(s->capath) free(s->capath); - if(s->crlfile) free(s->crlfile); - if(s->use_certfile) free(s->use_certfile); - if(s->use_keyfile) free(s->use_keyfile); - if(s->use_key) free(s->use_key); + free(s->cafile); + free(s->capath); + free(s->crlfile); + free(s->use_certfile); + free(s->use_keyfile); + free(s->use_key); sk_X509_free(s->certs); sk_X509_free(s->crls); sk_X509_free(s->use_certs); - s->ignore_ssl = 0; } diff --git a/vchat-ssl.h b/vchat-ssl.h index c745c97..baaa3c4 100755 --- a/vchat-ssl.h +++ b/vchat-ssl.h @@ -16,12 +16,11 @@ typedef struct { char *use_keyfile; EVP_PKEY *use_key; int flags; - int ignore_ssl; } vc_x509store_t; /* prototypes */ -int vc_connect_ssl(BIO **conn, vc_x509store_t *, SSL_CTX **); +int vc_connect_ssl(BIO **conn, vc_x509store_t * ); SSL_CTX * vc_create_sslctx( vc_x509store_t *); void vc_init_x509store(vc_x509store_t *); void vc_cleanup_x509store(vc_x509store_t *); @@ -34,15 +33,12 @@ void vc_x509store_addcert(vc_x509store_t *, X509 *); void vc_x509store_setcb(vc_x509store_t *, vc_x509verify_cb_t); void vc_x509store_set_pkeycb(vc_x509store_t *, vc_askpass_cb_t); void vc_x509store_setflags(vc_x509store_t *, int); -void vc_x509store_setignssl(vc_x509store_t *, int); void vc_x509store_clearflags(vc_x509store_t *, int); -int vc_verify_cert(X509 *, vc_x509store_t *); -int vc_verify_cert_hostname(X509 *, char *); int vc_verify_callback(int, X509_STORE_CTX *); X509_STORE * vc_x509store_create(vc_x509store_t *); #define VC_X509S_NODEF_CAFILE 0x01 -#define VC_X509S_NODEF_CAPATH 0x02 +#define VC_X509S_NODEF_CAPATH 0x02 #define VC_X509S_USE_CERTIFICATE 0x04 #define VC_X509S_SSL_VERIFY_NONE 0x10 #define VC_X509S_SSL_VERIFY_PEER 0x20 -- cgit v1.2.3