]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: extract full pkey info in load_certificate
authorEmmanuel Hocdet <manu@gandi.net>
Fri, 27 Oct 2017 16:43:29 +0000 (18:43 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 1 Mar 2018 10:33:18 +0000 (11:33 +0100)
Private key information is used in switchctx to implement native multicert
selection (ecdsa/rsa/anonymous). This patch extract and store full pkey
information: dsa type and pkey size in bits. This can be used for switchctx
or to report pkey informations in ppv2 and log.

include/types/ssl_sock.h
src/ssl_sock.c

index c31a4969882794b92c0f6c1062fcad9ff5cc70cd..8a5b3eeb898e3365cd59f72e51d07669e814b563 100644 (file)
 
 #include <common/hathreads.h>
 
+struct pkey_info {
+       uint8_t sig;          /* TLSEXT_signature_[rsa,ecdsa,...] */
+       uint16_t bits;        /* key size in bits */
+};
+
 struct sni_ctx {
        SSL_CTX *ctx;             /* context associated to the certificate */
        int order;                /* load order for the certificate */
        uint8_t neg;              /* reject if match */
-       uint8_t key_sig;          /* TLSEXT_signature_[rsa,ecdsa,...] */
+       struct pkey_info kinfo;   /* pkey info */
        struct ssl_bind_conf *conf; /* ssl "bind" conf for the certificate */
        struct ebmb_node name;    /* node holding the servername value */
 };
index fc1ead17647d6fca41b53d47cfa39cd3ec6fc908..1f52f18682eb82b32b1f853350347fabff27cb1a 100644 (file)
@@ -2226,7 +2226,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
        /* lookup a not neg filter */
        for (n = node; n; n = ebmb_next_dup(n)) {
                if (!container_of(n, struct sni_ctx, name)->neg) {
-                       switch(container_of(n, struct sni_ctx, name)->key_sig) {
+                       switch(container_of(n, struct sni_ctx, name)->kinfo.sig) {
                        case TLSEXT_signature_ecdsa:
                                if (has_ecdsa) {
                                        node_ecdsa = n;
@@ -2240,7 +2240,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                                                goto find_one;
                                }
                                break;
-                       default: /* TLSEXT_signature_anonymous */
+                       default: /* TLSEXT_signature_anonymous|dsa */
                                if (!node_anonymous)
                                        node_anonymous = n;
                                break;
@@ -2252,7 +2252,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                node = ebst_lookup(&s->sni_w_ctx, wildp);
                for (n = node; n; n = ebmb_next_dup(n)) {
                        if (!container_of(n, struct sni_ctx, name)->neg) {
-                               switch(container_of(n, struct sni_ctx, name)->key_sig) {
+                               switch(container_of(n, struct sni_ctx, name)->kinfo.sig) {
                                case TLSEXT_signature_ecdsa:
                                        if (has_ecdsa) {
                                                node_ecdsa = n;
@@ -2266,7 +2266,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                                                        goto find_one;
                                        }
                                        break;
-                               default: /* TLSEXT_signature_anonymous */
+                               default: /* TLSEXT_signature_anonymous|dsa */
                                        if (!node_anonymous)
                                                node_anonymous = n;
                                        break;
@@ -2659,7 +2659,7 @@ end:
 #endif
 
 static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
-                                uint8_t key_sig, char *name, int order)
+                                struct pkey_info kinfo, char *name, int order)
 {
        struct sni_ctx *sc;
        int wild = 0, neg = 0;
@@ -2692,8 +2692,7 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_b
                        node = ebst_lookup(&s->sni_ctx, trash.str);
                for (; node; node = ebmb_next_dup(node)) {
                        sc = ebmb_entry(node, struct sni_ctx, name);
-                       if (sc->ctx == ctx && sc->conf == conf &&
-                           sc->key_sig == key_sig && sc->neg == neg)
+                       if (sc->ctx == ctx && sc->conf == conf && sc->neg == neg)
                                return order;
                }
 
@@ -2703,7 +2702,7 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_b
                memcpy(sc->name.key, trash.str, len + 1);
                sc->ctx = ctx;
                sc->conf = conf;
-               sc->key_sig = key_sig;
+               sc->kinfo = kinfo;
                sc->order = order++;
                sc->neg = neg;
                if (wild)
@@ -3073,6 +3072,7 @@ static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_con
        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;
@@ -3136,7 +3136,7 @@ static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_con
 
                /* Update SNI Tree */
                key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
-                                                             TLSEXT_signature_anonymous, str, key_combos[i-1].order);
+                                                             kinfo, str, key_combos[i-1].order);
                node = ebmb_next(node);
        }
 
@@ -3197,7 +3197,7 @@ static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct
        pem_password_cb *passwd_cb;
        void *passwd_cb_userdata;
        EVP_PKEY *pkey;
-       uint8_t key_sig = TLSEXT_signature_anonymous;
+       struct pkey_info kinfo = { .sig = TLSEXT_signature_anonymous, .bits = 0 };
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
        STACK_OF(GENERAL_NAME) *names;
@@ -3220,12 +3220,16 @@ static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct
 
        pkey = X509_get_pubkey(x);
        if (pkey) {
+               kinfo.bits = EVP_PKEY_bits(pkey);
                switch(EVP_PKEY_base_id(pkey)) {
                case EVP_PKEY_RSA:
-                       key_sig = TLSEXT_signature_rsa;
+                       kinfo.sig = TLSEXT_signature_rsa;
                        break;
                case EVP_PKEY_EC:
-                       key_sig = TLSEXT_signature_ecdsa;
+                       kinfo.sig = TLSEXT_signature_ecdsa;
+                       break;
+               case EVP_PKEY_DSA:
+                       kinfo.sig = TLSEXT_signature_dsa;
                        break;
                }
                EVP_PKEY_free(pkey);
@@ -3233,7 +3237,7 @@ static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct
 
        if (fcount) {
                while (fcount--)
-                       order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
+                       order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, kinfo, sni_filter[fcount], order);
        }
        else {
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -3243,7 +3247,7 @@ static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct
                                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) {
-                                               order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
+                                               order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, kinfo, str, order);
                                                OPENSSL_free(str);
                                        }
                                }
@@ -3259,7 +3263,7 @@ static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct
 
                        value = X509_NAME_ENTRY_get_data(entry);
                        if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
-                               order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
+                               order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, kinfo, str, order);
                                OPENSSL_free(str);
                        }
                }