Juan Lang : crypt32: Implement verifying a decoded signed message'
s signature.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Aug 21 15:22:27 CDT 2007
Module: wine
Branch: master
Commit: b7e420429db8e3a2eab503f49ce0b04a4ac7f551
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b7e420429db8e3a2eab503f49ce0b04a4ac7f551
Author: Juan Lang <juan.lang at gmail.com>
Date: Tue Aug 21 07:34:47 2007 -0700
crypt32: Implement verifying a decoded signed message's signature.
---
dlls/crypt32/msg.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
dlls/crypt32/tests/msg.c | 9 ++++-----
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index ace5e51..c9226ad 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -2084,6 +2084,47 @@ static BOOL CDecodeHashMsg_VerifyHash(CDecodeMsg *msg)
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,
DWORD dwCtrlType, const void *pvCtrlPara)
{
@@ -2096,7 +2137,7 @@ static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags,
switch (msg->type)
{
case CMSG_SIGNED:
- FIXME("CMSG_CTRL_VERIFY_SIGNATURE: stub\n");
+ ret = CDecodeSignedMsg_VerifySignature(msg, (PCERT_INFO)pvCtrlPara);
break;
default:
SetLastError(CRYPT_E_INVALID_MSG_TYPE);
diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c
index f079916..b1e6c94 100644
--- a/dlls/crypt32/tests/msg.c
+++ b/dlls/crypt32/tests/msg.c
@@ -2291,7 +2291,6 @@ static void test_msg_control(void)
*/
SetLastError(0xdeadbeef);
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
- todo_wine
ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
"Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
/* 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;
SetLastError(0xdeadbeef);
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
- todo_wine
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
CryptMsgClose(msg);
@@ -2315,7 +2313,6 @@ static void test_msg_control(void)
/* Again, cert info needs to have a public key set */
SetLastError(0xdeadbeef);
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
- todo_wine
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
/* 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;
SetLastError(0xdeadbeef);
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
- todo_wine
ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
/* but not as a X509_PUBLIC_KEY_INFO.. */
@@ -2333,7 +2329,6 @@ static void test_msg_control(void)
certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
SetLastError(0xdeadbeef);
ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
- todo_wine
ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
/* 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;
SetLastError(0xdeadbeef);
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
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
More information about the wine-cvs
mailing list