/* Hashes input data and verifies a DSA signature. */ static int dsa_verify_sig (const gnutls_datum_t * text, const gnutls_datum_t * hash, const gnutls_datum_t * signature, bigint_t * params, int params_len) { int ret; opaque _digest[MAX_HASH_SIZE]; gnutls_datum_t digest; digest_hd_st hd; if (hash && hash->data && hash->size == 20) { digest = *hash; } else { ret = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_hash (&hd, text->data, text->size); _gnutls_hash_deinit (&hd, _digest); digest.data = _digest; digest.size = 20; } ret = _gnutls_dsa_verify (&digest, signature, params, params_len); return ret; }
/* Hashes input data and verifies a DSA signature. */ static int dsa_verify_sig (const gnutls_datum_t * text, const gnutls_datum_t * hash, const gnutls_datum_t * signature, bigint_t * params, int params_len) { int ret; opaque _digest[MAX_HASH_SIZE]; gnutls_datum_t digest; digest_hd_st hd; gnutls_digest_algorithm_t algo; unsigned int hash_len; algo = _gnutls_dsa_q_to_hash (params[1], &hash_len); if (hash) { /* SHA1 or better allowed */ if (!hash->data || hash->size < hash_len) { gnutls_assert(); _gnutls_debug_log("Hash size (%d) does not correspond to hash %s", (int)hash->size, gnutls_mac_get_name(algo)); if (hash->size != 20) return GNUTLS_E_PK_SIG_VERIFY_FAILED; } digest = *hash; } else { ret = _gnutls_hash_init (&hd, algo); if (ret < 0) { gnutls_assert (); return ret; } _gnutls_hash (&hd, text->data, text->size); _gnutls_hash_deinit (&hd, _digest); digest.data = _digest; digest.size = _gnutls_hash_get_algo_len(algo); } ret = _gnutls_dsa_verify (&digest, signature, params, params_len); return ret; }
static int _gnutls_verify_sig (gnutls_cert * cert, const gnutls_datum_t * hash_concat, gnutls_datum_t * signature, size_t sha1pos) { int ret; gnutls_datum_t vdata; if (cert->version == 0 || cert == NULL) { /* this is the only way to check * if it is initialized */ gnutls_assert (); return GNUTLS_E_CERTIFICATE_ERROR; } /* If the certificate supports signing continue. */ if (cert != NULL) if (cert->key_usage != 0) if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE)) { gnutls_assert (); return GNUTLS_E_KEY_USAGE_VIOLATION; } switch (cert->subject_pk_algorithm) { case GNUTLS_PK_RSA: vdata.data = hash_concat->data; vdata.size = hash_concat->size; /* verify signature */ if ((ret = _gnutls_rsa_verify (&vdata, signature, cert->params, cert->params_size, 1)) < 0) { gnutls_assert (); return ret; } break; case GNUTLS_PK_DSA: vdata.data = &hash_concat->data[sha1pos]; vdata.size = 20; /* sha1 */ /* verify signature */ if ((ret = _gnutls_dsa_verify (&vdata, signature, cert->params, cert->params_size)) < 0) { gnutls_assert (); return ret; } break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } return 0; }