From 972ce37ccd3c8f891ecdf4ad8bde5785a5053a89 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Wed, 27 Aug 2008 14:15:57 -0700 Subject: [PATCH] Implement CTL decoding --- dlls/crypt32/decode.c | 118 +++++++++++++++++++++++++++++++++++++++++++ dlls/crypt32/tests/encode.c | 16 +----- 2 files changed, 121 insertions(+), 13 deletions(-) diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 2253bef..bff9672 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -112,6 +112,9 @@ static BOOL CRYPT_AsnDecodeIntegerIntern static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); +static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded); /* Gets the number of length bytes from the given (leading) length byte */ #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f)) @@ -2033,6 +2036,116 @@ static BOOL CRYPT_DecodeDERArray(const B return ret; } +static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded, + DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) +{ + BOOL ret; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 }; + CTL_USAGE *usage = (CTL_USAGE *)pvStructInfo; + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, + NULL, pvStructInfo, pcbStructInfo, pcbDecoded, + usage ? usage->rgpszUsageIdentifier : NULL); + return ret; +} + +static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded, + DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) +{ + struct AsnDecodeSequenceItem items[] = { + { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier), + CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE, + offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 }, + { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute), + CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE, + TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 }, + }; + BOOL ret = TRUE; + CTL_ENTRY *entry = (CTL_ENTRY *)pvStructInfo; + + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, + *pcbStructInfo); + + ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), + pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, + pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL); + return ret; +} + +static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded, + DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) +{ + BOOL ret; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE, + offsetof(CTL_ENTRY, SubjectIdentifier.pbData) }; + struct GenericArray *entries = (struct GenericArray *)pvStructInfo; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, + NULL, pvStructInfo, pcbStructInfo, pcbDecoded, + entries ? entries->rgItems : NULL); + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeCTL(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 + { + struct AsnDecodeSequenceItem items[] = { + { ASN_INTEGER, offsetof(CTL_INFO, dwVersion), + CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, + { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage), + CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE, + offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 }, + { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier), + CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE, + TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 }, + { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber), + CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), + TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 }, + { 0, offsetof(CTL_INFO, ThisUpdate), + CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, + 0 }, + { 0, offsetof(CTL_INFO, NextUpdate), + CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE, + 0 }, + { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm), + CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), + FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 }, + { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry), + CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray), + TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 }, + { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension), + CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE, + offsetof(CTL_INFO, rgExtension), 0 }, + }; + + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, *pcbStructInfo); + + ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), + pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, + pcbStructInfo, NULL, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) @@ -4751,6 +4864,9 @@ static CryptDecodeObjectExFunc CRYPT_Get case LOWORD(X509_ENHANCED_KEY_USAGE): decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage; break; + case LOWORD(PKCS_CTL): + decodeFunc = CRYPT_AsnDecodeCTL; + break; case LOWORD(PKCS_SMIME_CAPABILITIES): decodeFunc = CRYPT_AsnDecodeSMIMECapabilities; break; @@ -4811,6 +4927,8 @@ static CryptDecodeObjectExFunc CRYPT_Get decodeFunc = CRYPT_AsnDecodeNameConstraints; else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS)) decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess; + else if (!strcmp(lpszStructType, szOID_CTL)) + decodeFunc = CRYPT_AsnDecodeCTL; return decodeFunc; } diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index 33d2773..47704ef 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -5305,7 +5305,6 @@ static void test_decodeCTL(DWORD dwEncod memset(&info, 0, sizeof(info)); ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5317,7 +5316,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1, sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5331,7 +5329,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier, sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5345,7 +5342,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier, sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5359,7 +5355,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber, sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5372,7 +5367,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate, sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5384,7 +5378,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate, sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5400,7 +5393,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId, sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5412,9 +5404,9 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry, sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine - ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, - "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); + ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT), + "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n", + GetLastError()); info.SubjectAlgorithm.Parameters.cbData = 0; info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0; info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0; @@ -5435,7 +5427,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry, sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { @@ -5456,7 +5447,6 @@ static void test_decodeCTL(DWORD dwEncod ret = CryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries, sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); - todo_wine ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); if (buf) { -- 1.4.1