mirror of
https://github.com/openssl/openssl.git
synced 2024-11-24 10:34:12 +08:00
Check that ed25519 and ed448 are allowed by the security level
Signature algorithms not using an MD weren't checked that they're allowed by the security level. Reviewed-by: Matt Caswell <matt@openssl.org> GH: #10785
This commit is contained in:
parent
77c4d39724
commit
620c97b671
39
ssl/t1_lib.c
39
ssl/t1_lib.c
@ -1075,6 +1075,31 @@ int tls_check_sigalg_curve(const SSL *s, int curve)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return the number of security bits for the signature algorithm, or 0 on
|
||||
* error.
|
||||
*/
|
||||
static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu)
|
||||
{
|
||||
const EVP_MD *md = NULL;
|
||||
int secbits = 0;
|
||||
|
||||
if (!tls1_lookup_md(ctx, lu, &md))
|
||||
return 0;
|
||||
if (md != NULL)
|
||||
{
|
||||
/* Security bits: half digest bits */
|
||||
secbits = EVP_MD_size(md) * 4;
|
||||
} else {
|
||||
/* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */
|
||||
if (lu->sigalg == TLSEXT_SIGALG_ed25519)
|
||||
secbits = 128;
|
||||
else if (lu->sigalg == TLSEXT_SIGALG_ed448)
|
||||
secbits = 224;
|
||||
}
|
||||
return secbits;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check signature algorithm is consistent with sent supported signature
|
||||
* algorithms and if so set relevant digest and signature scheme in
|
||||
@ -1088,6 +1113,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
|
||||
size_t sent_sigslen, i, cidx;
|
||||
int pkeyid = EVP_PKEY_id(pkey);
|
||||
const SIGALG_LOOKUP *lu;
|
||||
int secbits = 0;
|
||||
|
||||
/* Should never happen */
|
||||
if (pkeyid == -1)
|
||||
@ -1189,21 +1215,21 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
|
||||
SSL_R_UNKNOWN_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
if (md != NULL) {
|
||||
/*
|
||||
* Make sure security callback allows algorithm. For historical
|
||||
* reasons we have to pass the sigalg as a two byte char array.
|
||||
*/
|
||||
sigalgstr[0] = (sig >> 8) & 0xff;
|
||||
sigalgstr[1] = sig & 0xff;
|
||||
if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
|
||||
EVP_MD_size(md) * 4, EVP_MD_type(md),
|
||||
secbits = sigalg_security_bits(s->ctx, lu);
|
||||
if (secbits == 0 ||
|
||||
!ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits,
|
||||
md != NULL ? EVP_MD_type(md) : NID_undef,
|
||||
(void *)sigalgstr)) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG,
|
||||
SSL_R_WRONG_SIGNATURE_TYPE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Store the sigalg the peer uses */
|
||||
s->s3.tmp.peer_sigalg = lu;
|
||||
return 1;
|
||||
@ -1726,11 +1752,8 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
|
||||
}
|
||||
}
|
||||
|
||||
if (lu->hash == NID_undef)
|
||||
return 1;
|
||||
/* Security bits: half digest bits */
|
||||
secbits = EVP_MD_size(ssl_md(s->ctx, lu->hash_idx)) * 4;
|
||||
/* Finally see if security callback allows it */
|
||||
secbits = sigalg_security_bits(s->ctx, lu);
|
||||
sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
|
||||
sigalgstr[1] = lu->sigalg & 0xff;
|
||||
return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr);
|
||||
|
@ -1,11 +1,13 @@
|
||||
# Generated with generate_ssl_tests.pl
|
||||
|
||||
num_tests = 4
|
||||
num_tests = 6
|
||||
|
||||
test-0 = 0-SECLEVEL 3 with default key
|
||||
test-1 = 1-SECLEVEL 3 with ED448 key
|
||||
test-2 = 2-SECLEVEL 3 with P-384 key, X25519 ECDHE
|
||||
test-3 = 3-SECLEVEL 3 with ED448 key, TLSv1.2
|
||||
test-1 = 1-SECLEVEL 4 with ED448 key
|
||||
test-2 = 2-SECLEVEL 5 server with ED448 key
|
||||
test-3 = 3-SECLEVEL 5 client with ED448 key
|
||||
test-4 = 4-SECLEVEL 3 with P-384 key, X25519 ECDHE
|
||||
test-5 = 5-SECLEVEL 3 with ED448 key, TLSv1.2
|
||||
# ===========================================================
|
||||
|
||||
[0-SECLEVEL 3 with default key]
|
||||
@ -31,20 +33,20 @@ ExpectedResult = ServerFail
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[1-SECLEVEL 3 with ED448 key]
|
||||
ssl_conf = 1-SECLEVEL 3 with ED448 key-ssl
|
||||
[1-SECLEVEL 4 with ED448 key]
|
||||
ssl_conf = 1-SECLEVEL 4 with ED448 key-ssl
|
||||
|
||||
[1-SECLEVEL 3 with ED448 key-ssl]
|
||||
server = 1-SECLEVEL 3 with ED448 key-server
|
||||
client = 1-SECLEVEL 3 with ED448 key-client
|
||||
[1-SECLEVEL 4 with ED448 key-ssl]
|
||||
server = 1-SECLEVEL 4 with ED448 key-server
|
||||
client = 1-SECLEVEL 4 with ED448 key-client
|
||||
|
||||
[1-SECLEVEL 3 with ED448 key-server]
|
||||
[1-SECLEVEL 4 with ED448 key-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/server-ed448-cert.pem
|
||||
CipherString = DEFAULT:@SECLEVEL=3
|
||||
CipherString = DEFAULT:@SECLEVEL=4
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/server-ed448-key.pem
|
||||
|
||||
[1-SECLEVEL 3 with ED448 key-client]
|
||||
CipherString = DEFAULT
|
||||
[1-SECLEVEL 4 with ED448 key-client]
|
||||
CipherString = DEFAULT:@SECLEVEL=4
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-ed448-cert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
@ -54,49 +56,95 @@ ExpectedResult = Success
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[2-SECLEVEL 3 with P-384 key, X25519 ECDHE]
|
||||
ssl_conf = 2-SECLEVEL 3 with P-384 key, X25519 ECDHE-ssl
|
||||
[2-SECLEVEL 5 server with ED448 key]
|
||||
ssl_conf = 2-SECLEVEL 5 server with ED448 key-ssl
|
||||
|
||||
[2-SECLEVEL 3 with P-384 key, X25519 ECDHE-ssl]
|
||||
server = 2-SECLEVEL 3 with P-384 key, X25519 ECDHE-server
|
||||
client = 2-SECLEVEL 3 with P-384 key, X25519 ECDHE-client
|
||||
[2-SECLEVEL 5 server with ED448 key-ssl]
|
||||
server = 2-SECLEVEL 5 server with ED448 key-server
|
||||
client = 2-SECLEVEL 5 server with ED448 key-client
|
||||
|
||||
[2-SECLEVEL 3 with P-384 key, X25519 ECDHE-server]
|
||||
[2-SECLEVEL 5 server with ED448 key-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/server-ed448-cert.pem
|
||||
CipherString = DEFAULT:@SECLEVEL=5
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/server-ed448-key.pem
|
||||
|
||||
[2-SECLEVEL 5 server with ED448 key-client]
|
||||
CipherString = DEFAULT:@SECLEVEL=4
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-ed448-cert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-2]
|
||||
ExpectedResult = ServerFail
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[3-SECLEVEL 5 client with ED448 key]
|
||||
ssl_conf = 3-SECLEVEL 5 client with ED448 key-ssl
|
||||
|
||||
[3-SECLEVEL 5 client with ED448 key-ssl]
|
||||
server = 3-SECLEVEL 5 client with ED448 key-server
|
||||
client = 3-SECLEVEL 5 client with ED448 key-client
|
||||
|
||||
[3-SECLEVEL 5 client with ED448 key-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/server-ed448-cert.pem
|
||||
CipherString = DEFAULT:@SECLEVEL=4
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/server-ed448-key.pem
|
||||
|
||||
[3-SECLEVEL 5 client with ED448 key-client]
|
||||
CipherString = DEFAULT:@SECLEVEL=5
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-ed448-cert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-3]
|
||||
ExpectedResult = ServerFail
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[4-SECLEVEL 3 with P-384 key, X25519 ECDHE]
|
||||
ssl_conf = 4-SECLEVEL 3 with P-384 key, X25519 ECDHE-ssl
|
||||
|
||||
[4-SECLEVEL 3 with P-384 key, X25519 ECDHE-ssl]
|
||||
server = 4-SECLEVEL 3 with P-384 key, X25519 ECDHE-server
|
||||
client = 4-SECLEVEL 3 with P-384 key, X25519 ECDHE-client
|
||||
|
||||
[4-SECLEVEL 3 with P-384 key, X25519 ECDHE-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/p384-server-cert.pem
|
||||
CipherString = DEFAULT:@SECLEVEL=3
|
||||
Groups = X25519
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/p384-server-key.pem
|
||||
|
||||
[2-SECLEVEL 3 with P-384 key, X25519 ECDHE-client]
|
||||
[4-SECLEVEL 3 with P-384 key, X25519 ECDHE-client]
|
||||
CipherString = ECDHE:@SECLEVEL=3
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/p384-root.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-2]
|
||||
[test-4]
|
||||
ExpectedResult = Success
|
||||
|
||||
|
||||
# ===========================================================
|
||||
|
||||
[3-SECLEVEL 3 with ED448 key, TLSv1.2]
|
||||
ssl_conf = 3-SECLEVEL 3 with ED448 key, TLSv1.2-ssl
|
||||
[5-SECLEVEL 3 with ED448 key, TLSv1.2]
|
||||
ssl_conf = 5-SECLEVEL 3 with ED448 key, TLSv1.2-ssl
|
||||
|
||||
[3-SECLEVEL 3 with ED448 key, TLSv1.2-ssl]
|
||||
server = 3-SECLEVEL 3 with ED448 key, TLSv1.2-server
|
||||
client = 3-SECLEVEL 3 with ED448 key, TLSv1.2-client
|
||||
[5-SECLEVEL 3 with ED448 key, TLSv1.2-ssl]
|
||||
server = 5-SECLEVEL 3 with ED448 key, TLSv1.2-server
|
||||
client = 5-SECLEVEL 3 with ED448 key, TLSv1.2-client
|
||||
|
||||
[3-SECLEVEL 3 with ED448 key, TLSv1.2-server]
|
||||
[5-SECLEVEL 3 with ED448 key, TLSv1.2-server]
|
||||
Certificate = ${ENV::TEST_CERTS_DIR}/server-ed448-cert.pem
|
||||
CipherString = DEFAULT:@SECLEVEL=3
|
||||
MaxProtocol = TLSv1.2
|
||||
PrivateKey = ${ENV::TEST_CERTS_DIR}/server-ed448-key.pem
|
||||
|
||||
[3-SECLEVEL 3 with ED448 key, TLSv1.2-client]
|
||||
[5-SECLEVEL 3 with ED448 key, TLSv1.2-client]
|
||||
CipherString = DEFAULT
|
||||
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/root-ed448-cert.pem
|
||||
VerifyMode = Peer
|
||||
|
||||
[test-3]
|
||||
[test-5]
|
||||
ExpectedResult = Success
|
||||
|
||||
|
||||
|
@ -23,13 +23,38 @@ our @tests = (
|
||||
|
||||
our @tests_ec = (
|
||||
{
|
||||
name => "SECLEVEL 3 with ED448 key",
|
||||
server => { "CipherString" => "DEFAULT:\@SECLEVEL=3",
|
||||
name => "SECLEVEL 4 with ED448 key",
|
||||
server => { "CipherString" => "DEFAULT:\@SECLEVEL=4",
|
||||
"Certificate" => test_pem("server-ed448-cert.pem"),
|
||||
"PrivateKey" => test_pem("server-ed448-key.pem") },
|
||||
client => { "VerifyCAFile" => test_pem("root-ed448-cert.pem") },
|
||||
client => { "CipherString" => "DEFAULT:\@SECLEVEL=4",
|
||||
"VerifyCAFile" => test_pem("root-ed448-cert.pem") },
|
||||
test => { "ExpectedResult" => "Success" },
|
||||
},
|
||||
{
|
||||
# The Ed488 signature algorithm will not be enabled.
|
||||
# Because of the config order, the certificate is first loaded, and
|
||||
# then the security level is chaged. If you try this with s_server
|
||||
# the order will be reversed and it will instead fail to load the key.
|
||||
name => "SECLEVEL 5 server with ED448 key",
|
||||
server => { "CipherString" => "DEFAULT:\@SECLEVEL=5",
|
||||
"Certificate" => test_pem("server-ed448-cert.pem"),
|
||||
"PrivateKey" => test_pem("server-ed448-key.pem") },
|
||||
client => { "CipherString" => "DEFAULT:\@SECLEVEL=4",
|
||||
"VerifyCAFile" => test_pem("root-ed448-cert.pem") },
|
||||
test => { "ExpectedResult" => "ServerFail" },
|
||||
},
|
||||
{
|
||||
# The client will not sent the Ed488 signature algorithm, so the server
|
||||
# doesn't have a useable signature algorithm for the certificate.
|
||||
name => "SECLEVEL 5 client with ED448 key",
|
||||
server => { "CipherString" => "DEFAULT:\@SECLEVEL=4",
|
||||
"Certificate" => test_pem("server-ed448-cert.pem"),
|
||||
"PrivateKey" => test_pem("server-ed448-key.pem") },
|
||||
client => { "CipherString" => "DEFAULT:\@SECLEVEL=5",
|
||||
"VerifyCAFile" => test_pem("root-ed448-cert.pem") },
|
||||
test => { "ExpectedResult" => "ServerFail" },
|
||||
},
|
||||
{
|
||||
name => "SECLEVEL 3 with P-384 key, X25519 ECDHE",
|
||||
server => { "CipherString" => "DEFAULT:\@SECLEVEL=3",
|
||||
|
Loading…
Reference in New Issue
Block a user