From: yanbzhu Date: Wed, 9 Dec 2015 18:35:14 +0000 (-0500) Subject: MEDIUM: ssl: Added multi cert support for loading crt directories X-Git-Tag: v1.7-dev1~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=63ea84639923edbca89fc4fa824541917c6b9f95;p=thirdparty%2Fhaproxy.git MEDIUM: ssl: Added multi cert support for loading crt directories Loading of multiple certs into shared contexts is now supported if a user specifies a directory instead of a cert file. --- diff --git a/src/ssl_sock.c b/src/ssl_sock.c index d058e4f97a..3ede226817 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -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);