crypt32: Implement verifying a decoded signed message's signature.
This commit is contained in:
parent
d3431271fa
commit
b7e420429d
|
@ -2084,6 +2084,47 @@ static BOOL CDecodeHashMsg_VerifyHash(CDecodeMsg *msg)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info)
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
|
for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++)
|
||||||
|
{
|
||||||
|
ret = CertCompareCertificateName(X509_ASN_ENCODING,
|
||||||
|
&msg->u.signed_data.info->rgSignerInfo[i].Issuer, &info->Issuer);
|
||||||
|
if (ret)
|
||||||
|
ret = CertCompareIntegerBlob(
|
||||||
|
&msg->u.signed_data.info->rgSignerInfo[i].SerialNumber,
|
||||||
|
&info->SerialNumber);
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
HCRYPTKEY key;
|
||||||
|
|
||||||
|
ret = CryptImportPublicKeyInfo(msg->crypt_prov, X509_ASN_ENCODING,
|
||||||
|
&info->SubjectPublicKeyInfo, &key);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
HCRYPTHASH hash;
|
||||||
|
|
||||||
|
if (msg->u.signed_data.info->rgSignerInfo[i].AuthAttrs.cAttr)
|
||||||
|
hash = msg->u.signed_data.signerHandles[i].authAttrHash;
|
||||||
|
else
|
||||||
|
hash = msg->u.signed_data.signerHandles[i].contentHash;
|
||||||
|
ret = CryptVerifySignatureW(hash,
|
||||||
|
msg->u.signed_data.info->rgSignerInfo[i].EncryptedHash.pbData,
|
||||||
|
msg->u.signed_data.info->rgSignerInfo[i].EncryptedHash.cbData,
|
||||||
|
key, NULL, 0);
|
||||||
|
CryptDestroyKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags,
|
static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags,
|
||||||
DWORD dwCtrlType, const void *pvCtrlPara)
|
DWORD dwCtrlType, const void *pvCtrlPara)
|
||||||
{
|
{
|
||||||
|
@ -2096,7 +2137,7 @@ static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags,
|
||||||
switch (msg->type)
|
switch (msg->type)
|
||||||
{
|
{
|
||||||
case CMSG_SIGNED:
|
case CMSG_SIGNED:
|
||||||
FIXME("CMSG_CTRL_VERIFY_SIGNATURE: stub\n");
|
ret = CDecodeSignedMsg_VerifySignature(msg, (PCERT_INFO)pvCtrlPara);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SetLastError(CRYPT_E_INVALID_MSG_TYPE);
|
SetLastError(CRYPT_E_INVALID_MSG_TYPE);
|
||||||
|
|
|
@ -2291,7 +2291,6 @@ static void test_msg_control(void)
|
||||||
*/
|
*/
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
|
ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
|
||||||
"Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
|
"Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
|
||||||
/* The cert info is expected to have an issuer, serial number, and public
|
/* The cert info is expected to have an issuer, serial number, and public
|
||||||
|
@ -2303,7 +2302,6 @@ static void test_msg_control(void)
|
||||||
certInfo.Issuer.pbData = encodedCommonName;
|
certInfo.Issuer.pbData = encodedCommonName;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
|
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
|
||||||
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
||||||
CryptMsgClose(msg);
|
CryptMsgClose(msg);
|
||||||
|
@ -2315,7 +2313,6 @@ static void test_msg_control(void)
|
||||||
/* Again, cert info needs to have a public key set */
|
/* Again, cert info needs to have a public key set */
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
|
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
|
||||||
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
||||||
/* The public key is supposed to be in encoded form.. */
|
/* The public key is supposed to be in encoded form.. */
|
||||||
|
@ -2324,7 +2321,6 @@ static void test_msg_control(void)
|
||||||
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
|
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
|
ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
|
||||||
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
||||||
/* but not as a X509_PUBLIC_KEY_INFO.. */
|
/* but not as a X509_PUBLIC_KEY_INFO.. */
|
||||||
|
@ -2333,7 +2329,6 @@ static void test_msg_control(void)
|
||||||
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
|
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
|
ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
|
||||||
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
|
||||||
/* This decodes successfully, but it doesn't match any key in the message */
|
/* This decodes successfully, but it doesn't match any key in the message */
|
||||||
|
@ -2341,6 +2336,10 @@ static void test_msg_control(void)
|
||||||
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
|
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
|
||||||
|
/* In Wine's rsaenh, this fails to decode because the key length is too
|
||||||
|
* small. Not sure if that's a bug in rsaenh, so leaving todo_wine for
|
||||||
|
* now.
|
||||||
|
*/
|
||||||
todo_wine
|
todo_wine
|
||||||
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
|
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
|
||||||
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
|
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
|
||||||
|
|
Loading…
Reference in New Issue