]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: emulate multi-cert bundles loading in standard loading
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 16 Sep 2020 12:48:52 +0000 (14:48 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Wed, 16 Sep 2020 14:28:26 +0000 (16:28 +0200)
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

index 7e4abef1c5a636be700c36c9a039deeac6e6ddae..97f7802f5c903a75923e32d595da8c6551359b5d 100644 (file)
@@ -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));