crypt32: partially implement CMSG_CTRL_VERIFY_SIGNATURE_EX

Juan Lang juan.lang at gmail.com
Fri Aug 24 17:21:46 CDT 2007


--Juan
-------------- next part --------------
From 6599c6f4572ee5f96a4540b257a6b38080e3e502 Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang at gmail.com>
Date: Fri, 24 Aug 2007 15:20:13 -0700
Subject: [PATCH] Partially implement CMSG_CTRL_VERIFY_SIGNATURE_EX
---
 dlls/crypt32/msg.c |  101 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 77 insertions(+), 24 deletions(-)

diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index 7cf1a30..4e608bc 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -2087,6 +2087,38 @@ static BOOL CDecodeHashMsg_VerifyHash(CD
     return ret;
 }
 
+static BOOL CDecodeSignedMsg_VerifySignatureWithKey(CDecodeMsg *msg,
+ HCRYPTPROV prov, DWORD signerIndex, PCERT_PUBLIC_KEY_INFO keyInfo)
+{
+    HCRYPTKEY key;
+    BOOL ret;
+
+    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)
+        {
+            CRYPT_ReverseBytes(&reversedHash);
+            ret = CryptVerifySignatureW(hash, reversedHash.pbData,
+             reversedHash.cbData, key, NULL, 0);
+            CryptMemFree(reversedHash.pbData);
+        }
+        CryptDestroyKey(key);
+    }
+    return ret;
+}
+
 static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info)
 {
     BOOL ret = FALSE;
@@ -2106,35 +2138,45 @@ static BOOL CDecodeSignedMsg_VerifySigna
         }
     }
     if (ret)
-    {
-        HCRYPTKEY key;
+        ret = CDecodeSignedMsg_VerifySignatureWithKey(msg, 0, i,
+         &info->SubjectPublicKeyInfo);
+    else
+        SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
 
-        ret = CryptImportPublicKeyInfo(msg->crypt_prov, X509_ASN_ENCODING,
-         &info->SubjectPublicKeyInfo, &key);
-        if (ret)
+    return ret;
+}
+
+static BOOL CDecodeSignedMsg_VerifySignatureEx(CDecodeMsg *msg,
+ PCMSG_CTRL_VERIFY_SIGNATURE_EX_PARA para)
+{
+    BOOL ret = FALSE;
+
+    if (para->cbSize != sizeof(CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA))
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (para->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo)
+        SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
+    else
+    {
+        switch (para->dwSignerType)
+        {
+        case CMSG_VERIFY_SIGNER_PUBKEY:
+            ret = CDecodeSignedMsg_VerifySignatureWithKey(msg,
+             para->hCryptProv, para->dwSignerIndex,
+             (PCERT_PUBLIC_KEY_INFO)para->pvSigner);
+            break;
+        case CMSG_VERIFY_SIGNER_CERT:
         {
-            HCRYPTHASH hash;
-            CRYPT_HASH_BLOB reversedHash;
+            PCCERT_CONTEXT cert = (PCCERT_CONTEXT)para->pvSigner;
 
-            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 = CRYPT_ConstructBlob(&reversedHash,
-             &msg->u.signed_data.info->rgSignerInfo[i].EncryptedHash);
-            if (ret)
-            {
-                CRYPT_ReverseBytes(&reversedHash);
-                ret = CryptVerifySignatureW(hash, reversedHash.pbData,
-                 reversedHash.cbData, key, NULL, 0);
-                CryptMemFree(reversedHash.pbData);
-            }
-            CryptDestroyKey(key);
+            ret = CDecodeSignedMsg_VerifySignatureWithKey(msg, para->hCryptProv,
+             para->dwSignerIndex, &cert->pCertInfo->SubjectPublicKeyInfo);
+            break;
+        }
+        default:
+            FIXME("unimplemented for signer type %d\n", para->dwSignerType);
+            SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
         }
     }
-    else
-        SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
-
     return ret;
 }
 
@@ -2173,6 +2215,17 @@ static BOOL CDecodeMsg_Control(HCRYPTMSG
             SetLastError(CRYPT_E_INVALID_MSG_TYPE);
         }
         break;
+    case CMSG_CTRL_VERIFY_SIGNATURE_EX:
+        switch (msg->type)
+        {
+        case CMSG_SIGNED:
+            ret = CDecodeSignedMsg_VerifySignatureEx(msg,
+             (PCMSG_CTRL_VERIFY_SIGNATURE_EX_PARA)pvCtrlPara);
+            break;
+        default:
+            SetLastError(CRYPT_E_INVALID_MSG_TYPE);
+        }
+        break;
     default:
         SetLastError(CRYPT_E_CONTROL_TYPE);
     }
-- 
1.4.1


More information about the wine-patches mailing list