Juan Lang : crypt32: Implement decoding CMSG_CMS_SIGNER_INFO.
Alexandre Julliard
julliard at winehq.org
Wed Aug 20 08:13:39 CDT 2008
Module: wine
Branch: master
Commit: 9b953c5f1e253bf9bc62c9188ce873797449ca0f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9b953c5f1e253bf9bc62c9188ce873797449ca0f
Author: Juan Lang <juan.lang at gmail.com>
Date: Thu Aug 14 12:51:37 2008 -0700
crypt32: Implement decoding CMSG_CMS_SIGNER_INFO.
---
dlls/crypt32/decode.c | 129 ++++++++++++++++++++++++++++++++++++++++++-
dlls/crypt32/tests/encode.c | 6 --
2 files changed, 128 insertions(+), 7 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 89c62ee..3f9a243 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2007 Juan Lang
+ * Copyright 2005-2008 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -4321,6 +4321,130 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
return ret;
}
+static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ CERT_ID *id = (CERT_ID *)pvStructInfo;
+ BOOL ret = FALSE;
+
+ if (*pbEncoded == ASN_SEQUENCEOF)
+ {
+ ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
+ id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
+ if (ret)
+ {
+ if (id)
+ id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
+ if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
+ *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
+ sizeof(CERT_ISSUER_SERIAL_NUMBER);
+ else
+ *pcbStructInfo = sizeof(CERT_ID);
+ }
+ }
+ else if (*pbEncoded == (ASN_CONTEXT | 0))
+ {
+ ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
+ id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
+ if (ret)
+ {
+ if (id)
+ id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
+ if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
+ *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
+ sizeof(CRYPT_DATA_BLOB);
+ else
+ *pcbStructInfo = sizeof(CERT_ID);
+ }
+ }
+ else
+ SetLastError(CRYPT_E_ASN1_BADTAG);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ CMSG_CMS_SIGNER_INFO *info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
+ CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
+ { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
+ CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
+ offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
+ { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
+ CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
+ FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
+ { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
+ offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
+ CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
+ TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
+ { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
+ CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
+ FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
+ HashEncryptionAlgorithm.pszObjId), 0 },
+ { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
+ CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
+ FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
+ { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
+ offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
+ CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
+ TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
+ };
+ BOOL ret;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+ pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, *pcbStructInfo);
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
+ if (ret && pvStructInfo)
+ {
+ ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
+ pcbStructInfo, *pcbStructInfo);
+ if (ret)
+ {
+ CMSG_CMS_SIGNER_INFO *info;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
+ info->SignerId.u.KeyId.pbData = ((BYTE *)info +
+ sizeof(CMSG_CMS_SIGNER_INFO));
+ ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
+ cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
+ pcbStructInfo, NULL);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ }
+ __ENDTRY
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
@@ -4489,6 +4613,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(PKCS7_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
break;
+ case LOWORD(CMS_SIGNER_INFO):
+ decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index 10128ad..28542aa 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -5658,13 +5658,11 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
minimalPKCSSigner, sizeof(minimalPKCSSigner),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
- todo_wine
ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
"Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
if (buf)
{
@@ -5691,7 +5689,6 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
if (buf)
{
@@ -5721,7 +5718,6 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding)
PKCSSignerWithHashAndEncryptionAlgo,
sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
NULL, (BYTE *)&buf, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
if (buf)
{
@@ -5752,7 +5748,6 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
if (buf)
{
@@ -5787,7 +5782,6 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
if (buf)
{
More information about the wine-cvs
mailing list