Don't negotiate TLSv1.3 if our EC cert isn't TLSv1.3 capable
TLSv1.3 is more restrictive about the curve used. There must be a matching sig alg defined for that curve. Therefore if we are using some other curve in our certificate then we should not negotiate TLSv1.3. Fixes #7435 Reviewed-by: Viktor Dukhovni <viktor@openssl.org> (Merged from https://github.com/openssl/openssl/pull/7442)
This commit is contained in:
parent
425036130d
commit
de4dc59802
3 changed files with 48 additions and 2 deletions
|
@ -2564,6 +2564,7 @@ __owur int tls1_process_sigalgs(SSL *s);
|
|||
__owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey);
|
||||
__owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd);
|
||||
__owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
|
||||
__owur int tls_check_sigalg_curve(const SSL *s, int curve);
|
||||
__owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey);
|
||||
__owur int ssl_set_client_disabled(SSL *s);
|
||||
__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int echde);
|
||||
|
|
|
@ -1506,7 +1506,8 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method)
|
|||
*/
|
||||
static int is_tls13_capable(const SSL *s)
|
||||
{
|
||||
int i;
|
||||
int i, curve;
|
||||
EC_KEY *eckey;
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
if (s->psk_server_callback != NULL)
|
||||
|
@ -1527,7 +1528,20 @@ static int is_tls13_capable(const SSL *s)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (ssl_has_cert(s, i))
|
||||
if (!ssl_has_cert(s, i))
|
||||
continue;
|
||||
if (i != SSL_PKEY_ECC)
|
||||
return 1;
|
||||
/*
|
||||
* Prior to TLSv1.3 sig algs allowed any curve to be used. TLSv1.3 is
|
||||
* more restrictive so check that our sig algs are consistent with this
|
||||
* EC cert. See section 4.2.3 of RFC8446.
|
||||
*/
|
||||
eckey = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
|
||||
if (eckey == NULL)
|
||||
continue;
|
||||
curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
|
||||
if (tls_check_sigalg_curve(s, curve))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
31
ssl/t1_lib.c
31
ssl/t1_lib.c
|
@ -949,6 +949,37 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by servers only. Checks that we have a sig alg that supports the
|
||||
* specified EC curve.
|
||||
*/
|
||||
int tls_check_sigalg_curve(const SSL *s, int curve)
|
||||
{
|
||||
const uint16_t *sigs;
|
||||
size_t siglen, i;
|
||||
|
||||
if (s->cert->conf_sigalgs) {
|
||||
sigs = s->cert->conf_sigalgs;
|
||||
siglen = s->cert->conf_sigalgslen;
|
||||
} else {
|
||||
sigs = tls12_sigalgs;
|
||||
siglen = OSSL_NELEM(tls12_sigalgs);
|
||||
}
|
||||
|
||||
for (i = 0; i < siglen; i++) {
|
||||
const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]);
|
||||
|
||||
if (lu == NULL)
|
||||
continue;
|
||||
if (lu->sig == EVP_PKEY_EC
|
||||
&& lu->curve != NID_undef
|
||||
&& curve == lu->curve)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check signature algorithm is consistent with sent supported signature
|
||||
* algorithms and if so set relevant digest and signature scheme in
|
||||
|
|
Loading…
Reference in a new issue