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 ();
_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,
}
}
+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,
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);
{
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.