Module: wine Branch: master Commit: 9b953c5f1e253bf9bc62c9188ce873797449ca0f URL: http://source.winehq.org/git/wine.git/?a=commit;h=9b953c5f1e253bf9bc62c9188c...
Author: Juan Lang juan.lang@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) {