From 3777e3ad14f2ce54b6662fd0db56413dde9ec9fa Mon Sep 17 00:00:00 2001 From: Emmanuel Hocdet Date: Wed, 6 Nov 2019 16:05:34 +0100 Subject: [PATCH] BUG/MINOR: ssl: certificate choice can be unexpected with openssl >= 1.1.1 It's regression from 9f9b0c6 "BUG/MEDIUM: ECC cert should work with TLS < v1.2 and openssl >= 1.1.1". Wilcard EC certifcate could be selected at the expense of specific RSA certificate. In any case, specific certificate should always selected first, next wildcard. Reflect this rule in a loop to avoid any bug in certificate selection changes. Fix issue #394. It should be backported as far as 1.8. --- src/ssl_sock.c | 56 ++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 57e97fd2c0..5930c25a8f 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -2476,32 +2476,16 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) trash.area[i] = 0; HA_RWLOCK_RDLOCK(SNI_LOCK, &s->sni_lock); - /* lookup in full qualified names */ - node = ebst_lookup(&s->sni_ctx, trash.area); - /* 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)->kinfo.sig) { - case TLSEXT_signature_ecdsa: - if (!node_ecdsa) - node_ecdsa = n; - break; - case TLSEXT_signature_rsa: - if (!node_rsa) - node_rsa = n; - break; - default: /* TLSEXT_signature_anonymous|dsa */ - if (!node_anonymous) - node_anonymous = n; - break; - } - } - } - if (wildp) { - /* lookup in wildcards names */ - node = ebst_lookup(&s->sni_w_ctx, wildp); + for (i = 0; i < 2; i++) { + if (i == 0) /* lookup in full qualified names */ + node = ebst_lookup(&s->sni_ctx, trash.area); + else if (i == 1 && wildp) /* lookup in wildcards names */ + node = ebst_lookup(&s->sni_w_ctx, wildp); + else + break; for (n = node; n; n = ebmb_next_dup(n)) { + /* lookup a not neg filter */ if (!container_of(n, struct sni_ctx, name)->neg) { switch(container_of(n, struct sni_ctx, name)->kinfo.sig) { case TLSEXT_signature_ecdsa: @@ -2519,18 +2503,17 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) } } } - } - /* select by key_signature priority order */ - node = (has_ecdsa_sig && node_ecdsa) ? node_ecdsa - : ((has_rsa_sig && node_rsa) ? node_rsa - : (node_anonymous ? node_anonymous - : (node_ecdsa ? node_ecdsa /* no ecdsa signature case (< TLSv1.2) */ - : node_rsa /* no rsa signature case (far far away) */ - ))); - if (node) { - /* switch ctx */ - struct ssl_bind_conf *conf = container_of(node, struct sni_ctx, name)->conf; - ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx); + /* select by key_signature priority order */ + node = (has_ecdsa_sig && node_ecdsa) ? node_ecdsa + : ((has_rsa_sig && node_rsa) ? node_rsa + : (node_anonymous ? node_anonymous + : (node_ecdsa ? node_ecdsa /* no ecdsa signature case (< TLSv1.2) */ + : node_rsa /* no rsa signature case (far far away) */ + ))); + if (node) { + /* switch ctx */ + struct ssl_bind_conf *conf = container_of(node, struct sni_ctx, name)->conf; + ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx); if (conf) { methodVersions[conf->ssl_methods.min].ssl_set_version(ssl, SET_MIN); methodVersions[conf->ssl_methods.max].ssl_set_version(ssl, SET_MAX); @@ -2539,6 +2522,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg) } HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock); goto allow_early; + } } HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock); -- 2.39.5