Move SSL context code to get/set_ssl_context methods

- 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 <bip@animanova.fr>
This commit is contained in:
Loïc Gomez 2024-02-04 14:47:13 +09:00
parent 400b0d66de
commit f2443aaf23
Signed by: Kyoshiro
GPG Key ID: F80C2F71E89B990A
2 changed files with 84 additions and 45 deletions

View File

@ -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);

View File

@ -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