From 1f56e1936120d7f986ebeb4b906d5a0154ee22f2 Mon Sep 17 00:00:00 2001 From: Johannes Bauer Date: Wed, 23 Oct 2019 22:06:47 +0200 Subject: [PATCH] Consolidated session establishment for client and server Essentially, they share most of the same code. Consolidate everything into one function. --- client.c | 40 +------------------------------------ openssl.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ openssl.h | 1 + server.c | 41 +------------------------------------ 4 files changed, 63 insertions(+), 79 deletions(-) diff --git a/client.c b/client.c index 63b7fd9..12c1f00 100644 --- a/client.c +++ b/client.c @@ -225,45 +225,7 @@ static int psk_client_callback(SSL *ssl, const EVP_MD *md, const unsigned char * *id = key_client->identifier; *idlen = ASCII_UUID_CHARACTER_COUNT; - SSL_SESSION *sess = SSL_SESSION_new(); - if (!sess) { - log_openssl(LLVL_ERROR, "Failed to create SSL_SESSION context for client."); - return 0; - } - - const uint8_t tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; - const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); - if (!cipher) { - log_openssl(LLVL_ERROR, "Unable to look up SSL_CIPHER for TLSv1.3-PSK"); - return 0; - } - - int return_value = 1; - do { - if (!SSL_SESSION_set1_master_key(sess, key_client->keydb->hosts[0].tls_psk, PSK_SIZE_BYTES)) { - log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK master key."); - return_value = 0; - break; - } - - if (!SSL_SESSION_set_cipher(sess, cipher)) { - log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK cipher."); - return_value = 0; - break; - } - - if (!SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) { - log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK protocol version."); - return_value = 0; - break; - } - } while (false); - - if (return_value) { - *sessptr = sess; - } - - return return_value; + return openssl_tls13_psk_establish_session(ssl, key_client->keydb->hosts[0].tls_psk, PSK_SIZE_BYTES, EVP_sha256(), sessptr); } static bool contact_keyserver_socket(struct keyclient_t *keyclient, int sd) { diff --git a/openssl.c b/openssl.c index 7881412..0eb98e3 100644 --- a/openssl.c +++ b/openssl.c @@ -111,3 +111,63 @@ void free_generic_tls_context(struct generic_tls_ctx_t *gctx) { gctx->conf_ctx = NULL; } +enum psk_hash_t { + PSK_HASH_SHA256, + PSK_HASH_SHA384, +}; + +int openssl_tls13_psk_establish_session(SSL *ssl, const uint8_t *psk, unsigned int psk_length, const EVP_MD *cipher_md, SSL_SESSION **new_session) { + uint8_t codepoint[2]; + if (cipher_md == EVP_sha256()) { + // TLS_AES_128_GCM_SHA256 + codepoint[0] = 0x13; + codepoint[1] = 0x01; + } else if (cipher_md == EVP_sha384()) { + // TLS_AES_256_GCM_SHA384 + codepoint[0] = 0x13; + codepoint[1] = 0x02; + } else { + log_msg(LLVL_ERROR, "Unknown hash function %p (%s) passed for which we do not know how to create a SSL_CIPHER*.", cipher_md, EVP_MD_name(cipher_md)); + return 0; + } + + const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, codepoint); + if (!cipher) { + log_msg(LLVL_ERROR, "Unable to determine SSL_CIPHER* from codepoint 0x%02x 0x%02x (%s).", codepoint[0], codepoint[1], EVP_MD_name(cipher_md)); + return 0; + } + + SSL_SESSION *sess = SSL_SESSION_new(); + if (!sess) { + log_openssl(LLVL_ERROR, "Failed to create SSL_SESSION context for client."); + return 0; + } + + int return_value = 1; + do { + if (!SSL_SESSION_set1_master_key(sess, psk, psk_length)) { + log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK master key."); + return_value = 0; + break; + } + + if (!SSL_SESSION_set_cipher(sess, cipher)) { + log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK cipher."); + return_value = 0; + break; + } + + if (!SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) { + log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK protocol version."); + return_value = 0; + break; + } + } while (false); + + if (return_value) { + *new_session = sess; + } else { + SSL_SESSION_free(sess); + } + return return_value; +} diff --git a/openssl.h b/openssl.h index cd2e072..c8ce50e 100644 --- a/openssl.h +++ b/openssl.h @@ -37,6 +37,7 @@ struct generic_tls_ctx_t { bool openssl_init(void); bool create_generic_tls_context(struct generic_tls_ctx_t *gctx, bool server); void free_generic_tls_context(struct generic_tls_ctx_t *gctx); +int openssl_tls13_psk_establish_session(SSL *ssl, const uint8_t *psk, unsigned int psk_length, const EVP_MD *cipher_md, SSL_SESSION **new_session); /*************** AUTO GENERATED SECTION ENDS ***************/ #endif diff --git a/server.c b/server.c index 71ad413..21a80a6 100644 --- a/server.c +++ b/server.c @@ -286,46 +286,7 @@ static int psk_server_callback(SSL *ssl, const unsigned char *identity, size_t i return 0; } - const uint8_t tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; - const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); - if (!cipher) { - log_openssl(LLVL_ERROR, "Unable to look up SSL_CIPHER for TLSv1.3-PSK"); - return 0; - } - - SSL_SESSION *sess = SSL_SESSION_new(); - if (!sess) { - log_openssl(LLVL_ERROR, "Failed to create SSL_SESSION context for client."); - return 0; - } - - int return_value = 1; - do { - if (!SSL_SESSION_set1_master_key(sess, ctx->host->tls_psk, PSK_SIZE_BYTES)) { - log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK master key."); - return_value = 0; - break; - } - - if (!SSL_SESSION_set_cipher(sess, cipher)) { - log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK cipher."); - return_value = 0; - break; - } - - if (!SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) { - log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK protocol version."); - return_value = 0; - break; - } - } while (false); - - if (return_value) { - *sessptr = sess; - } else { - SSL_SESSION_free(sess); - } - return return_value; + return openssl_tls13_psk_establish_session(ssl, ctx->host->tls_psk, PSK_SIZE_BYTES, EVP_sha256(), sessptr); } static void client_handler_thread(void *vctx) {