From: Nikos Mavrogiannopoulos Date: Tue, 25 May 2010 12:22:35 +0000 (+0200) Subject: Use correct hashing algorithms for DSA with q over 160 bits. X-Git-Tag: gnutls_2_9_11~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b468facbe64978a471e8b6f52cc667ed2e5e5976;p=thirdparty%2Fgnutls.git Use correct hashing algorithms for DSA with q over 160 bits. --- diff --git a/lib/x509/common.h b/lib/x509/common.h index 46b9fcd9ca..a2a94fea54 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -128,4 +128,6 @@ int _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name, int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name, gnutls_datum_t * signature); +gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash(bigint_t q); + #endif diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index ce50da2a9e..f49380478b 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -1468,7 +1468,7 @@ cleanup: /** * gnutls_x509_privkey_sign_data: * @key: Holds the key - * @digest: should be MD5 or SHA1 + * @digest: should be MD5 or SHAx. May be ignored. * @flags: should be 0 for now * @data: holds the data to be signed * @signature: will contain the signature diff --git a/lib/x509/sign.c b/lib/x509/sign.c index 1c5739fa26..e74c48f00e 100644 --- a/lib/x509/sign.c +++ b/lib/x509/sign.c @@ -180,8 +180,9 @@ dsa_sign (const gnutls_datum_t * text, opaque _digest[MAX_HASH_SIZE]; digest_hd_st hd; gnutls_datum_t digest; + gnutls_digest_algorithm_t hash = _gnutls_dsa_q_to_hash(params[1]); - ret = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1); + ret = _gnutls_hash_init (&hd, hash); if (ret < 0) { gnutls_assert (); @@ -192,7 +193,7 @@ dsa_sign (const gnutls_datum_t * text, _gnutls_hash_deinit (&hd, _digest); digest.data = _digest; - digest.size = 20; + digest.size = _gnutls_hash_get_algo_len(hash); if ((ret = _gnutls_sign (GNUTLS_PK_DSA, params, params_len, &digest, diff --git a/lib/x509/verify.c b/lib/x509/verify.c index 33aef9461e..8ef697b16d 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -839,6 +839,19 @@ verify_sig (const gnutls_datum_t * tbs, } } +gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash(bigint_t q) +{ + int bits = _gnutls_mpi_get_nbits(q); + + if (bits <= 160) { + return GNUTLS_DIG_SHA1; + } else if (bits <= 224) { + return GNUTLS_DIG_SHA224; + } else { + return GNUTLS_DIG_SHA256; + } +} + int _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, const gnutls_datum_t * signature, @@ -851,38 +864,37 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, int digest_size; int ret, i; + issuer_params_size = MAX_PUBLIC_PARAMS_SIZE; + ret = + _gnutls_x509_crt_get_mpis (issuer, issuer_params, + &issuer_params_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + switch (gnutls_x509_crt_get_pk_algorithm (issuer, NULL)) { case GNUTLS_PK_DSA: + if (hash) - *hash = GNUTLS_MAC_SHA1; - return 0; + *hash = _gnutls_dsa_q_to_hash(issuer_params[1]); + + ret = 0; + break; case GNUTLS_PK_RSA: - issuer_params_size = MAX_PUBLIC_PARAMS_SIZE; - ret = - _gnutls_x509_crt_get_mpis (issuer, issuer_params, - &issuer_params_size); - if (ret < 0) - { - gnutls_assert (); - return ret; - } ret = _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, issuer_params, issuer_params_size, 1); - /* release allocated mpis */ - for (i = 0; i < issuer_params_size; i++) - { - _gnutls_mpi_release (&issuer_params[i]); - } if (ret < 0) { gnutls_assert (); - return ret; + goto cleanup; } digest_size = sizeof (digest); @@ -892,22 +904,34 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, { gnutls_assert (); _gnutls_free_datum (&decrypted); - return ret; + goto cleanup; } _gnutls_free_datum (&decrypted); if (digest_size != _gnutls_hash_get_algo_len (*hash)) { gnutls_assert (); - return GNUTLS_E_ASN1_GENERIC_ERROR; + ret = GNUTLS_E_ASN1_GENERIC_ERROR; + goto cleanup; } - return 0; + ret = 0; + break; default: gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; + ret = GNUTLS_E_INTERNAL_ERROR; + } + +cleanup: + /* release allocated mpis */ + for (i = 0; i < issuer_params_size; i++) + { + _gnutls_mpi_release (&issuer_params[i]); } + + return ret; + } /* verifies if the certificate is properly signed.