diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-03-06 15:09:50 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-03-09 17:01:10 +0100 |
commit | 51d21634c9329463a8d7def24550ef268bc9b88c (patch) | |
tree | 49a8e2370b632040c8fbdbd03b9f8b51cef34677 | |
parent | 02354f173e66df3dad4ac9447e4965aecfad65e8 (diff) | |
download | gnutls-51d21634c9329463a8d7def24550ef268bc9b88c.tar.gz |
signatures: distinguish RSA-PSS signatures with RSA PKCS#1 1.5 certificates from "pure"
This change enhances signature algorithms to have a private key algorithm
parameter. That is, to allow signature algorithms operating with a private
key of type X while the public key is of type Y. That is useful for the
RSA-PSS signatures which are of two types; one which is seen from servers
having PKCS#1 1.5 certificates, the other with RSA-PSS certificates, while
both utilize RSA-PSS private keys.
This is a draft-ietf-tls-tls13-23 change.
Resolves #400
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/algorithms.h | 34 | ||||
-rw-r--r-- | lib/algorithms/sign.c | 60 | ||||
-rw-r--r-- | lib/ext/signature.c | 23 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 24 | ||||
-rw-r--r-- | lib/priority.c | 8 | ||||
-rw-r--r-- | lib/privkey.c | 17 | ||||
-rw-r--r-- | lib/pubkey.c | 8 | ||||
-rw-r--r-- | lib/tls-sig.c | 9 | ||||
-rw-r--r-- | lib/tls13-sig.c | 17 | ||||
-rw-r--r-- | tests/common-cert-key-exchange.h | 2 | ||||
-rw-r--r-- | tests/dtls12-cert-key-exchange.c | 6 | ||||
-rw-r--r-- | tests/pkcs11/tls-neg-pkcs11-key.c | 2 | ||||
-rw-r--r-- | tests/privkey-verify-broken.c | 2 | ||||
-rw-r--r-- | tests/rsa-rsa-pss.c | 75 | ||||
-rw-r--r-- | tests/suite/tls-fuzzer/gnutls-cert.json | 5 | ||||
-rw-r--r-- | tests/suite/tls-fuzzer/gnutls-nocert.json | 6 | ||||
-rw-r--r-- | tests/tls-neg-ext-key.c | 6 | ||||
-rw-r--r-- | tests/tls12-cert-key-exchange.c | 6 | ||||
-rw-r--r-- | tests/tls13-cert-key-exchange.c | 16 | ||||
-rw-r--r-- | tests/tls13/prf.c | 18 |
20 files changed, 241 insertions, 103 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h index 556bc33901..495b20d439 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -327,6 +327,18 @@ struct gnutls_sign_entry_st { gnutls_pk_algorithm_t pk; gnutls_digest_algorithm_t hash; + /* if non-zero it must be the algorithm of the + * private key used or certificate. This is for algorithms + * which can have a different public key type than the + * private key (e.g., RSA PKCS#1 1.5 certificate, but + * an RSA-PSS private key, or an RSA private key and + * an RSA-PSS certificate). */ + gnutls_pk_algorithm_t priv_pk; + gnutls_pk_algorithm_t cert_pk; + + /* non-zero if it is ok to use under TLS1.3 */ + unsigned tls13_ok; + /* if this signature algorithm is restricted to a curve * under TLS 1.3. */ gnutls_ecc_curve_t curve; @@ -342,6 +354,28 @@ const gnutls_sign_entry_st *_gnutls_sign_to_entry(gnutls_sign_algorithm_t sign); const gnutls_sign_entry_st *_gnutls_pk_to_sign_entry(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash); const gnutls_sign_entry_st *_gnutls_oid_to_sign_entry(const char *oid); +/* returns true if that signature can be generated + * from the given private key algorithm. */ +inline static unsigned +sign_supports_priv_pk_algorithm(const gnutls_sign_entry_st *se, gnutls_pk_algorithm_t pk) +{ + if (pk == se->pk || (se->priv_pk && se->priv_pk == pk)) + return 1; + + return 0; +} + +/* returns true if that signature can be verified with + * the given public key algorithm. */ +inline static unsigned +sign_supports_cert_pk_algorithm(const gnutls_sign_entry_st *se, gnutls_pk_algorithm_t pk) +{ + if (pk == se->pk || (se->cert_pk && se->cert_pk == pk)) + return 1; + + return 0; +} + bool _gnutls_sign_is_secure2(const gnutls_sign_entry_st *se, unsigned int flags); gnutls_pk_algorithm_t _gnutls_x509_sign_to_pk(gnutls_sign_algorithm_t diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c index 33fd881892..5a45e9fa10 100644 --- a/lib/algorithms/sign.c +++ b/lib/algorithms/sign.c @@ -36,9 +36,6 @@ # define SHA1_SECURE_VAL _INSECURE_FOR_CERTS #endif -/* Signature algorithms may be listed twice with a different PK algorithm, - * e.g., RSA-PSS-SHA256 can be generated by GNUTLS_PK_RSA or GNUTLS_PK_RSA_PSS. - */ static const gnutls_sign_entry_st sign_algorithms[] = { /* RSA-PKCS#1 1.5: must be before PSS, * so that gnutls_pk_to_sign() will return @@ -67,37 +64,52 @@ static const gnutls_sign_entry_st sign_algorithms[] = { .oid = PK_PKIX1_RSA_PSS_OID, .id = GNUTLS_SIGN_RSA_PSS_SHA256, .pk = GNUTLS_PK_RSA_PSS, + .priv_pk = GNUTLS_PK_RSA, /* PKCS#11 doesn't separate RSA from RSA-PSS privkeys */ .hash = GNUTLS_DIG_SHA256, - .aid = {{8, 4}, SIG_SEM_DEFAULT}}, - {.name = "RSA-PSS-SHA256", + .tls13_ok = 1, + .aid = {{8, 9}, SIG_SEM_DEFAULT}}, + {.name = "RSA-PSS-RSAE-SHA256", .oid = PK_PKIX1_RSA_PSS_OID, - .id = GNUTLS_SIGN_RSA_PSS_SHA256, - .pk = GNUTLS_PK_RSA, + .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, + .pk = GNUTLS_PK_RSA_PSS, + .cert_pk = GNUTLS_PK_RSA, + .priv_pk = GNUTLS_PK_RSA, .hash = GNUTLS_DIG_SHA256, + .tls13_ok = 1, .aid = {{8, 4}, SIG_SEM_DEFAULT}}, {.name = "RSA-PSS-SHA384", .oid = PK_PKIX1_RSA_PSS_OID, .id = GNUTLS_SIGN_RSA_PSS_SHA384, .pk = GNUTLS_PK_RSA_PSS, + .priv_pk = GNUTLS_PK_RSA, .hash = GNUTLS_DIG_SHA384, - .aid = {{8, 5}, SIG_SEM_DEFAULT}}, - {.name = "RSA-PSS-SHA384", + .tls13_ok = 1, + .aid = {{8, 0x0A}, SIG_SEM_DEFAULT}}, + {.name = "RSA-PSS-RSAE-SHA384", .oid = PK_PKIX1_RSA_PSS_OID, - .id = GNUTLS_SIGN_RSA_PSS_SHA384, - .pk = GNUTLS_PK_RSA, + .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA384, + .pk = GNUTLS_PK_RSA_PSS, + .cert_pk = GNUTLS_PK_RSA, + .priv_pk = GNUTLS_PK_RSA, .hash = GNUTLS_DIG_SHA384, + .tls13_ok = 1, .aid = {{8, 5}, SIG_SEM_DEFAULT}}, {.name = "RSA-PSS-SHA512", .oid = PK_PKIX1_RSA_PSS_OID, .id = GNUTLS_SIGN_RSA_PSS_SHA512, .pk = GNUTLS_PK_RSA_PSS, + .priv_pk = GNUTLS_PK_RSA, .hash = GNUTLS_DIG_SHA512, - .aid = {{8, 6}, SIG_SEM_DEFAULT}}, - {.name = "RSA-PSS-SHA512", + .tls13_ok = 1, + .aid = {{8, 0x0B}, SIG_SEM_DEFAULT}}, + {.name = "RSA-PSS-RSAE-SHA512", .oid = PK_PKIX1_RSA_PSS_OID, - .id = GNUTLS_SIGN_RSA_PSS_SHA512, - .pk = GNUTLS_PK_RSA, + .id = GNUTLS_SIGN_RSA_PSS_RSAE_SHA512, + .pk = GNUTLS_PK_RSA_PSS, + .cert_pk = GNUTLS_PK_RSA, + .priv_pk = GNUTLS_PK_RSA, .hash = GNUTLS_DIG_SHA512, + .tls13_ok = 1, .aid = {{8, 6}, SIG_SEM_DEFAULT}}, /* Ed25519: The hash algorithm here is set to be SHA512, although that is @@ -108,6 +120,7 @@ static const gnutls_sign_entry_st sign_algorithms[] = { .id = GNUTLS_SIGN_EDDSA_ED25519, .pk = GNUTLS_PK_EDDSA_ED25519, .hash = GNUTLS_DIG_SHA512, + .tls13_ok = 1, .aid = {{8, 7}, SIG_SEM_DEFAULT}}, /* ECDSA */ @@ -144,18 +157,21 @@ static const gnutls_sign_entry_st sign_algorithms[] = { .pk = GNUTLS_PK_ECDSA, .curve = GNUTLS_ECC_CURVE_SECP256R1, .hash = GNUTLS_DIG_SHA256, + .tls13_ok = 1, .aid = {{4, 3}, SIG_SEM_TLS13}}, {.name = "ECDSA-SECP384R1-SHA384", .id = GNUTLS_SIGN_ECDSA_SECP384R1_SHA384, .pk = GNUTLS_PK_ECDSA, .curve = GNUTLS_ECC_CURVE_SECP384R1, .hash = GNUTLS_DIG_SHA384, + .tls13_ok = 1, .aid = {{5, 3}, SIG_SEM_TLS13}}, {.name = "ECDSA-SECP521R1-SHA512", .id = GNUTLS_SIGN_ECDSA_SECP521R1_SHA512, .pk = GNUTLS_PK_ECDSA, .curve = GNUTLS_ECC_CURVE_SECP521R1, .hash = GNUTLS_DIG_SHA512, + .tls13_ok = 1, .aid = {{6, 3}, SIG_SEM_TLS13}}, /* ECDSA-SHA3 */ @@ -616,7 +632,8 @@ gnutls_sign_get_pk_algorithm(gnutls_sign_algorithm_t sign) * @pk: is a public key algorithm * * This function returns non-zero if the public key algorithm corresponds to - * the given signature algorithm. + * the given signature algorithm. That is, if that signature can be generated + * from the given private key algorithm. * * Since: 3.6.0 * @@ -625,7 +642,16 @@ gnutls_sign_get_pk_algorithm(gnutls_sign_algorithm_t sign) unsigned gnutls_sign_supports_pk_algorithm(gnutls_sign_algorithm_t sign, gnutls_pk_algorithm_t pk) { - GNUTLS_SIGN_LOOP( if(p->id && p->id == sign && pk == p->pk) { return 1; } ); + const gnutls_sign_entry_st *p; + unsigned r; + + for(p = sign_algorithms; p->name != NULL; p++) { + if (p->id && p->id == sign) { + r = sign_supports_priv_pk_algorithm(p, pk); + if (r != 0) + return r; + } + } return 0; } diff --git a/lib/ext/signature.c b/lib/ext/signature.c index 8b4bb1ac65..7bf2761fdf 100644 --- a/lib/ext/signature.c +++ b/lib/ext/signature.c @@ -283,6 +283,7 @@ _gnutls_session_get_sign_algo(gnutls_session_t session, sig_ext_st *priv; gnutls_ext_priv_data_t epriv; unsigned int cert_algo; + const gnutls_sign_entry_st *se; if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_SIGN_UNKNOWN); @@ -304,23 +305,28 @@ _gnutls_session_get_sign_algo(gnutls_session_t session, return ret; } + + for (i = 0; i < priv->sign_algorithms_size; i++) { - _gnutls_handshake_log("checking cert compat with %s\n", gnutls_sign_algorithm_get_name(priv->sign_algorithms[i])); + se = _gnutls_sign_to_entry(priv->sign_algorithms[i]); + if (se == NULL) + continue; + + _gnutls_handshake_log("checking cert compat with %s\n", se->name); if (_gnutls_privkey_compatible_with_sig(privkey, priv->sign_algorithms[i]) == 0) continue; - if (gnutls_sign_supports_pk_algorithm(priv->sign_algorithms[i], cert_algo) != 0) { + if (sign_supports_cert_pk_algorithm(se, cert_algo) != 0) { if (_gnutls_pubkey_compatible_with_sig - (session, cert->pubkey, ver, - priv->sign_algorithms[i]) < 0) + (session, cert->pubkey, ver, se->id) < 0) continue; if (_gnutls_session_sign_algo_enabled - (session, priv->sign_algorithms[i]) < 0) + (session, se->id) < 0) continue; - return priv->sign_algorithms[i]; + return se->id; } } @@ -328,7 +334,7 @@ _gnutls_session_get_sign_algo(gnutls_session_t session, * using algorithms we don't always enable by default (e.g., DSA-SHA1), * continue and sign with it. */ if (client_cert) { - _gnutls_audit_log(session, "No shared signature schemes with peer for client certificate (%s). Is the certificate a legacy one?", + _gnutls_audit_log(session, "No shared signature schemes with peer for client certificate (%s). Is the certificate a legacy one?\n", gnutls_pk_get_name(cert_algo)); } @@ -357,8 +363,9 @@ _gnutls_session_sign_algo_enabled(gnutls_session_t session, if (ver->tls13_sem) { /* disallow RSA, DSA, and SHA1 */ const gnutls_sign_entry_st *se; + se = _gnutls_sign_to_entry(sig); - if (se == NULL || se->pk == GNUTLS_PK_RSA || se->pk == GNUTLS_PK_DSA || se->hash == GNUTLS_DIG_SHA1) { + if (se == NULL || (se->tls13_ok == 0)) { gnutls_assert(); goto disallowed; } diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 37d90adfcf..976ba7322a 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -797,9 +797,21 @@ const char *gnutls_pk_algorithm_get_name(gnutls_pk_algorithm_t algorithm); * @GNUTLS_SIGN_RSA_SHA3_256: Digital signature algorithm RSA with SHA3-256. * @GNUTLS_SIGN_RSA_SHA3_384: Digital signature algorithm RSA with SHA3-384. * @GNUTLS_SIGN_RSA_SHA3_512: Digital signature algorithm RSA with SHA3-512. - * @GNUTLS_SIGN_RSA_PSS_SHA256: Digital signature algorithm RSA with SHA-256, with PSS padding. - * @GNUTLS_SIGN_RSA_PSS_SHA384: Digital signature algorithm RSA with SHA-384, with PSS padding. - * @GNUTLS_SIGN_RSA_PSS_SHA512: Digital signature algorithm RSA with SHA-512, with PSS padding. + * @GNUTLS_SIGN_RSA_PSS_RSAE_SHA256: Digital signature algorithm RSA with SHA-256, + * with PSS padding (RSA PKCS#1 1.5 certificate). This signature is identical + * to #GNUTLS_SIGN_RSA_PSS_SHA256, but they are distinct as the TLS1.3 protocol + * treats them differently. + * @GNUTLS_SIGN_RSA_PSS_RSAE_SHA384: Digital signature algorithm RSA with SHA-384, + * with PSS padding (RSA PKCS#1 1.5 certificate). This signature is identical + * to #GNUTLS_SIGN_RSA_PSS_SHA384, but they are distinct as the TLS1.3 protocol + * treats them differently. + * @GNUTLS_SIGN_RSA_PSS_RSAE_SHA512: Digital signature algorithm RSA with SHA-512, + * with PSS padding (RSA PKCS#1 1.5 certificate). This signature is identical + * to #GNUTLS_SIGN_RSA_PSS_SHA512, but they are distinct as the TLS1.3 protocol + * treats them differently. + * @GNUTLS_SIGN_RSA_PSS_SHA256: Digital signature algorithm RSA with SHA-256, with PSS padding (RSA-PSS certificate). + * @GNUTLS_SIGN_RSA_PSS_SHA384: Digital signature algorithm RSA with SHA-384, with PSS padding (RSA-PSS certificate). + * @GNUTLS_SIGN_RSA_PSS_SHA512: Digital signature algorithm RSA with SHA-512, with PSS padding (RSA-PSS certificate). * @GNUTLS_SIGN_EDDSA_ED25519: Digital signature algorithm EdDSA with Ed25519 curve. * * Enumeration of different digital signature algorithms. @@ -849,7 +861,11 @@ typedef enum { GNUTLS_SIGN_ECDSA_SECP256R1_SHA256 = 37, GNUTLS_SIGN_ECDSA_SECP384R1_SHA384 = 38, GNUTLS_SIGN_ECDSA_SECP521R1_SHA512 = 39, - GNUTLS_SIGN_MAX = GNUTLS_SIGN_ECDSA_SECP521R1_SHA512 + + GNUTLS_SIGN_RSA_PSS_RSAE_SHA256 = 40, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA384 = 41, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA512 = 42, + GNUTLS_SIGN_MAX = GNUTLS_SIGN_RSA_PSS_RSAE_SHA512 } gnutls_sign_algorithm_t; /** diff --git a/lib/priority.c b/lib/priority.c index a83a1ffc78..8e2132ffea 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -349,6 +349,7 @@ static const int* cipher_priority_secure192 = _cipher_priority_secure192; static const int _sign_priority_default[] = { GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, @@ -356,11 +357,13 @@ static const int _sign_priority_default[] = { GNUTLS_SIGN_RSA_SHA384, GNUTLS_SIGN_RSA_PSS_SHA384, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA384, GNUTLS_SIGN_ECDSA_SHA384, GNUTLS_SIGN_ECDSA_SECP384R1_SHA384, GNUTLS_SIGN_RSA_SHA512, GNUTLS_SIGN_RSA_PSS_SHA512, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA512, GNUTLS_SIGN_ECDSA_SHA512, GNUTLS_SIGN_ECDSA_SECP521R1_SHA512, @@ -391,17 +394,20 @@ static const int* sign_priority_suiteb192 = _sign_priority_suiteb192; static const int _sign_priority_secure128[] = { GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_RSA_SHA384, GNUTLS_SIGN_RSA_PSS_SHA384, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA384, GNUTLS_SIGN_ECDSA_SHA384, GNUTLS_SIGN_ECDSA_SECP384R1_SHA384, GNUTLS_SIGN_RSA_SHA512, GNUTLS_SIGN_RSA_PSS_SHA512, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA512, GNUTLS_SIGN_ECDSA_SHA512, GNUTLS_SIGN_ECDSA_SECP521R1_SHA512, @@ -412,10 +418,12 @@ static const int* sign_priority_secure128 = _sign_priority_secure128; static const int _sign_priority_secure192[] = { GNUTLS_SIGN_RSA_SHA384, GNUTLS_SIGN_RSA_PSS_SHA384, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA384, GNUTLS_SIGN_ECDSA_SHA384, GNUTLS_SIGN_ECDSA_SECP384R1_SHA384, GNUTLS_SIGN_RSA_SHA512, GNUTLS_SIGN_RSA_PSS_SHA512, + GNUTLS_SIGN_RSA_PSS_RSAE_SHA512, GNUTLS_SIGN_ECDSA_SHA512, GNUTLS_SIGN_ECDSA_SECP521R1_SHA512, diff --git a/lib/privkey.c b/lib/privkey.c index 10afdf90f1..e5b7e83965 100644 --- a/lib/privkey.c +++ b/lib/privkey.c @@ -1148,13 +1148,13 @@ gnutls_privkey_sign_data2(gnutls_privkey_t signer, { int ret; gnutls_x509_spki_st params; - const gnutls_sign_entry_st *e; + const gnutls_sign_entry_st *se; if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - e = _gnutls_sign_to_entry(algo); - if (e == NULL) + se = _gnutls_sign_to_entry(algo); + if (se == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ret = _gnutls_privkey_get_spki_params(signer, ¶ms); @@ -1163,14 +1163,14 @@ gnutls_privkey_sign_data2(gnutls_privkey_t signer, return ret; } - ret = _gnutls_privkey_update_spki_params(signer, e->pk, e->hash, + ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash, flags, ¶ms); if (ret < 0) { gnutls_assert(); return ret; } - return privkey_sign_and_hash_data(signer, _gnutls_sign_to_entry(algo), data, signature, ¶ms); + return privkey_sign_and_hash_data(signer, se, data, signature, ¶ms); } /** @@ -1831,8 +1831,13 @@ unsigned _gnutls_privkey_compatible_with_sig(gnutls_privkey_t privkey, * and RSA keys which cannot do RSA-PSS (e.g., smart card) from * negotiating RSA-PSS sig. */ - if (privkey->pk_algorithm == GNUTLS_PK_RSA_PSS && se->pk != GNUTLS_PK_RSA_PSS) { + + if (se->pk != privkey->pk_algorithm) { /* if the PK algorithm of the signature differs to the one on the pubkey */ + if (!sign_supports_priv_pk_algorithm(se, privkey->pk_algorithm)) { + _gnutls_handshake_log("cannot use privkey of %s with %s\n", + gnutls_pk_get_name(privkey->pk_algorithm), se->name); return 0; + } } if (privkey->type == GNUTLS_PRIVKEY_EXT) { diff --git a/lib/pubkey.c b/lib/pubkey.c index 466e2dee63..d6d374b786 100644 --- a/lib/pubkey.c +++ b/lib/pubkey.c @@ -1518,7 +1518,7 @@ int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_e unsigned bits; if (se->pk != key_params->algo) { - if (!gnutls_sign_supports_pk_algorithm(se->id, key_params->algo)) { + if (!sign_supports_priv_pk_algorithm(se, key_params->algo)) { _gnutls_debug_log("have key: %s/%d, with sign %s/%d\n", gnutls_pk_get_name(key_params->algo), key_params->algo, se->name, se->id); @@ -1729,7 +1729,7 @@ int pubkey_supports_sig(gnutls_pubkey_t pubkey, gnutls_ecc_curve_t curve = pubkey->params.curve; if (curve != se->curve) { - _gnutls_debug_log("have key: ECDSA with %s/%d, with sign %s/%d\n", + _gnutls_handshake_log("have key: ECDSA with %s/%d, with sign %s/%d\n", gnutls_ecc_curve_get_name(curve), (int)curve, se->name, se->id); return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY); @@ -1737,8 +1737,8 @@ int pubkey_supports_sig(gnutls_pubkey_t pubkey, } if (se->pk != pubkey->params.algo) { /* if the PK algorithm of the signature differs to the one on the pubkey */ - if (!gnutls_sign_supports_pk_algorithm(se->id, pubkey->params.algo)) { - _gnutls_debug_log("have key: %s/%d, with sign %s/%d\n", + if (!sign_supports_priv_pk_algorithm(se, pubkey->params.algo)) { + _gnutls_handshake_log("have key: %s/%d, with sign %s/%d\n", gnutls_pk_get_name(pubkey->params.algo), pubkey->params.algo, se->name, se->id); return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY); diff --git a/lib/tls-sig.c b/lib/tls-sig.c index 26b36e6115..87016172e2 100644 --- a/lib/tls-sig.c +++ b/lib/tls-sig.c @@ -87,6 +87,9 @@ _gnutls_handshake_sign_data12(gnutls_session_t session, ("HSK[%p]: signing TLS 1.2 handshake data: using %s\n", session, gnutls_sign_algorithm_get_name(sign_algo)); + if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pkey->pk_algorithm) == 0)) + return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + dconcat.size = GNUTLS_RANDOM_SIZE*2 + params->size; dconcat.data = gnutls_malloc(dconcat.size); if (dconcat.data == NULL) @@ -121,7 +124,8 @@ _gnutls_handshake_sign_data10(gnutls_session_t session, const mac_entry_st *me; gnutls_pk_algorithm_t pk_algo; - if (gnutls_privkey_get_pk_algorithm(pkey, NULL) == GNUTLS_PK_RSA) + pk_algo = gnutls_privkey_get_pk_algorithm(pkey, NULL); + if (pk_algo == GNUTLS_PK_RSA) me = hash_to_entry(GNUTLS_DIG_MD5_SHA1); else me = hash_to_entry( @@ -129,6 +133,9 @@ _gnutls_handshake_sign_data10(gnutls_session_t session, if (me == NULL) return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM); + if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pk_algo) == 0)) + return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + pk_algo = gnutls_sign_get_pk_algorithm(sign_algo); if (pk_algo == GNUTLS_PK_UNKNOWN) return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM); diff --git a/lib/tls13-sig.c b/lib/tls13-sig.c index 8995fa456c..334052df2c 100644 --- a/lib/tls13-sig.c +++ b/lib/tls13-sig.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2017-2018 Red Hat, Inc. * * Author: Nikos Mavrogiannopoulos * @@ -61,14 +61,18 @@ _gnutls13_handshake_verify_data(gnutls_session_t session, if (ret < 0) return gnutls_assert_val(ret); + if (unlikely(sign_supports_cert_pk_algorithm(se, cert->pubkey->params.algo) == 0)) { + _gnutls_handshake_log("HSK[%p]: certificate of %s cannot be combined with %s sig\n", + session, gnutls_pk_get_name(cert->pubkey->params.algo), se->name); + return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + } + ret = _gnutls_session_sign_algo_enabled(session, se->id); if (ret < 0) return gnutls_assert_val(ret); - if (se->hash == GNUTLS_DIG_SHA1) /* explicitly prohibited */ - return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); - if (se->pk == GNUTLS_PK_RSA) /* explicitly prohibited */ + if (se->tls13_ok == 0) /* explicitly prohibited */ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); _gnutls_buffer_init(&buf); @@ -140,7 +144,10 @@ _gnutls13_handshake_sign_data(gnutls_session_t session, gnutls_buffer_st buf; uint8_t prefix[PREFIX_SIZE]; - if (unlikely(se == NULL || se->hash == GNUTLS_DIG_SHA1 || se->pk == GNUTLS_PK_RSA)) + if (unlikely(se == NULL || se->tls13_ok == 0)) + return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + + if (unlikely(sign_supports_priv_pk_algorithm(se, pkey->pk_algorithm) == 0)) return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); _gnutls_handshake_log diff --git a/tests/common-cert-key-exchange.h b/tests/common-cert-key-exchange.h index 4c7d6c0ca9..47e3738900 100644 --- a/tests/common-cert-key-exchange.h +++ b/tests/common-cert-key-exchange.h @@ -36,7 +36,7 @@ extern const char *server_priority; &server_ca3_localhost_cert, &server_ca3_key, NULL, NULL, 0) #define try_ks(name, client_prio, client_kx, group) \ - try_with_key_ks(name, client_prio, client_kx, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN, \ + try_with_key_ks(name, client_prio, client_kx, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN, \ &server_ca3_localhost_cert, &server_ca3_key, NULL, NULL, 0, group) #define try_cli(name, client_prio, client_kx, server_sign_algo, client_sign_algo, client_cert) \ diff --git a/tests/dtls12-cert-key-exchange.c b/tests/dtls12-cert-key-exchange.c index 0903cafe66..82028041d7 100644 --- a/tests/dtls12-cert-key-exchange.c +++ b/tests/dtls12-cert-key-exchange.c @@ -48,8 +48,8 @@ void doit(void) dtls_try_with_key("DTLS 1.2 with ecdhe ecdsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_UNKNOWN, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0); - dtls_try("DTLS 1.2 with ecdhe rsa-pss sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - dtls_try("DTLS 1.2 with ecdhe rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); + dtls_try("DTLS 1.2 with ecdhe rsa-pss sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + dtls_try("DTLS 1.2 with ecdhe rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); dtls_try_with_key("TLS 1.2 with ecdhe rsa-pss/rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN, &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, NULL, NULL, 0); dtls_try("DTLS 1.2 with rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN); @@ -63,7 +63,7 @@ void doit(void) &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, USE_CERT); - dtls_try_cli("DTLS 1.2 with ecdhe-rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, USE_CERT); + dtls_try_cli("DTLS 1.2 with ecdhe-rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, USE_CERT); dtls_try_with_key("DTLS 1.2 with ecdhe-rsa-pss/rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT); dtls_try_cli("DTLS 1.2 with dhe-rsa ask cli-cert", "NORMAL:-VERS-ALL:+VERS-DTLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT); diff --git a/tests/pkcs11/tls-neg-pkcs11-key.c b/tests/pkcs11/tls-neg-pkcs11-key.c index c85d8789df..c32dee27a6 100644 --- a/tests/pkcs11/tls-neg-pkcs11-key.c +++ b/tests/pkcs11/tls-neg-pkcs11-key.c @@ -286,7 +286,7 @@ static const test_st tests[] = { }, {.name = "tls1.2: rsa-pss cert, rsa-sign key no PSS signatures", .pk = GNUTLS_PK_RSA, - .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA:-VERS-TLS-ALL:+VERS-TLS1.2:-SIGN-RSA-PSS-SHA256:-SIGN-RSA-PSS-SHA384:-SIGN-RSA-PSS-SHA512", + .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA:-VERS-TLS-ALL:+VERS-TLS1.2:-SIGN-RSA-PSS-SHA256:-SIGN-RSA-PSS-SHA384:-SIGN-RSA-PSS-SHA512:-SIGN-RSA-PSS-RSAE-SHA256:-SIGN-RSA-PSS-RSAE-SHA384:-SIGN-RSA-PSS-RSAE-SHA512", .cert = &server_ca3_rsa_pss_cert, .key = &server_ca3_rsa_pss_key, .exp_kx = GNUTLS_KX_ECDHE_RSA, diff --git a/tests/privkey-verify-broken.c b/tests/privkey-verify-broken.c index aaf640d030..276fcdaafe 100644 --- a/tests/privkey-verify-broken.c +++ b/tests/privkey-verify-broken.c @@ -145,7 +145,7 @@ void doit(void) if (sign_verify_data(pkey, GNUTLS_SIGN_RSA_SHA3_256, 0) < 0) fail("failed verification with SHA3-256!\n"); - if (sign_verify_data(pkey, GNUTLS_SIGN_RSA_PSS_SHA256, 0) < 0) + if (sign_verify_data(pkey, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, 0) < 0) fail("failed verification with SHA256 with PSS!\n"); gnutls_x509_privkey_deinit(pkey); diff --git a/tests/rsa-rsa-pss.c b/tests/rsa-rsa-pss.c index 74ed99055a..2ba926e321 100644 --- a/tests/rsa-rsa-pss.c +++ b/tests/rsa-rsa-pss.c @@ -46,8 +46,8 @@ const gnutls_datum_t raw_data = { 11 }; -static void inv_sign_check(gnutls_pk_algorithm_t algorithm, unsigned sigalgo, - gnutls_privkey_t privkey, int exp_error) +static void inv_sign_check(unsigned sigalgo, + gnutls_privkey_t privkey, int exp_error) { int ret; gnutls_datum_t signature; @@ -55,9 +55,11 @@ static void inv_sign_check(gnutls_pk_algorithm_t algorithm, unsigned sigalgo, ret = gnutls_privkey_sign_data2(privkey, sigalgo, 0, &raw_data, &signature); if (ret != exp_error) - fail("gnutls_privkey_sign_data succeeded with %s and %s: %s\n", gnutls_pk_get_name(algorithm), + fail("gnutls_privkey_sign_data succeeded with %s and %s: %s\n", gnutls_pk_get_name(gnutls_privkey_get_pk_algorithm(privkey, NULL)), gnutls_sign_get_name(sigalgo), gnutls_strerror(ret)); + if (ret == 0) + gnutls_free(signature.data); } static void inv_encryption_check(gnutls_pk_algorithm_t algorithm, @@ -82,8 +84,7 @@ static void inv_encryption_check(gnutls_pk_algorithm_t algorithm, } -static void sign_verify_data(gnutls_pk_algorithm_t algorithm, unsigned sigalgo, - gnutls_privkey_t privkey) +static void sign_verify_data(unsigned sigalgo, gnutls_privkey_t privkey) { int ret; gnutls_pubkey_t pubkey; @@ -112,7 +113,8 @@ static void sign_verify_data(gnutls_pk_algorithm_t algorithm, unsigned sigalgo, void doit(void) { - gnutls_privkey_t pkey; + gnutls_privkey_t pkey_rsa_pss; + gnutls_privkey_t pkey_rsa; gnutls_x509_privkey_t tkey; int ret; gnutls_x509_spki_t spki; @@ -128,46 +130,67 @@ void doit(void) assert(gnutls_x509_spki_init(&spki)>=0); - assert(gnutls_privkey_init(&pkey) >=0); + assert(gnutls_privkey_init(&pkey_rsa) >=0); gnutls_x509_spki_set_rsa_pss_params(spki, GNUTLS_DIG_SHA256, 32); ret = - gnutls_privkey_generate(pkey, GNUTLS_PK_RSA, 2048, 0); + gnutls_privkey_generate(pkey_rsa, GNUTLS_PK_RSA, 2048, 0); if (ret < 0) { fail("gnutls_privkey_generate: %s\n", gnutls_strerror(ret)); } - assert(gnutls_privkey_set_spki(pkey, spki, 0)>=0); - assert(gnutls_privkey_export_x509(pkey, &tkey) >=0); + assert(gnutls_privkey_set_spki(pkey_rsa, spki, 0)>=0); + assert(gnutls_privkey_export_x509(pkey_rsa, &tkey) >=0); gnutls_x509_privkey_export2_pkcs8(tkey, GNUTLS_X509_FMT_PEM, NULL, 0, &tmp); - gnutls_x509_privkey_deinit(tkey); - gnutls_privkey_deinit(pkey); + /* import RSA-PSS version of key */ + assert(gnutls_privkey_init(&pkey_rsa_pss) >=0); + assert(gnutls_privkey_import_x509_raw(pkey_rsa_pss, &tmp, GNUTLS_X509_FMT_PEM, NULL, 0) >= 0); - assert(gnutls_privkey_init(&pkey) >=0); + gnutls_free(tmp.data); - assert(gnutls_privkey_import_x509_raw(pkey, &tmp, GNUTLS_X509_FMT_PEM, NULL, 0) >= 0); + /* import RSA-PSS version of key */ + gnutls_privkey_deinit(pkey_rsa); + gnutls_x509_privkey_export2(tkey, GNUTLS_X509_FMT_PEM, &tmp); + assert(gnutls_privkey_init(&pkey_rsa) >=0); + assert(gnutls_privkey_import_x509_raw(pkey_rsa, &tmp, GNUTLS_X509_FMT_PEM, NULL, 0) >= 0); - if (debug) - printf("%s", tmp.data); + gnutls_x509_privkey_deinit(tkey); + gnutls_free(tmp.data); - sign_verify_data(GNUTLS_PK_RSA_PSS, GNUTLS_SIGN_RSA_PSS_SHA256, pkey); + sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa_pss); + sign_verify_data(GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, pkey_rsa); + sign_verify_data(GNUTLS_SIGN_RSA_PSS_SHA256, pkey_rsa); if (debug) success("success signing with RSA-PSS-SHA256\n"); - /* check whether the RSA-PSS restrictions are being followed */ - inv_encryption_check(GNUTLS_PK_RSA_PSS, pkey, GNUTLS_E_INVALID_REQUEST); - inv_sign_check(GNUTLS_PK_RSA, GNUTLS_SIGN_RSA_SHA512, pkey, GNUTLS_E_CONSTRAINT_ERROR); - inv_sign_check(GNUTLS_PK_RSA, GNUTLS_SIGN_RSA_SHA256, pkey, GNUTLS_E_CONSTRAINT_ERROR); - inv_sign_check(GNUTLS_PK_RSA_PSS, GNUTLS_SIGN_RSA_PSS_SHA384, pkey, GNUTLS_E_CONSTRAINT_ERROR); - inv_sign_check(GNUTLS_PK_RSA_PSS, GNUTLS_SIGN_RSA_PSS_SHA512, pkey, GNUTLS_E_CONSTRAINT_ERROR); - - gnutls_privkey_deinit(pkey); + /* check whether the RSA-PSS key restrictions are being followed */ + inv_encryption_check(GNUTLS_PK_RSA_PSS, pkey_rsa_pss, GNUTLS_E_INVALID_REQUEST); + inv_sign_check(GNUTLS_SIGN_RSA_SHA512, pkey_rsa_pss, GNUTLS_E_CONSTRAINT_ERROR); + inv_sign_check(GNUTLS_SIGN_RSA_SHA256, pkey_rsa_pss, GNUTLS_E_CONSTRAINT_ERROR); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_SHA384, pkey_rsa_pss, GNUTLS_E_CONSTRAINT_ERROR); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_SHA512, pkey_rsa_pss, GNUTLS_E_CONSTRAINT_ERROR); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_RSAE_SHA384, pkey_rsa_pss, GNUTLS_E_CONSTRAINT_ERROR); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_RSAE_SHA512, pkey_rsa_pss, GNUTLS_E_CONSTRAINT_ERROR); + + /* check whether the RSA key is not being restricted */ + inv_sign_check(GNUTLS_SIGN_RSA_SHA512, pkey_rsa, 0); + inv_sign_check(GNUTLS_SIGN_RSA_SHA256, pkey_rsa, 0); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_RSAE_SHA384, pkey_rsa, 0); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_RSAE_SHA512, pkey_rsa, 0); + /* an RSA key can also generate "pure" for TLS RSA-PSS signatures + * as they are essentially the same thing, and we cannot always + * know whether a key is RSA-PSS only, or not (e.g., in PKCS#11 + * keys). */ + inv_sign_check(GNUTLS_SIGN_RSA_PSS_SHA384, pkey_rsa, 0); + inv_sign_check(GNUTLS_SIGN_RSA_PSS_SHA512, pkey_rsa, 0); + + gnutls_privkey_deinit(pkey_rsa); + gnutls_privkey_deinit(pkey_rsa_pss); gnutls_x509_spki_deinit(spki); - gnutls_free(tmp.data); gnutls_global_deinit(); } diff --git a/tests/suite/tls-fuzzer/gnutls-cert.json b/tests/suite/tls-fuzzer/gnutls-cert.json index 8da7a50a06..69b7812f72 100644 --- a/tests/suite/tls-fuzzer/gnutls-cert.json +++ b/tests/suite/tls-fuzzer/gnutls-cert.json @@ -30,10 +30,11 @@ "-e", "check sigalgs in cert request"] }, {"name" : "test-rsa-pss-sigs-on-certificate-verify.py", - "comment" : "tlsfuzzer doesn't like our set of algorithms", + "comment" : "tlsfuzzer doesn't yet support draft-22 RSA-PSS", "arguments" : ["-k", "tests/clientX509Key.pem", "-c", "tests/clientX509Cert.pem", - "-e", "check CertificateRequest sigalgs"] + "-e", "check CertificateRequest sigalgs"], + "exp_pass" : false }, {"name": "test-certificate-malformed.py", "comment" : "tlsfuzzer doesn't like the alerts we send", diff --git a/tests/suite/tls-fuzzer/gnutls-nocert.json b/tests/suite/tls-fuzzer/gnutls-nocert.json index db9ec67844..3c156d316d 100644 --- a/tests/suite/tls-fuzzer/gnutls-nocert.json +++ b/tests/suite/tls-fuzzer/gnutls-nocert.json @@ -134,9 +134,11 @@ "-e", "medium, maximum fragmentation: 1 fragment - 1024B extension"]}, {"name" : "test-sessionID-resumption.py"}, {"name" : "test-sig-algs.py", - "comment" : "FIXME: these fail, but most likely due to tls-fuzzer issue", + "comment" : "tlsfuzzer doesn't yet support draft-22 RSA-PSS", "arguments" : ["-e", "RSA-PSS only - fails in verify if server selects PSS", - "-e", "with RSA-PSS - fails in verify if server selects PSS"]}, + "-e", "with RSA-PSS - fails in verify if server selects PSS"], + "exp_pass" : false + }, {"name" : "test-signature-algorithms.py", "comment" : "gnutls doesn't tolerate that much", "arguments" : ["-e", "tolerance max (32764) number of methods"] diff --git a/tests/tls-neg-ext-key.c b/tests/tls-neg-ext-key.c index a02c6b0034..f8b4877a58 100644 --- a/tests/tls-neg-ext-key.c +++ b/tests/tls-neg-ext-key.c @@ -295,7 +295,7 @@ static const test_st tests[] = { }, {.name = "rsa-sign key with rsa-pss sigs prioritized", .pk = GNUTLS_PK_RSA, - .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-SHA256:+SIGN-RSA-SHA384:+SIGN-RSA-SHA512", + .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256:+SIGN-RSA-PSS-RSAE-SHA384:+SIGN-RSA-PSS-RSAE-SHA512:+SIGN-RSA-SHA256:+SIGN-RSA-SHA384:+SIGN-RSA-SHA512", .cert = &server_ca3_localhost_cert, .key = &server_ca3_key, .exp_kx = GNUTLS_KX_ECDHE_RSA @@ -308,9 +308,9 @@ static const test_st tests[] = { .exp_kx = GNUTLS_KX_ECDHE_RSA, .exp_key_err = GNUTLS_E_INVALID_REQUEST }, - {.name = "rsa-pss cert, rsa-sign key", /* we expect the server to refuse negotiating */ + {.name = "rsa-pss cert, rsa-sign key, no rsa-pss-rsae sigs", /* we expect the server to refuse negotiating */ .pk = GNUTLS_PK_RSA, - .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA", + .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-SHA256:+SIGN-RSA-SHA384:+SIGN-RSA-SHA512", .cert = &server_ca3_rsa_pss_cert, .key = &server_ca3_rsa_pss_key, .exp_kx = GNUTLS_KX_ECDHE_RSA, diff --git a/tests/tls12-cert-key-exchange.c b/tests/tls12-cert-key-exchange.c index 497c8aee3c..5a7eade47b 100644 --- a/tests/tls12-cert-key-exchange.c +++ b/tests/tls12-cert-key-exchange.c @@ -47,7 +47,7 @@ void doit(void) try("TLS 1.2 with ecdhe rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN); try_with_key("TLS 1.2 with ecdhe ecdsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_UNKNOWN, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0); - try("TLS 1.2 with ecdhe rsa-pss sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.2 with ecdhe rsa-pss sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); /* Test RSA-PSS cert/key combo issues */ try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN, @@ -59,7 +59,7 @@ void doit(void) try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and rsa-pss-sha512 first sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN, &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0); - try("TLS 1.2 with ecdhe rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.2 with ecdhe rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); try_with_key("TLS 1.2 with ecdhe rsa-pss/rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN, &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, NULL, NULL, 0); try("TLS 1.2 with rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN); @@ -71,7 +71,7 @@ void doit(void) try_cli("TLS 1.2 with rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_RSA_SHA256, USE_CERT); try_with_key("TLS 1.2 with ecdhe ecdsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_RSA_SHA256, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT); - try_cli("TLS 1.2 with ecdhe-rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, USE_CERT); + try_cli("TLS 1.2 with ecdhe-rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, USE_CERT); try_with_key("TLS 1.2 with ecdhe-rsa-pss/rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT); diff --git a/tests/tls13-cert-key-exchange.c b/tests/tls13-cert-key-exchange.c index ca1b205c50..91e73cba77 100644 --- a/tests/tls13-cert-key-exchange.c +++ b/tests/tls13-cert-key-exchange.c @@ -40,13 +40,13 @@ void doit(void) global_init(); /* TLS 1.3 no clin cert */ - try("TLS 1.3 with ffdhe2048 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - try("TLS 1.3 with ffdhe3072 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - try("TLS 1.3 with ffdhe4096 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - try("TLS 1.3 with secp256r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - try("TLS 1.3 with secp384r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - try("TLS 1.3 with secp521r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); - try("TLS 1.3 with x25519 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with ffdhe2048 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with ffdhe3072 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with ffdhe4096 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with secp256r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with secp384r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with secp521r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); + try("TLS 1.3 with x25519 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN); try_with_key_ks("TLS 1.3 with secp256r1 ecdsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_UNKNOWN, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0, GNUTLS_GROUP_SECP256R1); @@ -69,7 +69,7 @@ void doit(void) /* client authentication */ try_with_key("TLS 1.3 with rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT); - try_with_key("TLS 1.3 with rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256, + try_with_key("TLS 1.3 with rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT); try_with_key("TLS 1.3 with ecdsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, USE_CERT); diff --git a/tests/tls13/prf.c b/tests/tls13/prf.c index 762dddc15c..69a4e63683 100644 --- a/tests/tls13/prf.c +++ b/tests/tls13/prf.c @@ -126,18 +126,20 @@ static void dump(const char *name, const uint8_t *data, unsigned data_size) } \ } +#define KEY_EXP_VALUE "\x12\xbc\xfe\x50\x17\x79\x0f\x9b\x46\xf6\x07\xe7\x33\x55\x61\xf1\x15\xd0\x4e\xca\x99\xd6\xad\xa3\xcc\x67\xbf\xf1\x7c\x6c\x4c\xa8\x85\xd9" +#define HELLO_VALUE "\xa6\x60\x26\xeb\xf9\x53\x05\xb4\x7c\x43\x32\x92\xce\x1f\xe5\x0e\x02\xfd\x57\x04\x5c\x06\x45\x9f\x78\x61\xad\xb8\x74\x9f\xfc" static void check_prfs(gnutls_session_t session) { unsigned char key_material[512]; int ret; - TRY_OLD(13, "key expansion", 34, (uint8_t*)"\xac\x43\xa8\x49\x8f\x36\x3b\xbd\xcb\x3f\x45\x20\xac\xd5\x99\xf5\x4c\x92\x2a\x4d\xd6\x0b\xc2\x3f\xc2\xfe\xf3\xc7\x9e\x04\x70\xd3\xe1\x92"); - TRY_OLD(6, "hello", 31, (uint8_t*)"\x49\x74\x07\x6f\x2c\xed\xfa\xff\xda\xe8\x20\x1f\xc7\xce\xe7\x78\x66\xb9\x75\x3f\x5d\x6e\xb0\xa9\xb8\xb2\x46\xd1\xa1\xd6\x39"); + TRY_OLD(13, "key expansion", 34, (uint8_t*)KEY_EXP_VALUE); + TRY_OLD(6, "hello", 31, (uint8_t*)HELLO_VALUE); - TRY(13, "key expansion", 0, NULL, 34, (uint8_t*)"\xac\x43\xa8\x49\x8f\x36\x3b\xbd\xcb\x3f\x45\x20\xac\xd5\x99\xf5\x4c\x92\x2a\x4d\xd6\x0b\xc2\x3f\xc2\xfe\xf3\xc7\x9e\x04\x70\xd3\xe1\x92"); - TRY(6, "hello", 0, NULL, 31, (uint8_t*)"\x49\x74\x07\x6f\x2c\xed\xfa\xff\xda\xe8\x20\x1f\xc7\xce\xe7\x78\x66\xb9\x75\x3f\x5d\x6e\xb0\xa9\xb8\xb2\x46\xd1\xa1\xd6\x39"); - TRY(7, "context", 5, "abcd\xfa", 31, (uint8_t*)"\x0a\xa9\x28\xc7\x00\xf9\x49\xe8\x5a\xd0\xb8\x68\xba\x49\xd6\x04\x78\x61\x0b\xac\x45\xe3\xfb\x9c\x82\x94\x23\x24\xa4\x02\x8e"); - TRY(12, "null-context", 0, "", 31, (uint8_t*)"\xb1\xfa\x57\x28\x1a\x57\x20\xfd\x73\xed\xdd\xda\xf4\xf8\x9b\xec\x4d\xf5\x2d\x23\xd5\xe3\xd3\x77\x89\xeb\x54\xdd\x0e\x17\x49"); + TRY(13, "key expansion", 0, NULL, 34, (uint8_t*)KEY_EXP_VALUE); + TRY(6, "hello", 0, NULL, 31, (uint8_t*)HELLO_VALUE); + TRY(7, "context", 5, "abcd\xfa", 31, (uint8_t*)"\x1a\x7e\xc4\x88\x85\x6b\x93\x4e\x20\x7d\x82\xd3\xd9\xe6\xb8\xf9\x88\x22\x3e\x49\xb3\x1b\x3d\xd6\xd8\xaa\x9c\xb6\xb6\x9e\x09"); + TRY(12, "null-context", 0, "", 31, (uint8_t*)"\x2e\x7e\xbd\x18\x3d\x69\xd6\x2f\x03\xad\x40\xdc\x8d\x7a\x60\xc2\xfb\x35\xa4\x26\xd0\x02\x19\xb2\x12\x8b\x03\x1e\x58\x09\x0e"); /* Try whether calling gnutls_prf() with non-null context or server-first * param, will fail */ @@ -173,7 +175,7 @@ static void client(int fd) /* Use default priorities */ ret = gnutls_priority_set_direct(session, - "NONE:+VERS-TLS1.3:+AES-256-GCM:+AEAD:+SIGN-RSA-PSS-SHA384:+GROUP-SECP256R1", + "NONE:+VERS-TLS1.3:+AES-256-GCM:+AEAD:+SIGN-RSA-PSS-RSAE-SHA384:+GROUP-SECP256R1", &err); if (ret < 0) { fail("client: priority set failed (%s): %s\n", @@ -266,7 +268,7 @@ static void server(int fd) * are adequate. */ ret = gnutls_priority_set_direct(session, - "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL", NULL); + "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA384:-GROUP-ALL:+GROUP-SECP256R1", NULL); if (ret < 0) { fail("server: priority set failed (%s)\n\n", gnutls_strerror(ret)); |