From dfa93be3b51bd398ce3d143245f41f8a91e09deb Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Wed, 16 Sep 2020 14:48:52 +0200 Subject: [PATCH] MEDIUM: ssl: emulate multi-cert bundles loading in standard loading Like the previous commit, this one emulates the bundling by loading each certificate separately and storing it in a separate SSL_CTX. This patch does it for the standard certificate loading, which means outside directories or crt-list. The multi-certificates bundle was the common way of offering multiple certificates of different types (ecdsa and rsa) for a same SSL_CTX. This was implemented with OpenSSL 1.0.2 before the client_hello callback was available. Now that all versions which does not support this callback are deprecated (< 1.1.0), we can safely removes the support for the bundle which was inconvenient and complexify too much the code. --- src/ssl_sock.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 7e4abef1c..97f7802f5 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -3784,11 +3784,29 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err) } else { /* stat failed, could be a bundle */ if (global_ssl.extra_files & SSL_GF_BUNDLE) { - /* try to load a bundle if it is permitted */ - ckchs = ckchs_load_cert_file(path, 1, err); - if (!ckchs) - return ERR_ALERT | ERR_FATAL; - cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err); + char fp[MAXPATHLEN+1] = {0}; + int n = 0; + + /* Load all possible certs and keys in separate ckch_store */ + for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) { + struct stat buf; + int ret; + + ret = snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]); + if (ret > sizeof(fp)) + continue; + + if ((ckchs = ckchs_lookup(fp))) { + cfgerr |= ssl_sock_load_ckchs(fp, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err); + } else { + if (stat(fp, &buf) == 0) { + ckchs = ckchs_load_cert_file(fp, 0, err); + if (!ckchs) + return ERR_ALERT | ERR_FATAL; + cfgerr |= ssl_sock_load_ckchs(fp, ckchs, bind_conf, NULL, NULL, 0, &ckch_inst, err); + } + } + } } else { memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n", err && *err ? *err : "", fp, strerror(errno));