summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/algorithms.h34
-rw-r--r--lib/algorithms/sign.c60
-rw-r--r--lib/ext/signature.c23
-rw-r--r--lib/includes/gnutls/gnutls.h.in24
-rw-r--r--lib/priority.c8
-rw-r--r--lib/privkey.c17
-rw-r--r--lib/pubkey.c8
-rw-r--r--lib/tls-sig.c9
-rw-r--r--lib/tls13-sig.c17
9 files changed, 155 insertions, 45 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, &params);
@@ -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, &params);
if (ret < 0) {
gnutls_assert();
return ret;
}
- return privkey_sign_and_hash_data(signer, _gnutls_sign_to_entry(algo), data, signature, &params);
+ return privkey_sign_and_hash_data(signer, se, data, signature, &params);
}
/**
@@ -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