From f2443aaf23ac5cc9659c7a9c916c869eec4d15ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Gomez?= Date: Sun, 4 Feb 2024 14:47:13 +0900 Subject: [PATCH] Move SSL context code to get/set_ssl_context methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move code setting up SSL context from accept_new() to new get/set_ssl_context() methods - set_ssl_context() will allow setting context only if not already set, or force re-setting context even if already present - set_ssl_context() will return 1 if SSL context has been set - if getting the new SSL context fails, set_ssl_context() will not break current SSL context This is preparatory work for reloading SSL certificates/key on BIP reload. Signed-off-by: Loïc Gomez --- src/connection.c | 121 +++++++++++++++++++++++++++++------------------ src/connection.h | 8 ++++ 2 files changed, 84 insertions(+), 45 deletions(-) diff --git a/src/connection.c b/src/connection.c index e7ebba9..15c32e5 100644 --- a/src/connection.c +++ b/src/connection.c @@ -34,6 +34,7 @@ extern char *conf_client_ciphers; extern char *conf_client_dh_file; static int SSLize(connection_t *cn, int *nc); static SSL_CTX *SSL_init_context(char *ciphers); +SSL_CTX *get_ssl_context(void); /* SSH like trust management */ int link_add_untrusted(void *ls, X509 *cert); #endif @@ -1231,6 +1232,77 @@ static int ctx_set_dh(SSL_CTX *ctx) conf_client_dh_file); return 1; } + +int set_ssl_context(int force) +{ + SSL_CTX *newctx = NULL; + if (sslctx) { + if (force == SSLCTX_FORCE_UPDATE) { + mylog(LOG_DEBUG, "SSL context already set, forcing update"); + } else { + mylog(LOG_DEBUG, "SSL context is already set, not updating"); + return 0; + } + } else { + mylog(LOG_DEBUG, "Initializing SSL context for accepted connections"); + } + + newctx = get_ssl_context(); + if (!newctx) { + mylog(LOG_ERROR, "Failed to get new SSL context"); + if (sslctx) + mylog(LOG_WARN, "Keeping old SSL context"); + return 0; + } + sslctx = newctx; + return 1; +} + +SSL_CTX *get_ssl_context(void) +{ + SSL_CTX *newctx = NULL; + if (!(newctx = SSL_init_context(conf_client_ciphers))) { + mylog(LOG_ERROR, "SSL context initialization failed"); + return NULL; + } + + if (!conf_client_dh_file) { + // try with a default path but don't fail if it doesn't exist + conf_client_dh_file = default_path(conf_biphome, "dh.pem", + "DH parameters"); + + struct stat st_buf; + if (stat(conf_client_dh_file, &st_buf) != 0) { + free(conf_client_dh_file); + conf_client_dh_file = NULL; + } + } + + if (conf_client_dh_file) { + if (!ctx_set_dh(newctx)) { + SSL_CTX_free(newctx); + mylog(LOG_ERROR, "SSL Unable to load DH parameters"); + return NULL; + } + } + + mylog(LOG_DEBUG, "Loading SSL cert from %s", conf_ssl_certfile); + if (!SSL_CTX_use_certificate_chain_file(newctx, conf_ssl_certfile)) { + mylog(LOG_WARN, "SSL: Unable to load certificate file"); + SSL_CTX_free(newctx); + return NULL; + } + + mylog(LOG_DEBUG, "Loading SSL key from %s", conf_ssl_certfile); + if (!SSL_CTX_use_PrivateKey_file(newctx, conf_ssl_certfile, + SSL_FILETYPE_PEM)) { + mylog(LOG_WARN, "SSL: Unable to load key file"); + SSL_CTX_free(newctx); + return NULL; + } + + return newctx; +} #endif connection_t *accept_new(connection_t *cn) @@ -1266,52 +1338,11 @@ connection_t *accept_new(connection_t *cn) conn->client = 1; #ifdef HAVE_LIBSSL if (cn->ssl) { + if (!sslctx) + set_ssl_context(SSLCTX_NO_REPLACE); if (!sslctx) { - mylog(LOG_DEBUG, - "No SSL context available for " - "accepted connections. " - "Initializing..."); - if (!(sslctx = SSL_init_context(conf_client_ciphers))) { - mylog(LOG_ERROR, - "SSL context initialization " - "failed"); - connection_free(conn); - return NULL; - } - - if (!conf_client_dh_file) { - // try with a default path but don't fail if it - // doesn't exist - conf_client_dh_file = - default_path(conf_biphome, "dh.pem", - "DH parameters"); - - struct stat st_buf; - if (stat(conf_client_dh_file, &st_buf) != 0) { - free(conf_client_dh_file); - conf_client_dh_file = NULL; - } - } - - if (conf_client_dh_file) { - if (!ctx_set_dh(sslctx)) { - mylog(LOG_ERROR, - "SSL Unable to load DH " - "parameters"); - connection_free(conn); - return NULL; - } - } - - if (!SSL_CTX_use_certificate_chain_file( - sslctx, conf_ssl_certfile)) - mylog(LOG_WARN, - "SSL: Unable to load " - "certificate file"); - if (!SSL_CTX_use_PrivateKey_file(sslctx, - conf_ssl_certfile, - SSL_FILETYPE_PEM)) - mylog(LOG_WARN, "SSL: Unable to load key file"); + connection_free(conn); + return NULL; } conn->ssl_h = SSL_new(sslctx); diff --git a/src/connection.h b/src/connection.h index 400b41e..cb6faed 100644 --- a/src/connection.h +++ b/src/connection.h @@ -60,6 +60,9 @@ #define SSL_CHECK_NONE (0) #define SSL_CHECK_BASIC (1) #define SSL_CHECK_CA (2) + +#define SSLCTX_NO_REPLACE 0 +#define SSLCTX_FORCE_UPDATE 1 #endif struct connecting_data; @@ -113,4 +116,9 @@ uint16_t connection_localport(connection_t *cn); uint16_t connection_remoteport(connection_t *cn); char *connection_localip(connection_t *cn); char *connection_remoteip(connection_t *cn); +#ifdef HAVE_LIBSSL +/* Set SSL context, force update if already set and force is 1 + * Return 1 if SSL context has been set */ +int set_ssl_context(int force); +#endif #endif