mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 13:51:26 +02:00
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.
This commit is contained in:
parent
8c0c34b6e7
commit
ddc090bc55
@ -27,11 +27,16 @@
|
|||||||
|
|
||||||
#include <common/hathreads.h>
|
#include <common/hathreads.h>
|
||||||
|
|
||||||
|
struct pkey_info {
|
||||||
|
uint8_t sig; /* TLSEXT_signature_[rsa,ecdsa,...] */
|
||||||
|
uint16_t bits; /* key size in bits */
|
||||||
|
};
|
||||||
|
|
||||||
struct sni_ctx {
|
struct sni_ctx {
|
||||||
SSL_CTX *ctx; /* context associated to the certificate */
|
SSL_CTX *ctx; /* context associated to the certificate */
|
||||||
int order; /* load order for the certificate */
|
int order; /* load order for the certificate */
|
||||||
uint8_t neg; /* reject if match */
|
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 ssl_bind_conf *conf; /* ssl "bind" conf for the certificate */
|
||||||
struct ebmb_node name; /* node holding the servername value */
|
struct ebmb_node name; /* node holding the servername value */
|
||||||
};
|
};
|
||||||
|
@ -2226,7 +2226,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
|||||||
/* lookup a not neg filter */
|
/* lookup a not neg filter */
|
||||||
for (n = node; n; n = ebmb_next_dup(n)) {
|
for (n = node; n; n = ebmb_next_dup(n)) {
|
||||||
if (!container_of(n, struct sni_ctx, name)->neg) {
|
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:
|
case TLSEXT_signature_ecdsa:
|
||||||
if (has_ecdsa) {
|
if (has_ecdsa) {
|
||||||
node_ecdsa = n;
|
node_ecdsa = n;
|
||||||
@ -2240,7 +2240,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
|||||||
goto find_one;
|
goto find_one;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: /* TLSEXT_signature_anonymous */
|
default: /* TLSEXT_signature_anonymous|dsa */
|
||||||
if (!node_anonymous)
|
if (!node_anonymous)
|
||||||
node_anonymous = n;
|
node_anonymous = n;
|
||||||
break;
|
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);
|
node = ebst_lookup(&s->sni_w_ctx, wildp);
|
||||||
for (n = node; n; n = ebmb_next_dup(n)) {
|
for (n = node; n; n = ebmb_next_dup(n)) {
|
||||||
if (!container_of(n, struct sni_ctx, name)->neg) {
|
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:
|
case TLSEXT_signature_ecdsa:
|
||||||
if (has_ecdsa) {
|
if (has_ecdsa) {
|
||||||
node_ecdsa = n;
|
node_ecdsa = n;
|
||||||
@ -2266,7 +2266,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
|||||||
goto find_one;
|
goto find_one;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: /* TLSEXT_signature_anonymous */
|
default: /* TLSEXT_signature_anonymous|dsa */
|
||||||
if (!node_anonymous)
|
if (!node_anonymous)
|
||||||
node_anonymous = n;
|
node_anonymous = n;
|
||||||
break;
|
break;
|
||||||
@ -2659,7 +2659,7 @@ end:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
|
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;
|
struct sni_ctx *sc;
|
||||||
int wild = 0, neg = 0;
|
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);
|
node = ebst_lookup(&s->sni_ctx, trash.str);
|
||||||
for (; node; node = ebmb_next_dup(node)) {
|
for (; node; node = ebmb_next_dup(node)) {
|
||||||
sc = ebmb_entry(node, struct sni_ctx, name);
|
sc = ebmb_entry(node, struct sni_ctx, name);
|
||||||
if (sc->ctx == ctx && sc->conf == conf &&
|
if (sc->ctx == ctx && sc->conf == conf && sc->neg == neg)
|
||||||
sc->key_sig == key_sig && sc->neg == neg)
|
|
||||||
return order;
|
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);
|
memcpy(sc->name.key, trash.str, len + 1);
|
||||||
sc->ctx = ctx;
|
sc->ctx = ctx;
|
||||||
sc->conf = conf;
|
sc->conf = conf;
|
||||||
sc->key_sig = key_sig;
|
sc->kinfo = kinfo;
|
||||||
sc->order = order++;
|
sc->order = order++;
|
||||||
sc->neg = neg;
|
sc->neg = neg;
|
||||||
if (wild)
|
if (wild)
|
||||||
@ -3073,6 +3072,7 @@ static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_con
|
|||||||
while (node) {
|
while (node) {
|
||||||
SSL_CTX *cur_ctx;
|
SSL_CTX *cur_ctx;
|
||||||
char cur_file[MAXPATHLEN+1];
|
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;
|
str = (char *)container_of(node, struct sni_keytype, name)->name.key;
|
||||||
i = container_of(node, struct sni_keytype, name)->keytypes;
|
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 */
|
/* Update SNI Tree */
|
||||||
key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
|
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);
|
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;
|
pem_password_cb *passwd_cb;
|
||||||
void *passwd_cb_userdata;
|
void *passwd_cb_userdata;
|
||||||
EVP_PKEY *pkey;
|
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
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
STACK_OF(GENERAL_NAME) *names;
|
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);
|
pkey = X509_get_pubkey(x);
|
||||||
if (pkey) {
|
if (pkey) {
|
||||||
|
kinfo.bits = EVP_PKEY_bits(pkey);
|
||||||
switch(EVP_PKEY_base_id(pkey)) {
|
switch(EVP_PKEY_base_id(pkey)) {
|
||||||
case EVP_PKEY_RSA:
|
case EVP_PKEY_RSA:
|
||||||
key_sig = TLSEXT_signature_rsa;
|
kinfo.sig = TLSEXT_signature_rsa;
|
||||||
break;
|
break;
|
||||||
case EVP_PKEY_EC:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
EVP_PKEY_free(pkey);
|
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) {
|
if (fcount) {
|
||||||
while (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 {
|
else {
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#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);
|
GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
|
||||||
if (name->type == GEN_DNS) {
|
if (name->type == GEN_DNS) {
|
||||||
if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
|
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);
|
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);
|
value = X509_NAME_ENTRY_get_data(entry);
|
||||||
if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
|
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);
|
OPENSSL_free(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user