Commit 650fe1fd authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

crypt32: Support CNG keys in CDecodeSignedMsg_VerifySignatureWithKey().

parent 8436f038
......@@ -2810,7 +2810,7 @@ static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE
return TRUE;
}
static BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len,
BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len,
BYTE **sig_value, DWORD *sig_len)
{
if (!strcmp(alg_oid, szOID_ECC_PUBLIC_KEY))
......
......@@ -23,6 +23,8 @@
#include "wine/unixlib.h"
BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key) DECLSPEC_HIDDEN;
BOOL cng_prepare_signature(const char *alg_oid, BYTE *encoded_sig, DWORD encoded_sig_len,
BYTE **sig_value, DWORD *sig_len) DECLSPEC_HIDDEN;
/* a few asn.1 tags we need */
#define ASN_BOOL (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x01)
......
......@@ -3316,24 +3316,56 @@ static BOOL CDecodeHashMsg_VerifyHash(CDecodeMsg *msg)
return ret;
}
static BOOL cng_verify_msg_signature(CMSG_CMS_SIGNER_INFO *signer, HCRYPTHASH hash, CERT_PUBLIC_KEY_INFO *key_info)
{
BYTE *hash_value, *sig_value = NULL;
DWORD hash_len, sig_len;
BCRYPT_KEY_HANDLE key;
BOOL ret = FALSE;
NTSTATUS status;
if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, key_info, 0, NULL, &key)) return FALSE;
if (!extract_hash(hash, &hash_value, &hash_len)) goto done;
if (!cng_prepare_signature(key_info->Algorithm.pszObjId, signer->EncryptedHash.pbData,
signer->EncryptedHash.cbData, &sig_value, &sig_len)) goto done;
status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0);
if (status)
{
FIXME("Failed to verify signature: %08lx.\n", status);
SetLastError(RtlNtStatusToDosError(status));
}
ret = !status;
done:
CryptMemFree(sig_value);
CryptMemFree(hash_value);
BCryptDestroyKey(key);
return ret;
}
static BOOL CDecodeSignedMsg_VerifySignatureWithKey(CDecodeMsg *msg,
HCRYPTPROV prov, DWORD signerIndex, PCERT_PUBLIC_KEY_INFO keyInfo)
{
HCRYPTHASH hash;
HCRYPTKEY key;
BOOL ret;
ALG_ID alg_id = 0;
if (msg->u.signed_data.info->rgSignerInfo[signerIndex].AuthAttrs.cAttr)
hash = msg->u.signed_data.signerHandles[signerIndex].authAttrHash;
else
hash = msg->u.signed_data.signerHandles[signerIndex].contentHash;
if (keyInfo->Algorithm.pszObjId) alg_id = CertOIDToAlgId(keyInfo->Algorithm.pszObjId);
if (alg_id == CALG_OID_INFO_PARAMETERS || alg_id == CALG_OID_INFO_CNG_ONLY)
return cng_verify_msg_signature(&msg->u.signed_data.info->rgSignerInfo[signerIndex], hash, keyInfo);
if (!prov)
prov = msg->crypt_prov;
ret = CryptImportPublicKeyInfo(prov, X509_ASN_ENCODING, keyInfo, &key);
if (ret)
{
HCRYPTHASH hash;
CRYPT_HASH_BLOB reversedHash;
if (msg->u.signed_data.info->rgSignerInfo[signerIndex].AuthAttrs.cAttr)
hash = msg->u.signed_data.signerHandles[signerIndex].authAttrHash;
else
hash = msg->u.signed_data.signerHandles[signerIndex].contentHash;
ret = CRYPT_ConstructBlob(&reversedHash,
&msg->u.signed_data.info->rgSignerInfo[signerIndex].EncryptedHash);
if (ret)
......
......@@ -3608,12 +3608,12 @@ static void test_verify_ecc_signature(void)
BCryptDestroyKey(bkey);
bret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
todo_wine ok(bret, "failed, error %#lx.\n", GetLastError());
ok(bret, "failed, error %#lx.\n", GetLastError());
verify_para.dwSignerType = CMSG_VERIFY_SIGNER_CERT;
verify_para.pvSigner = (void *)cert;
bret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE_EX, &verify_para);
todo_wine ok(bret, "failed, error %#lx.\n", GetLastError());
ok(bret, "failed, error %#lx.\n", GetLastError());
free(signer_info);
free(cert_info);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment