@@ -519,14 +519,17 @@ void init_public_keys(const char *keyfiles)
}
}
+/*
+ * Return: 0 verification good, 1 verification bad, -1 error.
+ */
int verify_hash_v2(const char *file, const unsigned char *hash, int size,
unsigned char *sig, int siglen, const char *keyfile)
{
- int err, len;
- unsigned char out[1024];
- RSA *key;
+ int ret = -1;
+ EVP_PKEY *pkey;
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
- const struct RSA_ASN1_template *asn1;
+ EVP_PKEY_CTX *ctx;
+ const EVP_MD *md;
if (params.verbose > LOG_INFO) {
log_info("hash: ");
@@ -534,45 +537,44 @@ int verify_hash_v2(const char *file, const unsigned char *hash, int size,
}
if (public_keys) {
- key = find_keyid(hdr->keyid);
- if (!key) {
+ pkey = find_keyid_pkey(hdr->keyid);
+ if (!pkey) {
log_err("%s: unknown keyid: %x\n", file,
__be32_to_cpup(&hdr->keyid));
return -1;
}
} else {
- key = read_pub_key(keyfile, 1);
- if (!key)
- return 1;
- }
-
-
- err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr),
- out, key, RSA_PKCS1_PADDING);
- if (err < 0) {
- log_err("%s: RSA_public_decrypt() failed: %d\n", file, err);
- return 1;
- }
-
- len = err;
-
- asn1 = &RSA_ASN1_templates[hdr->hash_algo];
-
- if (len < asn1->size || memcmp(out, asn1->data, asn1->size)) {
- log_err("%s: verification failed: %d (asn1 mismatch)\n",
- file, err);
- return -1;
- }
-
- len -= asn1->size;
-
- if (len != size || memcmp(out + asn1->size, hash, len)) {
- log_err("%s: verification failed: %d (digest mismatch)\n",
- file, err);
- return -1;
+ pkey = read_pub_pkey(keyfile, 1);
+ if (!pkey)
+ return -1;
}
- return 0;
+ if (!(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
+ goto err;
+ if (!EVP_PKEY_verify_init(ctx))
+ goto err;
+ if (!(md = EVP_get_digestbyname(params.hash_algo)))
+ goto err;
+ if (!EVP_PKEY_CTX_set_signature_md(ctx, md))
+ goto err;
+ ret = EVP_PKEY_verify(ctx, sig + sizeof(*hdr),
+ siglen - sizeof(*hdr), hash, size);
+ if (ret == 1)
+ ret = 0;
+ else if (ret == 0) {
+ log_err("%s: verification failed: %d (%s)\n",
+ file, ret, ERR_reason_error_string(ERR_get_error()));
+ ret = 1;
+ }
+err:
+ if (ret < 0 || ret > 1) {
+ log_err("%s: verification failed: %d (%s)\n",
+ file, ret, ERR_reason_error_string(ERR_peek_error()));
+ ret = -1;
+ }
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_free(pkey);
+ return ret;
}
int get_hash_algo(const char *algo)
Rely on OpenSSL API to verify v2 signatures instead of manual PKCS1 decoding. Signed-off-by: Vitaly Chikunov <vt@altlinux.org> --- src/libimaevm.c | 74 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 36 deletions(-)