summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-09-01 19:07:18 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-09-01 19:08:46 +0200
commit56f982b0247219569ebe962bec68f0dbd5c19cfd (patch)
tree5b6885d754660737a313114e4b2afd23e640d94a
parentd178911375a37f9ed087c624c5bc601c3f655cc6 (diff)
downloadgnutls-56f982b0247219569ebe962bec68f0dbd5c19cfd.tar.gz
Be tolerant is ECDSA-violating signatures.
-rw-r--r--lib/abstract_int.h4
-rw-r--r--lib/ext/signature.c2
-rw-r--r--lib/gnutls_pubkey.c22
-rw-r--r--lib/gnutls_sig.c4
4 files changed, 20 insertions, 12 deletions
diff --git a/lib/abstract_int.h b/lib/abstract_int.h
index c01e9834f7..9b1de33fe6 100644
--- a/lib/abstract_int.h
+++ b/lib/abstract_int.h
@@ -79,8 +79,8 @@ int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
gnutls_pk_params_st*);
int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params);
-int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t ver,
- gnutls_sign_algorithm_t sign);
+int _gnutls_pubkey_compatible_with_sig(gnutls_session_t, gnutls_pubkey_t pubkey,
+ gnutls_protocol_t ver, gnutls_sign_algorithm_t sign);
int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey);
int
_gnutls_pubkey_get_mpis (gnutls_pubkey_t key,
diff --git a/lib/ext/signature.c b/lib/ext/signature.c
index 59e3750c10..d8a6bccac0 100644
--- a/lib/ext/signature.c
+++ b/lib/ext/signature.c
@@ -272,7 +272,7 @@ _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_pcert_st* cert)
{
if (gnutls_sign_get_pk_algorithm (priv->sign_algorithms[i]) == cert_algo)
{
- if (_gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, priv->sign_algorithms[i]) < 0)
+ if (_gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, priv->sign_algorithms[i]) < 0)
continue;
if (_gnutls_session_sign_algo_enabled(session, priv->sign_algorithms[i]) < 0)
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index b894677e42..58c41398bd 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -1545,12 +1545,18 @@ gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
}
-
-int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t ver,
- gnutls_sign_algorithm_t sign)
+/* Checks whether the public key given is compatible with the
+ * signature algorithm used. The session is only used for audit logging, and
+ * it may be null.
+ */
+int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
+ gnutls_pubkey_t pubkey,
+ gnutls_protocol_t ver,
+ gnutls_sign_algorithm_t sign)
{
unsigned int hash_size;
unsigned int hash_algo;
+unsigned int sig_hash_size;
if (pubkey->pk_algorithm == GNUTLS_PK_DSA)
{
@@ -1564,8 +1570,9 @@ unsigned int hash_algo;
}
else if (sign != GNUTLS_SIGN_UNKNOWN)
{
- if (_gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign)) < hash_size)
- return GNUTLS_E_UNWANTED_ALGORITHM;
+ sig_hash_size = _gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign));
+ if (sig_hash_size < hash_size)
+ _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
}
}
@@ -1574,9 +1581,10 @@ unsigned int hash_algo;
if (_gnutls_version_has_selectable_sighash (ver) && sign != GNUTLS_SIGN_UNKNOWN)
{
hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, &pubkey->params, &hash_size);
+ sig_hash_size = _gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign));
- if (_gnutls_hash_get_algo_len(gnutls_sign_get_hash_algorithm(sign)) < hash_size)
- return GNUTLS_E_UNWANTED_ALGORITHM;
+ if (sig_hash_size < hash_size)
+ _gnutls_audit_log(session, "The hash size used in signature (%u) is less than the expected (%u)\n", sig_hash_size, hash_size);
}
}
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 6b5386a3c6..256ca1c923 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -320,7 +320,7 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert,
_gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
session, gnutls_sign_algorithm_get_name (sign_algo));
- ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, sign_algo);
+ ret = _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, sign_algo);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -639,7 +639,7 @@ _gnutls_handshake_sign_crt_vrfy (gnutls_session_t session,
_gnutls_hash_deinit (&td_sha, &concat[16]);
/* ensure 1024 bit DSA keys are used */
- ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, GNUTLS_SIGN_UNKNOWN);
+ ret = _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, GNUTLS_SIGN_UNKNOWN);
if (ret < 0)
return gnutls_assert_val(ret);