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