/* params is p, q, g, y in that order */ int _gnutls_dsa_verify (const gnutls_datum_t * vdata, const gnutls_datum_t * sig_value, bigint_t * params, int params_len) { int ret, i; gnutls_pk_params_st pk_params; for (i = 0; i < params_len; i++) pk_params.params[i] = params[i]; pk_params.params_nr = params_len; if (vdata->size != 20) { /* sha-1 only */ gnutls_assert (); return GNUTLS_E_PK_SIG_VERIFY_FAILED; } /* decrypt signature */ ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, &pk_params); if (ret < 0) { gnutls_assert (); return ret; } return 0; /* ok */ }
/* params is p, q, g, y in that order */ int _gnutls_dsa_verify (const gnutls_datum_t * vdata, const gnutls_datum_t * sig_value, mpi_t * params, int params_len) { mpi_t mdata; int ret; size_t k; mpi_t rs[2]; if (vdata->size != 20) { /* sha-1 only */ gnutls_assert (); return GNUTLS_E_PK_SIG_VERIFY_FAILED; } if (decode_ber_rs (sig_value, &rs[0], &rs[1]) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } k = vdata->size; if (_gnutls_mpi_scan_nz (&mdata, vdata->data, &k) != 0) { gnutls_assert (); _gnutls_mpi_release (&rs[0]); _gnutls_mpi_release (&rs[1]); return GNUTLS_E_MPI_SCAN_FAILED; } /* decrypt signature */ ret = _gnutls_pk_verify (GCRY_PK_DSA, mdata, rs, params, params_len); _gnutls_mpi_release (&mdata); _gnutls_mpi_release (&rs[0]); _gnutls_mpi_release (&rs[1]); if (ret < 0) { gnutls_assert (); return ret; } return 0; /* ok */ }
/** * cdk_pk_verify: * @pk: the public key * @sig: signature * @md: the message digest * * Verify the signature in @sig and compare it with the message digest in @md. **/ cdk_error_t cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md) { gnutls_datum_t s_sig; byte *encmd = NULL; size_t enclen; cdk_error_t rc; int ret, algo; unsigned int i; gnutls_datum_t data; gnutls_pk_params_st params; if (!pk || !sig || !md) { gnutls_assert (); return CDK_Inv_Value; } if (is_DSA (pk->pubkey_algo)) algo = GNUTLS_PK_DSA; else if (is_RSA (pk->pubkey_algo)) algo = GNUTLS_PK_RSA; else { gnutls_assert (); return CDK_Inv_Value; } rc = sig_to_datum (&s_sig, sig); if (rc) { gnutls_assert (); goto leave; } rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, pk->pubkey_algo, md, sig->digest_algo, cdk_pk_get_nbits (pk)); if (rc) { gnutls_assert (); goto leave; } data.data = encmd; data.size = enclen; params.params_nr = cdk_pk_get_npkey (pk->pubkey_algo); for (i = 0; i < params.params_nr; i++) params.params[i] = pk->mpi[i]; params.flags = 0; ret = _gnutls_pk_verify (algo, &data, &s_sig, ¶ms); if (ret < 0) { gnutls_assert (); rc = map_gnutls_error (ret); goto leave; } rc = 0; leave: _gnutls_free_datum (&s_sig); cdk_free (encmd); return rc; }
/** * cdk_pk_verify: * @pk: the public key * @sig: signature * @md: the message digest * * Verify the signature in @sig and compare it with the message digest in @md. **/ cdk_error_t cdk_pk_verify(cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md) { gnutls_datum_t s_sig = { NULL, 0 }, di = { NULL, 0}; byte *encmd = NULL; cdk_error_t rc; int ret, algo; unsigned int i; gnutls_pk_params_st params; const mac_entry_st *me; if (!pk || !sig || !md) { gnutls_assert(); return CDK_Inv_Value; } if (is_DSA(pk->pubkey_algo)) algo = GNUTLS_PK_DSA; else if (is_RSA(pk->pubkey_algo)) algo = GNUTLS_PK_RSA; else { gnutls_assert(); return CDK_Inv_Value; } rc = sig_to_datum(&s_sig, sig); if (rc) { gnutls_assert(); goto leave; } me = mac_to_entry(sig->digest_algo); rc = _gnutls_set_datum(&di, md, _gnutls_hash_get_algo_len(me)); if (rc < 0) { rc = gnutls_assert_val(CDK_Out_Of_Core); goto leave; } rc = pk_prepare_hash(algo, me, &di); if (rc < 0) { rc = gnutls_assert_val(CDK_General_Error); goto leave; } params.params_nr = cdk_pk_get_npkey(pk->pubkey_algo); for (i = 0; i < params.params_nr; i++) params.params[i] = pk->mpi[i]; params.flags = 0; ret = _gnutls_pk_verify(algo, &di, &s_sig, ¶ms); if (ret < 0) { gnutls_assert(); rc = map_gnutls_error(ret); goto leave; } rc = 0; leave: _gnutls_free_datum(&s_sig); _gnutls_free_datum(&di); cdk_free(encmd); return rc; }
static int pct_test(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* params) { int ret; gnutls_datum_t sig = {NULL, 0}; const char const_data[20] = "onetwothreefourfive"; gnutls_datum_t ddata, tmp = {NULL,0}; char* gen_data = NULL; if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) { unsigned hash_len; _gnutls_dsa_q_to_hash(algo, params, &hash_len); gen_data = gnutls_malloc(hash_len); gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len); ddata.data = (void*)gen_data; ddata.size = hash_len; } else { ddata.data = (void*)const_data; ddata.size = sizeof(const_data); } switch (algo) { case GNUTLS_PK_RSA: ret = _gnutls_pk_encrypt(algo, &sig, &ddata, params); if (ret < 0) { ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); goto cleanup; } if (ddata.size == sig.size && memcmp(ddata.data, sig.data, sig.size) == 0) { ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); gnutls_assert(); goto cleanup; } ret = _gnutls_pk_decrypt(algo, &tmp, &sig, params); if (ret < 0) { ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); gnutls_assert(); goto cleanup; } if (tmp.size != ddata.size || memcmp(tmp.data, ddata.data, tmp.size) != 0) { ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); gnutls_assert(); goto cleanup; } free(sig.data); sig.data = NULL; /* Here we don't know the purpose of the key. Check both * signing and encryption. */ case GNUTLS_PK_EC: /* we only do keys for ECDSA */ case GNUTLS_PK_DSA: ret = _gnutls_pk_sign(algo, &sig, &ddata, params); if (ret < 0) { ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); goto cleanup; } ret = _gnutls_pk_verify(algo, &ddata, &sig, params); if (ret < 0) { ret = gnutls_assert_val(GNUTLS_E_PK_GENERATION_ERROR); gnutls_assert(); goto cleanup; } break; default: ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM); goto cleanup; } ret = 0; cleanup: if (ret == GNUTLS_E_PK_GENERATION_ERROR) { _gnutls_switch_lib_state(LIB_STATE_ERROR); } gnutls_free(gen_data); gnutls_free(sig.data); gnutls_free(tmp.data); return ret; }