]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: ssl: remove utility functions for bundle
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 16 Sep 2020 14:17:51 +0000 (16:17 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Wed, 16 Sep 2020 14:28:26 +0000 (16:28 +0200)
Remove the last utility functions for handling the multi-cert bundles
and remove the multi-variable from the ckch structure.

With this patch, the bundles are completely removed.

include/haproxy/ssl_ckch-t.h
include/haproxy/ssl_ckch.h
src/ssl_sock.c

index 1901060c3f817cbd6a0a8fe5aadfb06b3a3b347f..9cb0dc486f4c2630cc8adaea5793af2ce9fd27a7 100644 (file)
@@ -65,7 +65,6 @@ struct cert_key_and_chain {
  */
 struct ckch_store {
        struct cert_key_and_chain *ckch;
-       unsigned int multi:1;  /* is it a multi-cert bundle ? */
        struct list ckch_inst; /* list of ckch_inst which uses this ckch_node */
        struct list crtlist_entry; /* list of entries which use this store */
        struct ebmb_node node;
index b41ce8ac1efab8f303b3846f2a6bdb46581e2b57..f8184b62ad64f9804efe866f7d442c6741186ff9 100644 (file)
@@ -55,9 +55,6 @@ void ckch_store_free(struct ckch_store *store);
 /* ckch_inst functions */
 void ckch_inst_free(struct ckch_inst *inst);
 struct ckch_inst *ckch_inst_new();
-int ckch_inst_new_load_multi_store(const char *path, struct ckch_store *ckchs,
-                                   struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
-                                   char **sni_filter, int fcount, struct ckch_inst **ckchi, char **err);
 int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct bind_conf *bind_conf,
                              struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount, struct ckch_inst **ckchi, char **err);
 
index f3b1b0e87ecd66f8f9852361bac034e9a4dcc198..03580ddc3cc3b04e57174ff6854a1db8b91fc3c7 100644 (file)
@@ -3155,309 +3155,6 @@ static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_an
        return errcode;
 }
 
-#if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL
-
-static int ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
-{
-       struct sni_keytype *s_kt = NULL;
-       struct ebmb_node *node;
-       int i;
-
-       for (i = 0; i < trash.size; i++) {
-               if (!str[i])
-                       break;
-               trash.area[i] = tolower((unsigned char)str[i]);
-       }
-       trash.area[i] = 0;
-       node = ebst_lookup(sni_keytypes, trash.area);
-       if (!node) {
-               /* CN not found in tree */
-               s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
-               /* Using memcpy here instead of strncpy.
-                * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
-                * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
-                */
-               if (!s_kt)
-                       return -1;
-
-               memcpy(s_kt->name.key, trash.area, i+1);
-               s_kt->keytypes = 0;
-               ebst_insert(sni_keytypes, &s_kt->name);
-       } else {
-               /* CN found in tree */
-               s_kt = container_of(node, struct sni_keytype, name);
-       }
-
-       /* Mark that this CN has the keytype of key_index via keytypes mask */
-       s_kt->keytypes |= 1<<key_index;
-
-       return 0;
-
-}
-
-#endif
-
-#if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL
-
-/*
- * Take a ckch_store which contains a multi-certificate bundle.
- * Group these certificates into a set of SSL_CTX*
- * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
- *
- * This will allow the user to explicitly group multiple cert/keys for a single purpose
- *
- * Returns a bitfield containing the flags:
- *     ERR_FATAL in any fatal error case
- *     ERR_ALERT if the reason of the error is available in err
- *     ERR_WARN if a warning is available into err
- *
- */
-int ckch_inst_new_load_multi_store(const char *path, struct ckch_store *ckchs,
-                                   struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
-                                   char **sni_filter, int fcount, struct ckch_inst **ckchi, char **err)
-{
-       int i = 0, n = 0;
-       struct cert_key_and_chain *certs_and_keys;
-       struct eb_root sni_keytypes_map = EB_ROOT;
-       struct ebmb_node *node;
-       struct ebmb_node *next;
-       /* Array of SSL_CTX pointers corresponding to each possible combo
-        * of keytypes
-        */
-       struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
-       int errcode = 0;
-       X509_NAME *xname = NULL;
-       char *str = NULL;
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-       STACK_OF(GENERAL_NAME) *names = NULL;
-#endif
-       struct ckch_inst *ckch_inst;
-
-       *ckchi = NULL;
-
-       if (!ckchs || !ckchs->ckch || !ckchs->multi) {
-               memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
-                         err && *err ? *err : "", path);
-               return ERR_ALERT | ERR_FATAL;
-       }
-
-       ckch_inst = ckch_inst_new();
-       if (!ckch_inst) {
-               memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
-                         err && *err ? *err : "", path);
-               errcode |= ERR_ALERT | ERR_FATAL;
-               goto end;
-       }
-
-       certs_and_keys = ckchs->ckch;
-
-       /* Process each ckch and update keytypes for each CN/SAN
-        * for example, if CN/SAN www.a.com is associated with
-        * certs with keytype 0 and 2, then at the end of the loop,
-        * www.a.com will have:
-        *     keyindex = 0 | 1 | 4 = 5
-        */
-       for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
-               int ret;
-
-               if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
-                       continue;
-
-               if (fcount) {
-                       for (i = 0; i < fcount; i++) {
-                               ret = ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
-                               if (ret < 0) {
-                                       memprintf(err, "%sunable to allocate SSL context.\n",
-                                                 err && *err ? *err : "");
-                                       errcode |= ERR_ALERT | ERR_FATAL;
-                                       goto end;
-                               }
-                       }
-               } else {
-                       /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
-                        * so the line that contains logic is marked via comments
-                        */
-                       xname = X509_get_subject_name(certs_and_keys[n].cert);
-                       i = -1;
-                       while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
-                               X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
-                               ASN1_STRING *value;
-                               value = X509_NAME_ENTRY_get_data(entry);
-                               if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
-                                       /* Important line is here */
-                                       ret = ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
-
-                                       OPENSSL_free(str);
-                                       str = NULL;
-                                       if (ret < 0) {
-                                               memprintf(err, "%sunable to allocate SSL context.\n",
-                                                         err && *err ? *err : "");
-                                               errcode |= ERR_ALERT | ERR_FATAL;
-                                               goto end;
-                                       }
-                               }
-                       }
-
-                       /* Do the above logic for each SAN */
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-                       names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
-                       if (names) {
-                               for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
-                                       GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
-
-                                       if (name->type == GEN_DNS) {
-                                               if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
-                                                       /* Important line is here */
-                                                       ret = ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
-
-                                                       OPENSSL_free(str);
-                                                       str = NULL;
-                                                       if (ret < 0) {
-                                                               memprintf(err, "%sunable to allocate SSL context.\n",
-                                                                         err && *err ? *err : "");
-                                                               errcode |= ERR_ALERT | ERR_FATAL;
-                                                               goto end;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
-       }
-
-       /* If no files found, return error */
-       if (eb_is_empty(&sni_keytypes_map)) {
-               memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
-                         err && *err ? *err : "", path);
-               errcode |= ERR_ALERT | ERR_FATAL;
-               goto end;
-       }
-
-       /* We now have a map of CN/SAN to keytypes that are loaded in
-        * Iterate through the map to create the SSL_CTX's (if needed)
-        * and add each CTX to the SNI tree
-        *
-        * Some math here:
-        *   There are 2^n - 1 possible combinations, each unique
-        *   combination is denoted by the key in the map. Each key
-        *   has a value between 1 and 2^n - 1. Conveniently, the array
-        *   of SSL_CTX* is sized 2^n. So, we can simply use the i'th
-        *   entry in the array to correspond to the unique combo (key)
-        *   associated with i. This unique key combo (i) will be associated
-        *   with combos[i-1]
-        */
-
-       node = ebmb_first(&sni_keytypes_map);
-       while (node) {
-               SSL_CTX *cur_ctx;
-               char cur_file[MAXPATHLEN+1];
-               const struct pkey_info kinfo = { .sig = TLSEXT_signature_anonymous, .bits = 0 };
-
-               str = (char *)container_of(node, struct sni_keytype, name)->name.key;
-               i = container_of(node, struct sni_keytype, name)->keytypes;
-               cur_ctx = key_combos[i-1].ctx;
-
-               if (cur_ctx == NULL) {
-                       /* need to create SSL_CTX */
-                       cur_ctx = SSL_CTX_new(SSLv23_server_method());
-                       if (cur_ctx == NULL) {
-                               memprintf(err, "%sunable to allocate SSL context.\n",
-                                         err && *err ? *err : "");
-                               errcode |= ERR_ALERT | ERR_FATAL;
-                               goto end;
-                       }
-
-                       /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
-                       for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
-                               if (i & (1<<n)) {
-                                       /* Key combo contains ckch[n] */
-                                       snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
-                                       errcode |= ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err);
-                                       if (errcode & ERR_CODE)
-                                               goto end;
-                               }
-                       }
-
-                       /* Update key_combos */
-                       key_combos[i-1].ctx = cur_ctx;
-               }
-
-               /* Update SNI Tree */
-
-               key_combos[i-1].order = ckch_inst_add_cert_sni(cur_ctx, ckch_inst, bind_conf, ssl_conf,
-                                                             kinfo, str, key_combos[i-1].order);
-               if (key_combos[i-1].order < 0) {
-                       memprintf(err, "%sunable to create a sni context.\n", err && *err ? *err : "");
-                       errcode |= ERR_ALERT | ERR_FATAL;
-                       goto end;
-               }
-               node = ebmb_next(node);
-       }
-
-
-       /* Mark a default context if none exists, using the ctx that has the most shared keys */
-       if (!bind_conf->default_ctx) {
-               for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
-                       if (key_combos[i].ctx) {
-                               bind_conf->default_ctx = key_combos[i].ctx;
-                               bind_conf->default_ssl_conf = ssl_conf;
-                               ckch_inst->is_default = 1;
-                               SSL_CTX_up_ref(bind_conf->default_ctx);
-                               break;
-                       }
-               }
-       }
-
-       ckch_inst->bind_conf = bind_conf;
-       ckch_inst->ssl_conf = ssl_conf;
-       ckch_inst->ckch_store = ckchs;
-
-end:
-
-       if (names)
-               sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
-
-       node = ebmb_first(&sni_keytypes_map);
-       while (node) {
-               next = ebmb_next(node);
-               ebmb_delete(node);
-               free(ebmb_entry(node, struct sni_keytype, name));
-               node = next;
-       }
-
-       /* we need to free the ctx since we incremented the refcount where it's used */
-       for (i = 0; i < SSL_SOCK_POSSIBLE_KT_COMBOS; i++) {
-               if (key_combos[i].ctx)
-                       SSL_CTX_free(key_combos[i].ctx);
-       }
-
-       if (errcode & ERR_CODE && ckch_inst) {
-               if (ckch_inst->is_default) {
-                       SSL_CTX_free(bind_conf->default_ctx);
-                       bind_conf->default_ctx = NULL;
-               }
-
-               ckch_inst_free(ckch_inst);
-               ckch_inst = NULL;
-       }
-
-       *ckchi = ckch_inst;
-       return errcode;
-}
-#else
-/* This is a dummy, that just logs an error and returns error */
-int ckch_inst_new_load_multi_store(const char *path, struct ckch_store *ckchs,
-                                   struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
-                                   char **sni_filter, int fcount, struct ckch_inst **ckchi, char **err)
-{
-       memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
-                 err && *err ? *err : "", path, strerror(errno));
-       return ERR_ALERT | ERR_FATAL;
-}
-
-#endif /* #if HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
-
 /*
  * This function allocate a ckch_inst and create its snis
  *
@@ -3627,10 +3324,7 @@ static int ssl_sock_load_ckchs(const char *path, struct ckch_store *ckchs,
        int errcode = 0;
 
        /* we found the ckchs in the tree, we can use it directly */
-       if (ckchs->multi)
-               errcode |= ckch_inst_new_load_multi_store(path, ckchs, bind_conf, ssl_conf, sni_filter, fcount, ckch_inst, err);
-       else
-               errcode |= ckch_inst_new_load_store(path, ckchs, bind_conf, ssl_conf, sni_filter, fcount, ckch_inst, err);
+       errcode |= ckch_inst_new_load_store(path, ckchs, bind_conf, ssl_conf, sni_filter, fcount, ckch_inst, err);
 
        if (errcode & ERR_CODE)
                return errcode;