From 92c67507e7b9b94341b3453b01a124f642aa68fb Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Wed, 18 May 2022 00:03:41 +0200 Subject: Simplify tls code by removing all unused functions to allow for more generic helpers that can be used across lib wrappers --- vchat-client.c | 6 +- vchat-commands.c | 4 +- vchat-connection.c | 28 ++--- vchat-tls.c | 308 ++++++++++++++++++----------------------------------- vchat-tls.h | 21 +++- vchat.h | 6 +- 6 files changed, 139 insertions(+), 234 deletions(-) diff --git a/vchat-client.c b/vchat-client.c index 39b42d9..65cc335 100755 --- a/vchat-client.c +++ b/vchat-client.c @@ -440,8 +440,8 @@ void versions() { puts (vchat_io_version); puts (vchat_us_version); puts (vchat_cm_version); - puts (vchat_ssl_version); - puts (vchat_ssl_version_external); + puts (vchat_tls_version); + puts (vchat_tls_version_external); } /* main - d'oh */ @@ -457,7 +457,7 @@ main (int argc, char **argv) loadconfig (getstroption (CF_CONFIGFILE)); /* make SSL version used visible */ - vchat_ssl_get_version_external(); + vchat_tls_get_version_external(); /* parse commandline */ while (cmdsunparsed) { diff --git a/vchat-commands.c b/vchat-commands.c index 1b69a94..8094a7c 100755 --- a/vchat-commands.c +++ b/vchat-commands.c @@ -456,8 +456,8 @@ command_version(char *tail) writeout (vchat_io_version); writeout (vchat_us_version); writeout (vchat_cm_version); - writeout (vchat_ssl_version); - writeout (vchat_ssl_version_external); + writeout (vchat_tls_version); + writeout (vchat_tls_version_external); showout(); } diff --git a/vchat-connection.c b/vchat-connection.c index 60dc81f..c0648c8 100644 --- a/vchat-connection.c +++ b/vchat-connection.c @@ -84,7 +84,7 @@ int vc_connect (const char *server, const char *port) { /* vchat connection x509 store */ - vc_x509store_t *vc_store; + vc_x509store_t vc_store; /* pointer to tilde-expanded certificate/keyfile-names */ char *certfile, *cafile; @@ -102,12 +102,7 @@ vc_connect (const char *server, const char *port) return 0; /* If SSL is requested, get our ssl-BIO running */ - vc_store = vc_init_x509store(); - if( !vc_store ) { - snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "Out of memory" ); - writechan (tmpstr); - return -1; - } + vc_init_x509store(&vc_store); /* get name of certificate file */ certfile = get_tilde_expanded (CF_CERTFILE); @@ -116,30 +111,25 @@ vc_connect (const char *server, const char *port) /* get name of key file */ char *keyfile = get_tilde_expanded (CF_KEYFILE); - vc_x509store_setflags(vc_store, VC_X509S_USE_CERTIFICATE); - vc_x509store_setcertfile(vc_store, certfile); + vc_x509store_setcertfile(&vc_store, certfile); + vc_x509store_set_pkeycb(&vc_store, (vc_askpass_cb_t)passprompt); - vc_x509store_set_pkeycb(vc_store, (vc_askpass_cb_t)passprompt); /* if we don't have a key file, the key may be in the cert file */ - vc_x509store_setkeyfile(vc_store, keyfile ? keyfile : certfile); + vc_x509store_setkeyfile(&vc_store, keyfile ? keyfile : certfile); free(keyfile); free(certfile); } - vc_x509store_setflags(vc_store, VC_X509S_SSL_VERIFY_PEER); - /* get name of ca file */ cafile = get_tilde_expanded (CF_CAFILE); - if (cafile && !access(cafile, F_OK)) { - vc_x509store_setflags(vc_store, VC_X509S_NODEF_CAFILE); - vc_x509store_setcafile(vc_store, cafile); - } + if (cafile && !access(cafile, F_OK)) + vc_x509store_setcafile(&vc_store, cafile); free(cafile); /* upgrade our plain BIO to ssl */ - int result = vc_tls_connect( serverfd, vc_store ); - vc_cleanup_x509store(vc_store); + int result = vc_tls_connect( serverfd, &vc_store ); + vc_cleanup_x509store(&vc_store); if (result) { close(serverfd); diff --git a/vchat-tls.c b/vchat-tls.c index 4131a23..205f0e0 100755 --- a/vchat-tls.c +++ b/vchat-tls.c @@ -20,6 +20,62 @@ #include #include +#include + +#include "vchat.h" +#include "vchat-tls.h" + +const char *vchat_tls_version = "vchat-tls.c $Id$"; +const char *vchat_tls_version_external = "Unknown implementation; version unknown"; + +void vc_cleanup_x509store(vc_x509store_t *store) +{ + free(store->cafile); + free(store->capath); + free(store->crlfile); + free(store->certfile); + free(store->keyfile); + memset(store, 0, sizeof(vc_x509store_t)); +} + +void vc_x509store_setflags(vc_x509store_t *store, int flags) { store->flags |= flags; } +void vc_x509store_clearflags(vc_x509store_t *store, int flags) { store->flags &= ~flags; } +void vc_x509store_set_pkeycb(vc_x509store_t *store, vc_askpass_cb_t callback) { store->askpass_callback = callback; } + +void vc_x509store_setcafile(vc_x509store_t *store, char *file) +{ + free(store->cafile); + store->cafile = ( file ? strdup(file) : 0 ); + store->flags |= VC_X509S_USE_CAFILE; +} + +void vc_x509store_setcapath(vc_x509store_t *store, char *path) +{ + free(store->capath); + store->capath = ( path ? strdup(path) : 0 ); +} + +void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) +{ + free(store->crlfile); + store->crlfile = ( file ? strdup(file) : 0 ); +} + +void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) +{ + free(store->keyfile); + store->keyfile = ( file ? strdup(file) : 0 ); +} + +void vc_x509store_setcertfile(vc_x509store_t *store, char *file) +{ + free(store->certfile); + store->certfile = ( file ? strdup(file) : 0 ); + store->flags |= VC_X509S_USE_CERTIFICATE; +} + +//// OPENSSL SPECIFIC + #include #include #include @@ -28,77 +84,53 @@ #include #include -#include +void vchat_tls_get_version_external() +{ + snprintf(tmpstr, sizeof(tmpstr), "OpenSSL %s with %s", SSLeay_version(SSLEAY_VERSION), SSLeay_version(SSLEAY_CFLAGS)); + vchat_tls_version_external = strdup(tmpstr); +} -#include "vchat.h" -#include "vchat-tls.h" +/* Helpers to work with vc_x509store_t used by all tls libs */ +void vc_init_x509store(vc_x509store_t *store) +{ + static int sslinit; + if (!sslinit++) { + SSL_library_init (); + SSL_load_error_strings(); + } + memset(store, 0, sizeof(vc_x509store_t)); -const char *vchat_ssl_version = "vchat-tlsl.c $Id$"; + /* We want to make verifying the peer the default */ + store->flags |= VC_X509S_SSL_VERIFY_PEER; +} /* connection BIO for openssl */ static BIO *server_conn = NULL; -typedef int (*vc_x509verify_cb_t)(int, X509_STORE_CTX *); -struct vc_x509store_t { - char *cafile; - char *capath; - char *crlfile; - vc_x509verify_cb_t callback; - vc_askpass_cb_t askpass_callback; - STACK_OF(X509) *certs; - STACK_OF(X509_CRL) *crls; - char *use_certfile; - STACK_OF(X509) *use_certs; - char *use_keyfile; - EVP_PKEY *use_key; - int flags; -}; - static SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ); static int vc_verify_callback(int, X509_STORE_CTX *); static X509_STORE * vc_x509store_create(vc_x509store_t *); -static void vc_x509store_clearflags(vc_x509store_t *, int); -static void vc_x509store_setcapath(vc_x509store_t *, char *); -static void vc_x509store_setcrlfile(vc_x509store_t *, char *); -static void vc_x509store_addcert(vc_x509store_t *, X509 *); -static void vc_x509store_setcb(vc_x509store_t *, vc_x509verify_cb_t); - -#define VC_CTX_ERR_EXIT(se, cx) do { \ - snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", \ - ERR_error_string (ERR_get_error (), NULL)); \ - writecf(FS_ERR, tmpstr); \ - if(se) X509_STORE_free(se); \ - if(cx) SSL_CTX_free(cx); \ - return(0); \ - } while(0) - -#define VC_SETCERT_ERR_EXIT(se, cx, err) do { \ - snprintf(tmpstr, TMPSTRSIZE, "CREATE CTX: %s", err); \ - writecf(FS_ERR, tmpstr); \ - if(se) X509_STORE_free(se); \ - if(cx) SSL_CTX_free(cx); \ - return(NULL); \ - } while(0) static SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ) { - int i = 0; - int n = 0; - int flags = 0; - int r = 0; - SSL_CTX *ctx = NULL; - X509_STORE *store = NULL; - vc_x509verify_cb_t verify_callback = NULL; + int flags = 0; /* Explicitly use TLSv1 (or maybe later) */ - if( !(ctx = SSL_CTX_new(TLS_client_method())) ) - VC_CTX_ERR_EXIT(store, ctx); + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + X509_STORE *store = vc_x509store_create(vc_store); - if( !(store = vc_x509store_create(vc_store)) ) - VC_CTX_ERR_EXIT(store, ctx); + if (!ctx || !store) { + snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: %s",ERR_error_string (ERR_get_error (), NULL)); + writecf(FS_ERR, tmpstr); + if (store) + X509_STORE_free(store); + if (ctx) + SSL_CTX_free(ctx); + return NULL; + } SSL_CTX_set_cert_store(ctx, store); - store = NULL; + /* Disable some insecure protocols explicitly */ SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); if (getstroption(CF_CIPHERSUITE)) @@ -108,14 +140,10 @@ static SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ) SSL_CTX_set_verify_depth (ctx, getintoption(CF_VERIFYSSL)); - if( !(verify_callback = vc_store->callback) ) - verify_callback = vc_verify_callback; - if( !(vc_store->flags & VC_X509S_SSL_VERIFY_MASK) ) { writecf(FS_DBG, tmpstr); flags = SSL_VERIFY_NONE; - } - else { + } else { if(vc_store->flags & VC_X509S_SSL_VERIFY_PEER) flags |= SSL_VERIFY_PEER; if(vc_store->flags & VC_X509S_SSL_VERIFY_FAIL_IF_NO_PEER_CERT) @@ -124,29 +152,25 @@ static SSL_CTX * vc_create_sslctx( vc_x509store_t *vc_store ) flags |= SSL_VERIFY_CLIENT_ONCE; } - SSL_CTX_set_verify(ctx, flags, verify_callback); + SSL_CTX_set_verify(ctx, flags, vc_verify_callback); if(vc_store->flags & VC_X509S_USE_CERTIFICATE) { - if(vc_store->use_certfile) - SSL_CTX_use_certificate_chain_file(ctx, vc_store->use_certfile); - else { - SSL_CTX_use_certificate(ctx, - sk_X509_value(vc_store->use_certs, 0)); - for(i=0,n=sk_X509_num(vc_store->use_certs); iuse_certs, i)); - } + int r = 0; + if(vc_store->certfile) + SSL_CTX_use_certificate_chain_file(ctx, vc_store->certfile); SSL_CTX_set_default_passwd_cb(ctx, vc_store->askpass_callback); - if(vc_store->use_keyfile) { - r=SSL_CTX_use_PrivateKey_file(ctx, vc_store->use_keyfile, + if(vc_store->keyfile) + r=SSL_CTX_use_PrivateKey_file(ctx, vc_store->keyfile, SSL_FILETYPE_PEM); - } else if(vc_store->use_key) - r=SSL_CTX_use_PrivateKey(ctx, vc_store->use_key); - if( r!=1 || !SSL_CTX_check_private_key(ctx)) - VC_SETCERT_ERR_EXIT(store, ctx, "Load private key failed"); + if( r!=1 || !SSL_CTX_check_private_key(ctx)) { + snprintf(tmpstr, sizeof(tmpstr), "CREATE CTX: Load private key failed"); + writecf(FS_ERR, tmpstr); + SSL_CTX_free(ctx); + return NULL; + } } SSL_CTX_set_app_data(ctx, vc_store); @@ -298,29 +322,24 @@ all_errors: X509_STORE *vc_x509store_create(vc_x509store_t *vc_store) { - int i = 0; - int n = 0; X509_STORE *store = NULL; X509_LOOKUP *lookup = NULL; store = X509_STORE_new(); - if(vc_store->callback) - X509_STORE_set_verify_cb_func(store, vc_store->callback); - else - X509_STORE_set_verify_cb_func(store, vc_verify_callback); + X509_STORE_set_verify_cb_func(store, vc_verify_callback); if( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) ) VC_STORE_ERR_EXIT(store); - if(!vc_store->cafile) { - if( !(vc_store->flags & VC_X509S_NODEF_CAFILE) ) + if (!vc_store->cafile) { + if( !(vc_store->flags & VC_X509S_USE_CAFILE) ) X509_LOOKUP_load_file(lookup, 0, X509_FILETYPE_DEFAULT); } else if( !X509_LOOKUP_load_file(lookup, vc_store->cafile, X509_FILETYPE_PEM) ) VC_STORE_ERR_EXIT(store); - if(vc_store->crlfile) { + if (vc_store->crlfile) { if( !X509_load_crl_file(lookup, vc_store->crlfile, X509_FILETYPE_PEM) ) VC_STORE_ERR_EXIT(store); @@ -329,25 +348,16 @@ X509_STORE *vc_x509store_create(vc_x509store_t *vc_store) X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL ); } - if( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir())) ) + if ( !(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir())) ) VC_STORE_ERR_EXIT(store); - if( !vc_store->capath ) { - if( !(vc_store->flags & VC_X509S_NODEF_CAPATH) ) + if ( !vc_store->capath ) { + if( !(vc_store->flags & VC_X509S_USE_CAPATH) ) X509_LOOKUP_add_dir(lookup, 0, X509_FILETYPE_DEFAULT); } else if( !X509_LOOKUP_add_dir(lookup, vc_store->capath, X509_FILETYPE_PEM) ) VC_STORE_ERR_EXIT(store); - for( i=0, n=sk_X509_num(vc_store->certs); icerts, i)) ) - VC_STORE_ERR_EXIT(store); - - for( i=0, n=sk_X509_CRL_num(vc_store->crls); icrls, i)) ) - VC_STORE_ERR_EXIT(store); - return(store); } @@ -361,104 +371,6 @@ int vc_verify_callback(int ok, X509_STORE_CTX *store) return (ok | getintoption(CF_IGNSSL)); } -void vc_x509store_setflags(vc_x509store_t *store, int flags) -{ - store->flags |= flags; -} - -void vc_x509store_clearflags(vc_x509store_t *store, int flags) -{ - store->flags &= ~flags; -} - -void vc_x509store_setcb(vc_x509store_t *store, - vc_x509verify_cb_t callback) -{ - store->callback = callback; -} - -void vc_x509store_set_pkeycb(vc_x509store_t *store, - vc_askpass_cb_t callback) -{ - store->askpass_callback = callback; -} - -void vc_x509store_addcert(vc_x509store_t *store, X509 *cert) -{ - sk_X509_push(store->certs, cert); -} - -void vc_x509store_setcafile(vc_x509store_t *store, char *file) -{ - free(store->cafile); - store->cafile = ( file ? strdup(file) : 0 ); -} - -void vc_x509store_setcapath(vc_x509store_t *store, char *path) -{ - free(store->capath); - store->capath = ( path ? strdup(path) : 0 ); -} - -void vc_x509store_setcrlfile(vc_x509store_t *store, char *file) -{ - free(store->crlfile); - store->crlfile = ( file ? strdup(file) : 0 ); -} - -void vc_x509store_setkeyfile(vc_x509store_t *store, char *file) -{ - free(store->use_keyfile); - store->use_keyfile = ( file ? strdup(file) : 0 ); -} - -void vc_x509store_setcertfile(vc_x509store_t *store, char *file) -{ - free(store->use_certfile); - store->use_certfile = ( file ? strdup(file) : 0 ); -} - -vc_x509store_t *vc_init_x509store() -{ - vc_x509store_t *s = malloc(sizeof(vc_x509store_t)); - if (s) { - - static int sslinit; - if( !sslinit++ ) { - SSL_library_init (); - SSL_load_error_strings(); - } - - s->cafile = NULL; - s->capath = NULL; - s->crlfile = NULL; - s->callback = NULL; - s->askpass_callback = NULL; - s->certs = sk_X509_new_null(); - s->crls = sk_X509_CRL_new_null(); - s->use_certfile = NULL; - s->use_certs = sk_X509_new_null(); - s->use_keyfile = NULL; - s->use_key = NULL; - s->flags = 0; - } - return s; -} - -void vc_cleanup_x509store(vc_x509store_t *s) -{ - 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_CRL_free(s->crls); - sk_X509_free(s->use_certs); - free(s); -} - ssize_t vc_tls_sendmessage(const void *buf, size_t size) { return BIO_write(server_conn, buf, size); } @@ -476,11 +388,3 @@ void vc_tls_cleanup() { BIO_free_all( server_conn ); server_conn = NULL; } - -const char *vchat_ssl_version_external = "OpenSSL implementation; version unknown"; -void vchat_ssl_get_version_external() -{ - char tmpstr[TMPSTRSIZE]; - snprintf(tmpstr, TMPSTRSIZE, "%s with %s", SSLeay_version(SSLEAY_VERSION), SSLeay_version(SSLEAY_CFLAGS)); - vchat_ssl_version_external = strdup(tmpstr); -} diff --git a/vchat-tls.h b/vchat-tls.h index 8d33ebd..440d08e 100755 --- a/vchat-tls.h +++ b/vchat-tls.h @@ -2,16 +2,27 @@ /* prototypes */ -struct vc_x509store_t; -typedef struct vc_x509store_t vc_x509store_t; typedef int (*vc_askpass_cb_t)(char *, int, int, void *); +struct vc_x509store_t { + char *cafile; + char *capath; + char *crlfile; + vc_askpass_cb_t askpass_callback; + char *certfile; + char *keyfile; + int flags; +}; +typedef struct vc_x509store_t vc_x509store_t; -vc_x509store_t *vc_init_x509store(); +void vc_init_x509store(vc_x509store_t *); void vc_x509store_set_pkeycb(vc_x509store_t *, vc_askpass_cb_t); void vc_x509store_setflags(vc_x509store_t *, int); void vc_x509store_setkeyfile(vc_x509store_t *, char *); void vc_x509store_setcertfile(vc_x509store_t *, char *); void vc_x509store_setcafile(vc_x509store_t *, char *); +void vc_x509store_clearflags(vc_x509store_t *, int); +void vc_x509store_setcapath(vc_x509store_t *, char *); +void vc_x509store_setcrlfile(vc_x509store_t *, char *); void vc_cleanup_x509store(vc_x509store_t *s); int vc_tls_connect(int serverfd, vc_x509store_t * ); @@ -19,8 +30,8 @@ ssize_t vc_tls_sendmessage(const void *buf, size_t size); ssize_t vc_tls_receivemessage(void *buf, size_t size); void vc_tls_cleanup(); -#define VC_X509S_NODEF_CAFILE 0x01 -#define VC_X509S_NODEF_CAPATH 0x02 +#define VC_X509S_USE_CAFILE 0x01 +#define VC_X509S_USE_CAPATH 0x02 #define VC_X509S_USE_CERTIFICATE 0x04 #define VC_X509S_SSL_VERIFY_NONE 0x10 #define VC_X509S_SSL_VERIFY_PEER 0x20 diff --git a/vchat.h b/vchat.h index c6077a6..71ad149 100755 --- a/vchat.h +++ b/vchat.h @@ -167,6 +167,6 @@ typedef struct { } commandentry; /* vchat-tls.c */ -extern const char *vchat_ssl_version; -extern const char *vchat_ssl_version_external; -void vchat_ssl_get_version_external(); +extern const char *vchat_tls_version; +extern const char *vchat_tls_version_external; +void vchat_tls_get_version_external(); -- cgit v1.2.3