From cb2e21ffb404a5a7f04af343f0dda26a89d7bfb3 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Mon, 19 Jun 2006 15:12:51 -0700 Subject: [PATCH] crypt32: Encode/decode CRL issuing dist points. --- dlls/crypt32/decode.c | 49 ++++++++++ dlls/crypt32/encode.c | 95 ++++++++++++++++++ dlls/crypt32/tests/encode.c | 230 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 374 insertions(+) diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 1f632e98af3..c3b2a7a9566 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -3070,6 +3070,50 @@ static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType, return ret; } +static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret; + + TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, *pcbStructInfo); + + __TRY + { + struct AsnDecodeSequenceItem items[] = { + { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT, + DistPointName), CRYPT_AsnDecodeDistPointName, + sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, + offsetof(CRL_ISSUING_DIST_POINT, + DistPointName.u.FullName.rgAltEntry), 0 }, + { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT, + fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, + FALSE, 0 }, + { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT, + fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, + FALSE, 0 }, + { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT, + OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal, + sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT, + OnlySomeReasonFlags.pbData), 0 }, + { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT, + fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 }, + }; + + ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) @@ -3179,6 +3223,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, case (WORD)X509_ENHANCED_KEY_USAGE: decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage; break; + case (WORD)X509_ISSUING_DIST_POINT: + decodeFunc = CRYPT_AsnDecodeIssuingDistPoint; + break; default: FIXME("%d: unimplemented\n", LOWORD(lpszStructType)); } @@ -3211,6 +3258,8 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, decodeFunc = CRYPT_AsnDecodeCRLDistPoints; else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE)) decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage; + else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) + decodeFunc = CRYPT_AsnDecodeIssuingDistPoint; else TRACE("OID %s not found or unimplemented, looking for DLL\n", debugstr_a(lpszStructType)); diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index bc00ecf7b9d..2f4e5310068 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -2241,6 +2241,96 @@ static BOOL WINAPI CRYPT_AsnEncodeEnhancedKeyUsage(DWORD dwCertEncodingType, return ret; } +static BOOL WINAPI CRYPT_AsnEncodeIssuingDistPoint(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + + __TRY + { + const CRL_ISSUING_DIST_POINT *point = + (const CRL_ISSUING_DIST_POINT *)pvStructInfo; + struct AsnEncodeSequenceItem items[6] = { { 0 } }; + struct AsnConstructedItem constructed = { 0 }; + struct AsnEncodeTagSwappedItem swapped[5] = { { 0 } }; + DWORD cItem = 0, cSwapped = 0; + + ret = TRUE; + switch (point->DistPointName.dwDistPointNameChoice) + { + case CRL_DIST_POINT_NO_NAME: + /* do nothing */ + break; + case CRL_DIST_POINT_FULL_NAME: + swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0; + swapped[cSwapped].pvStructInfo = &point->DistPointName.u.FullName; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName; + constructed.tag = 0; + constructed.pvStructInfo = &swapped[cSwapped]; + constructed.encodeFunc = CRYPT_AsnEncodeSwapTag; + items[cItem].pvStructInfo = &constructed; + items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; + cSwapped++; + cItem++; + break; + default: + SetLastError(E_INVALIDARG); + ret = FALSE; + } + if (ret && point->fOnlyContainsUserCerts) + { + swapped[cSwapped].tag = ASN_CONTEXT | 1; + swapped[cSwapped].pvStructInfo = &point->fOnlyContainsUserCerts; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBool; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (ret && point->fOnlyContainsCACerts) + { + swapped[cSwapped].tag = ASN_CONTEXT | 2; + swapped[cSwapped].pvStructInfo = &point->fOnlyContainsCACerts; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBool; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (ret && point->OnlySomeReasonFlags.cbData) + { + swapped[cSwapped].tag = ASN_CONTEXT | 3; + swapped[cSwapped].pvStructInfo = &point->OnlySomeReasonFlags; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (ret && point->fIndirectCRL) + { + swapped[cSwapped].tag = ASN_CONTEXT | 4; + swapped[cSwapped].pvStructInfo = &point->fIndirectCRL; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBool; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (ret) + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem, + dwFlags, pEncodePara, pbEncoded, pcbEncoded); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + ret = FALSE; + } + __ENDTRY + return ret; +} + BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded) @@ -2340,6 +2430,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, case (WORD)X509_ENHANCED_KEY_USAGE: encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage; break; + case (WORD)X509_ISSUING_DIST_POINT: + encodeFunc = CRYPT_AsnEncodeIssuingDistPoint; + break; default: FIXME("%d: unimplemented\n", LOWORD(lpszStructType)); } @@ -2372,6 +2465,8 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, encodeFunc = CRYPT_AsnEncodeCRLDistPoints; else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE)) encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage; + else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) + encodeFunc = CRYPT_AsnEncodeIssuingDistPoint; else TRACE("OID %s not found or unimplemented, looking for DLL\n", debugstr_a(lpszStructType)); diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c index c122807a57d..d2ea0c3291a 100644 --- a/dlls/crypt32/tests/encode.c +++ b/dlls/crypt32/tests/encode.c @@ -2591,6 +2591,198 @@ static void test_decodeCRLDistPoints(DWORD dwEncoding) } } +static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff }; +static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 }; +static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68, + 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72, + 0x67 }; + +static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) +{ + BOOL ret; + BYTE *buf = NULL; + DWORD size = 0; + CRL_ISSUING_DIST_POINT point = { { 0 } }; + CERT_ALT_NAME_ENTRY entry; + + ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, + "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError()); + ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError()); + if (buf) + { + ok(size == sizeof(emptySequence), "Unexpected size %ld\n", size); + ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); + LocalFree(buf); + } + /* nonsensical flags */ + point.fOnlyContainsUserCerts = TRUE; + point.fOnlyContainsCACerts = TRUE; + ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError()); + if (buf) + { + ok(size == sizeof(badFlagsIDP), "Unexpected size %ld\n", size); + ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n"); + LocalFree(buf); + } + /* unimplemented name type */ + point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE; + point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME; + ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08lx\n", GetLastError()); + /* empty name */ + point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; + point.DistPointName.FullName.cAltEntry = 0; + ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError()); + if (buf) + { + ok(size == sizeof(emptyNameIDP), "Unexpected size %ld\n", size); + ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n"); + LocalFree(buf); + } + /* name with URL entry */ + entry.dwAltNameChoice = CERT_ALT_NAME_URL; + entry.pwszURL = (LPWSTR)url; + point.DistPointName.FullName.cAltEntry = 1; + point.DistPointName.FullName.rgAltEntry = &entry; + ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError()); + if (buf) + { + ok(size == sizeof(urlIDP), "Unexpected size %ld\n", size); + ok(!memcmp(buf, urlIDP, size), "Unexpected value\n"); + LocalFree(buf); + } +} + +static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected, + const CERT_ALT_NAME_ENTRY *got) +{ + ok(expected->dwAltNameChoice == got->dwAltNameChoice, + "Expected name choice %ld, got %ld\n", expected->dwAltNameChoice, + got->dwAltNameChoice); + if (expected->dwAltNameChoice == got->dwAltNameChoice) + { + switch (got->dwAltNameChoice) + { + case CERT_ALT_NAME_RFC822_NAME: + case CERT_ALT_NAME_DNS_NAME: + case CERT_ALT_NAME_EDI_PARTY_NAME: + case CERT_ALT_NAME_URL: + case CERT_ALT_NAME_REGISTERED_ID: + ok((!expected->pwszURL && !got->pwszURL) || + !lstrcmpW(expected->pwszURL, got->pwszURL), "Unexpected name\n"); + break; + case CERT_ALT_NAME_X400_ADDRESS: + case CERT_ALT_NAME_DIRECTORY_NAME: + case CERT_ALT_NAME_IP_ADDRESS: + ok(got->IPAddress.cbData == expected->IPAddress.cbData, + "Unexpected IP address length %ld\n", got->IPAddress.cbData); + ok(!memcmp(got->IPAddress.pbData, got->IPAddress.pbData, + got->IPAddress.cbData), "Unexpected value\n"); + break; + } + } +} + +static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected, + const CERT_ALT_NAME_INFO *got) +{ + DWORD i; + + ok(expected->cAltEntry == got->cAltEntry, "Expected %ld entries, got %ld\n", + expected->cAltEntry, got->cAltEntry); + for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++) + compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]); +} + +static void compareDistPointName(const CRL_DIST_POINT_NAME *expected, + const CRL_DIST_POINT_NAME *got) +{ + ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice, + "Unexpected name choice %ld\n", got->dwDistPointNameChoice); + if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) + compareAltNameInfo(&expected->FullName, &got->FullName); +} + +static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected, + const CRL_ISSUING_DIST_POINT *got) +{ + compareDistPointName(&expected->DistPointName, &got->DistPointName); + ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts, + "Unexpected fOnlyContainsUserCerts\n"); + ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts, + "Unexpected fOnlyContainsCACerts\n"); + ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData, + "Unexpected reason flags\n"); + ok(got->fIndirectCRL == expected->fIndirectCRL, + "Unexpected fIndirectCRL\n"); +} + +static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding) +{ + BOOL ret; + BYTE *buf = NULL; + DWORD size = 0; + CRL_ISSUING_DIST_POINT point = { { 0 } }; + + ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, + emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, + (BYTE *)&buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError()); + if (ret) + { + compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, + badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, + (BYTE *)&buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError()); + if (ret) + { + point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE; + compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, + emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, + (BYTE *)&buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError()); + if (ret) + { + point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE; + point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; + point.DistPointName.FullName.cAltEntry = 0; + compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); + LocalFree(buf); + } + ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, + urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError()); + if (ret) + { + CERT_ALT_NAME_ENTRY entry; + + entry.dwAltNameChoice = CERT_ALT_NAME_URL; + entry.pwszURL = (LPWSTR)url; + point.DistPointName.FullName.cAltEntry = 1; + point.DistPointName.FullName.rgAltEntry = &entry; + compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf); + LocalFree(buf); + } +} + static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a }; @@ -2635,6 +2827,13 @@ static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06, 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30, 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d, 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; +static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01, + 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03, + 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31, + 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30, + 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06, + 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; static void test_encodeCRLToBeSigned(DWORD dwEncoding) { @@ -2643,6 +2842,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) DWORD size = 0; CRL_INFO info = { 0 }; CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 }; + CERT_EXTENSION ext; /* Test with a V1 CRL */ ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, @@ -2747,6 +2947,21 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n"); LocalFree(buf); } + /* a v2 CRL with an issuing dist point extension */ + ext.pszObjId = szOID_ISSUING_DIST_POINT; + ext.fCritical = TRUE; + ext.Value.cbData = sizeof(urlIDP); + ext.Value.pbData = (LPBYTE)urlIDP; + entry.rgExtension = &ext; + ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError()); + if (buf) + { + ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %ld\n", size); + ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n"); + LocalFree(buf); + } } static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01, @@ -2908,6 +3123,19 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) info->cExtension); LocalFree(buf); } + /* And again, with an issuing dist point */ + ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, + v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint), + CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError()); + if (buf) + { + CRL_INFO *info = (CRL_INFO *)buf; + + ok(info->cExtension == 1, "Expected 1 extensions, got %ld\n", + info->cExtension); + LocalFree(buf); + } } static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING, @@ -3183,6 +3411,8 @@ START_TEST(encode) test_decodeCert(encodings[i]); test_encodeCRLDistPoints(encodings[i]); test_decodeCRLDistPoints(encodings[i]); + test_encodeCRLIssuingDistPoint(encodings[i]); + test_decodeCRLIssuingDistPoint(encodings[i]); test_encodeCRLToBeSigned(encodings[i]); test_decodeCRLToBeSigned(encodings[i]); test_encodeEnhancedKeyUsage(encodings[i]); -- 2.11.4.GIT