From ddc090bc55508305f471fd394579d0787f7ada44 Mon Sep 17 00:00:00 2001 From: Emmanuel Hocdet Date: Fri, 27 Oct 2017 18:43:29 +0200 Subject: [PATCH] MINOR: ssl: extract full pkey info in load_certificate 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 | 7 ++++++- src/ssl_sock.c | 34 +++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h index c31a49698..8a5b3eeb8 100644 --- a/include/types/ssl_sock.h +++ b/include/types/ssl_sock.h @@ -27,11 +27,16 @@ #include +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 */ }; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index fc1ead176..1f52f1868 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -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); } }