Alexander Morozov : crypt32: Implement getting content of an enveloped message.

Alexandre Julliard julliard at winehq.org
Thu Dec 2 12:23:58 CST 2010


Module: wine
Branch: master
Commit: 6ad5416f32dae5e436a55d1a6fac871d533abf30
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6ad5416f32dae5e436a55d1a6fac871d533abf30

Author: Alexander Morozov <amorozov at etersoft.ru>
Date:   Wed Dec  1 14:40:27 2010 +0300

crypt32: Implement getting content of an enveloped message.

---

 dlls/crypt32/crypt32_private.h |   18 +++++++++++++
 dlls/crypt32/encode.c          |   55 ++++++++++++++++++++++++++++++++++++++++
 dlls/crypt32/msg.c             |   55 +++++++++++++++++++++++++++++++++++++--
 dlls/crypt32/tests/msg.c       |    2 -
 4 files changed, 125 insertions(+), 5 deletions(-)

diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 36ee3e2..a4b9aff 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -82,6 +82,24 @@ typedef struct _CRYPT_DIGESTED_DATA
 BOOL CRYPT_AsnEncodePKCSDigestedData(const CRYPT_DIGESTED_DATA *digestedData,
  void *pvData, DWORD *pcbData);
 
+typedef struct _CRYPT_ENCRYPTED_CONTENT_INFO
+{
+    LPSTR                      contentType;
+    CRYPT_ALGORITHM_IDENTIFIER contentEncryptionAlgorithm;
+    CRYPT_DATA_BLOB            encryptedContent;
+} CRYPT_ENCRYPTED_CONTENT_INFO;
+
+typedef struct _CRYPT_ENVELOPED_DATA
+{
+    DWORD                          version;
+    DWORD                          cRecipientInfo;
+    PCMSG_KEY_TRANS_RECIPIENT_INFO rgRecipientInfo;
+    CRYPT_ENCRYPTED_CONTENT_INFO   encryptedContentInfo;
+} CRYPT_ENVELOPED_DATA;
+
+BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
+ void *pvData, DWORD *pcbData);
+
 typedef struct _CRYPT_SIGNED_INFO
 {
     DWORD                 version;
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index 3beab84..5d6affe 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -4293,6 +4293,61 @@ BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
     return ret;
 }
 
+static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    const CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo;
+    struct AsnEncodeSequenceItem items[] = {
+     { &info->dwVersion, CRYPT_AsnEncodeInt, 0 },
+     { &info->RecipientId.u.IssuerSerialNumber,
+       CRYPT_AsnEncodeIssuerSerialNumber, 0 },
+     { &info->KeyEncryptionAlgorithm,
+       CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
+     { &info->EncryptedKey, CRYPT_AsnEncodeOctets, 0 },
+    };
+
+    return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
+     sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+     pcbEncoded);
+}
+
+static BOOL WINAPI CRYPT_AsnEncodeEncryptedContentInfo(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    const CRYPT_ENCRYPTED_CONTENT_INFO *info = pvStructInfo;
+    struct AsnEncodeTagSwappedItem swapped = { ASN_CONTEXT | 0,
+     &info->encryptedContent, CRYPT_AsnEncodeOctets };
+    struct AsnEncodeSequenceItem items[] = {
+     { info->contentType, CRYPT_AsnEncodeOid, 0 },
+     { &info->contentEncryptionAlgorithm,
+       CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
+     { &swapped, CRYPT_AsnEncodeSwapTag, 0 },
+    };
+
+    return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
+     sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+     pcbEncoded);
+}
+
+BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
+ void *pvData, DWORD *pcbData)
+{
+    struct DERSetDescriptor recipientInfosSet = { envelopedData->cRecipientInfo,
+     envelopedData->rgRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), 0,
+     CRYPT_AsnEncodeRecipientInfo };
+    struct AsnEncodeSequenceItem items[] = {
+     { &envelopedData->version, CRYPT_AsnEncodeInt, 0 },
+     { &recipientInfosSet, CRYPT_DEREncodeItemsAsSet, 0 },
+     { &envelopedData->encryptedContentInfo,
+       CRYPT_AsnEncodeEncryptedContentInfo, 0 },
+    };
+
+    return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
+     sizeof(items) / sizeof(items[0]), 0, NULL, pvData, pcbData);
+}
+
 static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
  LPCSTR lpszStructType)
 {
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index 2b93a5b..f083c53 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -1785,9 +1785,58 @@ static void CEnvelopedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
 static BOOL CEnvelopedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
  DWORD dwIndex, void *pvData, DWORD *pcbData)
 {
-    FIXME("(%p, %d, %d, %p, %p): stub\n", hCryptMsg, dwParamType, dwIndex,
-     pvData, pcbData);
-    return FALSE;
+    CEnvelopedEncodeMsg *msg = hCryptMsg;
+    BOOL ret = FALSE;
+
+    switch (dwParamType)
+    {
+    case CMSG_BARE_CONTENT_PARAM:
+        if (msg->base.streamed)
+            SetLastError(E_INVALIDARG);
+        else
+        {
+            char oid_rsa_data[] = szOID_RSA_data;
+            CRYPT_ENVELOPED_DATA envelopedData = {
+             CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION, msg->cRecipientInfo,
+             msg->recipientInfo, { oid_rsa_data, msg->algo, msg->data }
+            };
+
+            ret = CRYPT_AsnEncodePKCSEnvelopedData(&envelopedData, pvData,
+             pcbData);
+        }
+        break;
+    case CMSG_CONTENT_PARAM:
+    {
+        CRYPT_CONTENT_INFO info;
+
+        ret = CryptMsgGetParam(hCryptMsg, CMSG_BARE_CONTENT_PARAM, 0, NULL,
+         &info.Content.cbData);
+        if (ret)
+        {
+            info.Content.pbData = CryptMemAlloc(info.Content.cbData);
+            if (info.Content.pbData)
+            {
+                ret = CryptMsgGetParam(hCryptMsg, CMSG_BARE_CONTENT_PARAM, 0,
+                 info.Content.pbData, &info.Content.cbData);
+                if (ret)
+                {
+                    char oid_rsa_enveloped[] = szOID_RSA_envelopedData;
+
+                    info.pszObjId = oid_rsa_enveloped;
+                    ret = CryptEncodeObjectEx(X509_ASN_ENCODING,
+                     PKCS_CONTENT_INFO, &info, 0, NULL, pvData, pcbData);
+                }
+                CryptMemFree(info.Content.pbData);
+            }
+            else
+                ret = FALSE;
+        }
+        break;
+    }
+    default:
+        SetLastError(CRYPT_E_INVALID_MSG_TYPE);
+    }
+    return ret;
 }
 
 static BOOL CEnvelopedEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c
index 9ffae52..e32690b 100644
--- a/dlls/crypt32/tests/msg.c
+++ b/dlls/crypt32/tests/msg.c
@@ -2248,11 +2248,9 @@ static void test_enveloped_msg_encoding(void)
      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
     if (msg)
     {
-        todo_wine
         check_param("enveloped empty bare content", msg,
          CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
          sizeof(envelopedEmptyBareContent));
-        todo_wine
         check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
          envelopedEmptyContent, sizeof(envelopedEmptyContent));
         CryptMsgClose(msg);




More information about the wine-cvs mailing list