mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
BUG/MEDIUM: ssl: does not look for all SNIs before chosing a certificate
In bug #810, the SNI are not matched correctly, indeed when trying to match a certificate type in ssl_sock_switchctx_cbk() all SNIs were not looked up correctly. In the case you have in a crt-list: wildcard.subdomain.domain.tld.pem.rsa *.subdomain.domain.tld record.subdomain.domain.tld record.subdomain.domain.tld.pem.ecdsa record.subdomain.domain.tld another-record.subdomain.domain.tld If the client only supports RSA and requests "another-record.subdomain.domain.tld", HAProxy will find the single ECDSA certificate and won't try to look up for a wildcard RSA certificate. This patch fixes the code so we look for all single and wildcard before chosing the certificate type. This bug was introduced by commit 3777e3a ("BUG/MINOR: ssl: certificate choice can be unexpected with openssl >= 1.1.1"). It must be backported as far as 1.8 once it is heavily tested.
This commit is contained in:
parent
7adf8f35df
commit
94bd319b26
@ -2352,6 +2352,8 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
|
|||||||
|
|
||||||
HA_RWLOCK_RDLOCK(SNI_LOCK, &s->sni_lock);
|
HA_RWLOCK_RDLOCK(SNI_LOCK, &s->sni_lock);
|
||||||
|
|
||||||
|
/* Look for an ECDSA, RSA and DSA certificate, first in the single
|
||||||
|
* name and if not found in the wildcard */
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
if (i == 0) /* lookup in full qualified names */
|
if (i == 0) /* lookup in full qualified names */
|
||||||
node = ebst_lookup(&s->sni_ctx, trash.area);
|
node = ebst_lookup(&s->sni_ctx, trash.area);
|
||||||
@ -2378,26 +2380,28 @@ 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
|
/* Once the certificates are found, select them depending on what is
|
||||||
: ((has_rsa_sig && node_rsa) ? node_rsa
|
* supported in the client and by key_signature priority order: EDSA >
|
||||||
: (node_anonymous ? node_anonymous
|
* RSA > DSA */
|
||||||
: (node_ecdsa ? node_ecdsa /* no ecdsa signature case (< TLSv1.2) */
|
node = (has_ecdsa_sig && node_ecdsa) ? node_ecdsa
|
||||||
: node_rsa /* no rsa signature case (far far away) */
|
: ((has_rsa_sig && node_rsa) ? node_rsa
|
||||||
)));
|
: (node_anonymous ? node_anonymous
|
||||||
if (node) {
|
: (node_ecdsa ? node_ecdsa /* no ecdsa signature case (< TLSv1.2) */
|
||||||
/* switch ctx */
|
: node_rsa /* no rsa signature case (far far away) */
|
||||||
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 (node) {
|
||||||
if (conf) {
|
/* switch ctx */
|
||||||
methodVersions[conf->ssl_methods.min].ssl_set_version(ssl, SET_MIN);
|
struct ssl_bind_conf *conf = container_of(node, struct sni_ctx, name)->conf;
|
||||||
methodVersions[conf->ssl_methods.max].ssl_set_version(ssl, SET_MAX);
|
ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
|
||||||
if (conf->early_data)
|
if (conf) {
|
||||||
allow_early = 1;
|
methodVersions[conf->ssl_methods.min].ssl_set_version(ssl, SET_MIN);
|
||||||
}
|
methodVersions[conf->ssl_methods.max].ssl_set_version(ssl, SET_MAX);
|
||||||
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
|
if (conf->early_data)
|
||||||
goto allow_early;
|
allow_early = 1;
|
||||||
}
|
}
|
||||||
|
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
|
||||||
|
goto allow_early;
|
||||||
}
|
}
|
||||||
|
|
||||||
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
|
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user