summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-11-08 17:57:01 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-11-08 17:57:43 +0100
commit3a7a9116a5ac1dd8fdb45ab90b6f86e6fcd10bb8 (patch)
treefc21573b88350d924d2e904caf837955e0a75d93 /lib
parent1dcfd44d38b1bacde16ae5d8bd66c33619e27603 (diff)
downloadgnutls-3a7a9116a5ac1dd8fdb45ab90b6f86e6fcd10bb8.tar.gz
Allow easier marking of insecure algorithms.
Diffstat (limited to 'lib')
-rw-r--r--lib/algorithms.h1
-rw-r--r--lib/algorithms/mac.c34
-rw-r--r--lib/algorithms/sign.c53
-rw-r--r--lib/includes/gnutls/gnutls.h.in2
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/verify-tofu.c2
-rw-r--r--lib/x509/ocsp_output.c2
-rw-r--r--lib/x509/output.c6
-rw-r--r--lib/x509/verify.c15
9 files changed, 80 insertions, 36 deletions
diff --git a/lib/algorithms.h b/lib/algorithms.h
index a11a2a2bff..3ee2032aa6 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -56,6 +56,7 @@ const char *_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t mac);
/* Functions for digests. */
const char *_gnutls_x509_digest_to_oid (gnutls_digest_algorithm_t algorithm);
const char *_gnutls_digest_get_name (gnutls_digest_algorithm_t algorithm);
+int _gnutls_digest_is_secure (gnutls_digest_algorithm_t algorithm);
/* Functions for cipher suites. */
int _gnutls_supported_ciphersuites (gnutls_session_t session,
diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c
index ad7d57c582..bcaffb8a05 100644
--- a/lib/algorithms/mac.c
+++ b/lib/algorithms/mac.c
@@ -32,21 +32,22 @@ struct gnutls_hash_entry
gnutls_mac_algorithm_t id;
size_t key_size; /* in case of mac */
unsigned placeholder; /* if set, then not a real MAC */
+ unsigned secure; /* if set the this algorithm is secure as hash */
};
typedef struct gnutls_hash_entry gnutls_hash_entry;
static const gnutls_hash_entry hash_algorithms[] = {
- {"SHA1", HASH_OID_SHA1, GNUTLS_MAC_SHA1, 20, 0},
- {"MD5", HASH_OID_MD5, GNUTLS_MAC_MD5, 16, 0},
- {"SHA256", HASH_OID_SHA256, GNUTLS_MAC_SHA256, 32, 0},
- {"SHA384", HASH_OID_SHA384, GNUTLS_MAC_SHA384, 48, 0},
- {"SHA512", HASH_OID_SHA512, GNUTLS_MAC_SHA512, 64, 0},
- {"SHA224", HASH_OID_SHA224, GNUTLS_MAC_SHA224, 28, 0},
- {"AEAD", NULL, GNUTLS_MAC_AEAD, 0, 1},
- {"MD2", HASH_OID_MD2, GNUTLS_MAC_MD2, 0, 0}, /* not used as MAC */
- {"RIPEMD160", HASH_OID_RMD160, GNUTLS_MAC_RMD160, 20, 0},
- {"MAC-NULL", NULL, GNUTLS_MAC_NULL, 0, 0},
- {0, 0, 0, 0}
+ {"SHA1", HASH_OID_SHA1, GNUTLS_MAC_SHA1, 20, 0, 1},
+ {"MD5", HASH_OID_MD5, GNUTLS_MAC_MD5, 16, 0, 0},
+ {"SHA256", HASH_OID_SHA256, GNUTLS_MAC_SHA256, 32, 0, 1},
+ {"SHA384", HASH_OID_SHA384, GNUTLS_MAC_SHA384, 48, 0, 1},
+ {"SHA512", HASH_OID_SHA512, GNUTLS_MAC_SHA512, 64, 0, 1},
+ {"SHA224", HASH_OID_SHA224, GNUTLS_MAC_SHA224, 28, 0, 1},
+ {"AEAD", NULL, GNUTLS_MAC_AEAD, 0, 1, 1},
+ {"MD2", HASH_OID_MD2, GNUTLS_MAC_MD2, 0, 0, 0}, /* not used as MAC */
+ {"RIPEMD160", HASH_OID_RMD160, GNUTLS_MAC_RMD160, 20, 0, 1},
+ {"MAC-NULL", NULL, GNUTLS_MAC_NULL, 0, 0, 0},
+ {0, 0, 0, 0, 0}
};
@@ -219,3 +220,14 @@ _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm)
ret = 1;
return ret;
}
+
+int
+_gnutls_digest_is_secure (gnutls_digest_algorithm_t algo)
+{
+ ssize_t ret = 0;
+ gnutls_mac_algorithm_t algorithm = algo;
+
+ GNUTLS_HASH_ALG_LOOP (ret = p->secure);
+
+ return ret;
+}
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index 316392ff84..823846664d 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -45,32 +45,32 @@ static const sign_algorithm_st unknown_tls_aid = TLS_SIGN_AID_UNKNOWN;
static const gnutls_sign_entry sign_algorithms[] = {
{"RSA-SHA1", SIG_RSA_SHA1_OID, GNUTLS_SIGN_RSA_SHA1, GNUTLS_PK_RSA,
- GNUTLS_MAC_SHA1, {2, 1}},
+ GNUTLS_DIG_SHA1, {2, 1}},
{"RSA-SHA224", SIG_RSA_SHA224_OID, GNUTLS_SIGN_RSA_SHA224, GNUTLS_PK_RSA,
- GNUTLS_MAC_SHA224, {3, 1}},
+ GNUTLS_DIG_SHA224, {3, 1}},
{"RSA-SHA256", SIG_RSA_SHA256_OID, GNUTLS_SIGN_RSA_SHA256, GNUTLS_PK_RSA,
- GNUTLS_MAC_SHA256, {4, 1}},
+ GNUTLS_DIG_SHA256, {4, 1}},
{"RSA-SHA384", SIG_RSA_SHA384_OID, GNUTLS_SIGN_RSA_SHA384, GNUTLS_PK_RSA,
- GNUTLS_MAC_SHA384, {5, 1}},
+ GNUTLS_DIG_SHA384, {5, 1}},
{"RSA-SHA512", SIG_RSA_SHA512_OID, GNUTLS_SIGN_RSA_SHA512, GNUTLS_PK_RSA,
- GNUTLS_MAC_SHA512, {6, 1}},
+ GNUTLS_DIG_SHA512, {6, 1}},
{"RSA-RMD160", SIG_RSA_RMD160_OID, GNUTLS_SIGN_RSA_RMD160, GNUTLS_PK_RSA,
- GNUTLS_MAC_RMD160, TLS_SIGN_AID_UNKNOWN},
+ GNUTLS_DIG_RMD160, TLS_SIGN_AID_UNKNOWN},
{"DSA-SHA1", SIG_DSA_SHA1_OID, GNUTLS_SIGN_DSA_SHA1, GNUTLS_PK_DSA,
- GNUTLS_MAC_SHA1, {2, 2}},
+ GNUTLS_DIG_SHA1, {2, 2}},
{"DSA-SHA224", SIG_DSA_SHA224_OID, GNUTLS_SIGN_DSA_SHA224, GNUTLS_PK_DSA,
- GNUTLS_MAC_SHA224, {3, 2}},
+ GNUTLS_DIG_SHA224, {3, 2}},
{"DSA-SHA256", SIG_DSA_SHA256_OID, GNUTLS_SIGN_DSA_SHA256, GNUTLS_PK_DSA,
- GNUTLS_MAC_SHA256, {4, 2}},
+ GNUTLS_DIG_SHA256, {4, 2}},
{"RSA-MD5", SIG_RSA_MD5_OID, GNUTLS_SIGN_RSA_MD5, GNUTLS_PK_RSA,
- GNUTLS_MAC_MD5, {1, 1}},
+ GNUTLS_DIG_MD5, {1, 1}},
{"RSA-MD2", SIG_RSA_MD2_OID, GNUTLS_SIGN_RSA_MD2, GNUTLS_PK_RSA,
- GNUTLS_MAC_MD2, TLS_SIGN_AID_UNKNOWN},
- {"ECDSA-SHA1", "1.2.840.10045.4.1", GNUTLS_SIGN_ECDSA_SHA1, GNUTLS_PK_EC, GNUTLS_MAC_SHA1, {2, 3}},
- {"ECDSA-SHA224", "1.2.840.10045.4.3.1", GNUTLS_SIGN_ECDSA_SHA224, GNUTLS_PK_EC, GNUTLS_MAC_SHA224, {3, 3}},
- {"ECDSA-SHA256", "1.2.840.10045.4.3.2", GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_PK_EC, GNUTLS_MAC_SHA256, {4, 3}},
- {"ECDSA-SHA384", "1.2.840.10045.4.3.3", GNUTLS_SIGN_ECDSA_SHA384, GNUTLS_PK_EC, GNUTLS_MAC_SHA384, {5, 3}},
- {"ECDSA-SHA512", "1.2.840.10045.4.3.4", GNUTLS_SIGN_ECDSA_SHA512, GNUTLS_PK_EC, GNUTLS_MAC_SHA512, {6, 3}},
+ GNUTLS_DIG_MD2, TLS_SIGN_AID_UNKNOWN},
+ {"ECDSA-SHA1", "1.2.840.10045.4.1", GNUTLS_SIGN_ECDSA_SHA1, GNUTLS_PK_EC, GNUTLS_DIG_SHA1, {2, 3}},
+ {"ECDSA-SHA224", "1.2.840.10045.4.3.1", GNUTLS_SIGN_ECDSA_SHA224, GNUTLS_PK_EC, GNUTLS_DIG_SHA224, {3, 3}},
+ {"ECDSA-SHA256", "1.2.840.10045.4.3.2", GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_PK_EC, GNUTLS_DIG_SHA256, {4, 3}},
+ {"ECDSA-SHA384", "1.2.840.10045.4.3.3", GNUTLS_SIGN_ECDSA_SHA384, GNUTLS_PK_EC, GNUTLS_DIG_SHA384, {5, 3}},
+ {"ECDSA-SHA512", "1.2.840.10045.4.3.4", GNUTLS_SIGN_ECDSA_SHA512, GNUTLS_PK_EC, GNUTLS_DIG_SHA512, {6, 3}},
{"GOST R 34.10-2001", SIG_GOST_R3410_2001_OID, 0, 0, 0,
TLS_SIGN_AID_UNKNOWN},
{"GOST R 34.10-94", SIG_GOST_R3410_94_OID, 0, 0, 0, TLS_SIGN_AID_UNKNOWN},
@@ -108,6 +108,27 @@ gnutls_sign_get_name (gnutls_sign_algorithm_t algorithm)
}
/**
+ * gnutls_sign_is_secure:
+ * @algorithm: is a sign algorithm
+ *
+ * Returns: Non-zero if the provided signature algorithm is considered to be secure.
+ **/
+int
+gnutls_sign_is_secure (gnutls_sign_algorithm_t algorithm)
+{
+ gnutls_sign_algorithm_t sign = algorithm;
+ gnutls_digest_algorithm_t dig = GNUTLS_DIG_UNKNOWN;
+
+ /* avoid prefix */
+ GNUTLS_SIGN_ALG_LOOP (dig = p->mac);
+
+ if (dig != GNUTLS_DIG_UNKNOWN)
+ return _gnutls_digest_is_secure(dig);
+
+ return 0;
+}
+
+/**
* gnutls_sign_list:
*
* Get a list of supported public key signature algorithms.
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 800323fc7c..0a07565fb2 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -819,6 +819,8 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
type);
const char *gnutls_pk_get_name (gnutls_pk_algorithm_t algorithm);
const char *gnutls_sign_get_name (gnutls_sign_algorithm_t algorithm);
+
+ int gnutls_sign_is_secure (gnutls_sign_algorithm_t algorithm);
gnutls_digest_algorithm_t
gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t sign);
gnutls_pk_algorithm_t
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 201bdda3e4..a8c1c080fc 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -869,6 +869,7 @@ GNUTLS_3_1_0 {
gnutls_srtp_get_mki;
gnutls_srtp_set_mki;
gnutls_ocsp_status_request_is_checked;
+ gnutls_sign_is_secure;
} GNUTLS_3_0_0;
GNUTLS_PRIVATE {
diff --git a/lib/verify-tofu.c b/lib/verify-tofu.c
index d97d43d7ea..3592395803 100644
--- a/lib/verify-tofu.c
+++ b/lib/verify-tofu.c
@@ -700,7 +700,7 @@ FILE* fd = NULL;
int ret;
char local_file[MAX_FILENAME];
- if (hash_algo == GNUTLS_DIG_MD5 || hash_algo == GNUTLS_DIG_MD2)
+ if (_gnutls_digest_is_secure(hash_algo) == 0)
return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
if (_gnutls_hash_get_algo_len(hash_algo) != hash->size)
diff --git a/lib/x509/ocsp_output.c b/lib/x509/ocsp_output.c
index 6b60872a14..853404fd6f 100644
--- a/lib/x509/ocsp_output.c
+++ b/lib/x509/ocsp_output.c
@@ -513,7 +513,7 @@ print_resp (gnutls_buffer_st * str, gnutls_ocsp_resp_t resp,
name = _("unknown");
addf (str, _("\tSignature Algorithm: %s\n"), name);
}
- if (ret == GNUTLS_SIGN_RSA_MD5 || ret == GNUTLS_SIGN_RSA_MD2)
+ if (gnutls_sign_is_secure(ret) == 0)
{
adds (str, _("warning: signed using a broken signature "
"algorithm that can be forged.\n"));
diff --git a/lib/x509/output.c b/lib/x509/output.c
index c2f0cb42e8..18db408204 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -1420,7 +1420,7 @@ print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
name = _("unknown");
addf (str, _("\tSignature Algorithm: %s\n"), name);
}
- if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
+ if (gnutls_sign_is_secure(err) == 0)
{
adds (str, _("warning: signed using a broken signature "
"algorithm that can be forged.\n"));
@@ -1608,7 +1608,7 @@ print_oneline (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
const char *name = gnutls_sign_algorithm_get_name (err);
if (name == NULL)
name = _("unknown");
- if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
+ if (gnutls_sign_is_secure(err) == 0)
addf (str, _("signed using %s (broken!), "), name);
else
addf (str, _("signed using %s, "), name);
@@ -2037,7 +2037,7 @@ print_crl (gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
name = _("unknown");
addf (str, _("\tSignature Algorithm: %s\n"), name);
}
- if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
+ if (gnutls_sign_is_secure(err) == 0)
{
adds (str, _("warning: signed using a broken signature "
"algorithm that can be forged.\n"));
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 636ae0e27e..ef36fe52aa 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -387,6 +387,16 @@ check_time (gnutls_x509_crt_t crt, time_t now)
return 0;
}
+static
+int is_broken_allowed( gnutls_sign_algorithm_t sig, unsigned int flags)
+{
+ if ((sig == GNUTLS_SIGN_RSA_MD2) && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2))
+ return 1;
+ if ((sig == GNUTLS_SIGN_RSA_MD5) && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5))
+ return 1;
+ return 0;
+}
+
/*
* Verifies the given certificate again a certificate list of
* trusted CAs.
@@ -538,10 +548,7 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
- if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
- !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
- ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
- !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
+ if (gnutls_sign_is_secure(sigalg) == 0 && is_broken_allowed(sigalg, flags) == 0)
{
out = GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
if (output)