]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: Added multi cert support for loading crt directories
authoryanbzhu <yanbzhu@cisco.com>
Wed, 9 Dec 2015 18:35:14 +0000 (13:35 -0500)
committerWilly Tarreau <w@1wt.eu>
Mon, 14 Dec 2015 10:22:29 +0000 (11:22 +0100)
Loading of multiple certs into shared contexts is now supported if a user
specifies a directory instead of a cert file.

src/ssl_sock.c

index d058e4f97a8ea96913ebe03337e2919f444cadd3..3ede226817a4ce9bd70fba9eb35369fafe33f2ab 100644 (file)
@@ -2215,6 +2215,10 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *cu
        char *end;
        char fp[MAXPATHLEN+1];
        int cfgerr = 0;
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
+       int is_bundle;
+       int j;
+#endif
 
        if (stat(path, &buf) == 0) {
                dir = opendir(path);
@@ -2248,6 +2252,45 @@ int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *cu
                                }
                                if (!S_ISREG(buf.st_mode))
                                        goto ignore_entry;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
+                               is_bundle = 0;
+                               /* Check if current entry in directory is part of a multi-cert bundle */
+
+                               if (end) {
+                                       for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
+                                               if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
+                                                       is_bundle = 1;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (is_bundle) {
+                                               char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
+                                               int dp_len;
+
+                                               dp_len = end - de->d_name;
+                                               snprintf(dp, dp_len + 1, "%s", de->d_name);
+
+                                               /* increment i and free de until we get to a non-bundle cert
+                                                * Note here that we look at de_list[i + 1] before freeing de
+                                                * this is important since ignore_entry will free de
+                                                */
+                                               while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
+                                                       free(de);
+                                                       i++;
+                                                       de = de_list[i];
+                                               }
+
+                                               snprintf(fp, sizeof(fp), "%s/%s", path, dp);
+                                               ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, err);
+
+                                               /* Successfully processed the bundle */
+                                               goto ignore_entry;
+                                       }
+                               }
+
+#endif
                                cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
 ignore_entry:
                                free(de);