From 2b23e89568873468cdd9e3da099bc40c2e52af3c Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 23 Jan 2012 15:45:22 +0000 Subject: [PATCH] [CRYPT32_WINETEST] * Sync to Wine 1.3.37. svn path=/trunk/; revision=55109 --- rostests/winetests/crypt32/base64.c | 30 +- rostests/winetests/crypt32/cert.c | 80 ++- rostests/winetests/crypt32/chain.c | 840 +++++++++++++---------- rostests/winetests/crypt32/crl.c | 33 +- rostests/winetests/crypt32/ctl.c | 3 +- rostests/winetests/crypt32/encode.c | 494 +++++++------ rostests/winetests/crypt32/main.c | 11 +- rostests/winetests/crypt32/message.c | 660 +++++++++++++++++- rostests/winetests/crypt32/msg.c | 623 ++++++++++++++++- rostests/winetests/crypt32/oid.c | 1 + rostests/winetests/crypt32/protectdata.c | 1 - rostests/winetests/crypt32/store.c | 54 +- rostests/winetests/crypt32/str.c | 627 ++++++++++++++--- 13 files changed, 2735 insertions(+), 722 deletions(-) diff --git a/rostests/winetests/crypt32/base64.c b/rostests/winetests/crypt32/base64.c index 5a260edfd6e..8f19515e531 100644 --- a/rostests/winetests/crypt32/base64.c +++ b/rostests/winetests/crypt32/base64.c @@ -28,7 +28,9 @@ #include "wine/test.h" #define CERT_HEADER "-----BEGIN CERTIFICATE-----\r\n" +#define ALT_CERT_HEADER "-----BEGIN This is some arbitrary text that goes on and on-----\r\n" #define CERT_TRAILER "-----END CERTIFICATE-----\r\n" +#define ALT_CERT_TRAILER "-----END More arbitrary text------\r\n" #define CERT_REQUEST_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----\r\n" #define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----\r\n" #define X509_HEADER "-----BEGIN X509 CRL-----\r\n" @@ -40,15 +42,12 @@ #define X509_HEADER_NOCR "-----BEGIN X509 CRL-----\n" #define X509_TRAILER_NOCR "-----END X509 CRL-----\n" -typedef BOOL (WINAPI *CryptBinaryToStringAFunc)(const BYTE *pbBinary, +static BOOL (WINAPI *pCryptBinaryToStringA)(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString); -typedef BOOL (WINAPI *CryptStringToBinaryAFunc)(LPCSTR pszString, +static BOOL (WINAPI *pCryptStringToBinaryA)(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags); -CryptBinaryToStringAFunc pCryptBinaryToStringA; -CryptStringToBinaryAFunc pCryptStringToBinaryA; - struct BinTests { const BYTE *toEncode; @@ -64,7 +63,7 @@ static const BYTE toEncode4[] = "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"; -struct BinTests tests[] = { +static const struct BinTests tests[] = { { toEncode1, sizeof(toEncode1), "AA==\r\n", }, { toEncode2, sizeof(toEncode2), "AQI=\r\n", }, /* { toEncode3, sizeof(toEncode3), "AQID\r\n", }, This test fails on Vista. */ @@ -76,7 +75,7 @@ struct BinTests tests[] = { "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\r\n" }, }; -struct BinTests testsNoCR[] = { +static const struct BinTests testsNoCR[] = { { toEncode1, sizeof(toEncode1), "AA==\n", }, { toEncode2, sizeof(toEncode2), "AQI=\n", }, /* { toEncode3, sizeof(toEncode3), "AQID\n", }, This test fails on Vista. */ @@ -118,11 +117,8 @@ static void encodeAndCompareBase64_A(const BYTE *toEncode, DWORD toEncodeLen, "Expected %s, got %s\n", expected, ptr); ptr += strlen(expected); if (trailer) - { ok(!strncmp(trailer, ptr, strlen(trailer)), "Expected trailer %s, got %s\n", trailer, ptr); - ptr += strlen(trailer); - } HeapFree(GetProcessHeap(), 0, str); } } @@ -154,6 +150,7 @@ static void testBinaryToStringA(void) ret = pCryptBinaryToStringA(tests[i].toEncode, tests[i].toEncodeLen, CRYPT_STRING_BINARY, str, &strLen2); + ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, strLen2); ok(!memcmp(str, tests[i].toEncode, tests[i].toEncodeLen), @@ -190,6 +187,7 @@ static void testBinaryToStringA(void) ret = pCryptBinaryToStringA(testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen, CRYPT_STRING_BINARY | CRYPT_STRING_NOCR, str, &strLen2); + ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, strLen2); ok(!memcmp(str, testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen), @@ -290,6 +288,7 @@ static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header, ret = pCryptStringToBinaryA(str, 0, useFormat, buf, &bufLen, &skipped, &usedFormat); + ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); ok(skipped == strlen(garbage), "Expected %d characters of \"%s\" skipped when trying format %08x, got %d (used format is %08x)\n", lstrlenA(garbage), str, useFormat, skipped, usedFormat); @@ -306,7 +305,7 @@ struct BadString DWORD format; }; -struct BadString badStrings[] = { +static const struct BadString badStrings[] = { { "A\r\nA\r\n=\r\n=\r\n", CRYPT_STRING_BASE64 }, { "AA\r\n=\r\n=\r\n", CRYPT_STRING_BASE64 }, { "AA=\r\n=\r\n", CRYPT_STRING_BASE64 }, @@ -360,6 +359,9 @@ static void testStringToBinaryA(void) decodeAndCompareBase64_A(tests[i].base64, CERT_HEADER, CERT_TRAILER, CRYPT_STRING_BASE64HEADER, CRYPT_STRING_BASE64HEADER, tests[i].toEncode, tests[i].toEncodeLen); + decodeAndCompareBase64_A(tests[i].base64, ALT_CERT_HEADER, ALT_CERT_TRAILER, + CRYPT_STRING_BASE64HEADER, CRYPT_STRING_BASE64HEADER, + tests[i].toEncode, tests[i].toEncodeLen); decodeAndCompareBase64_A(tests[i].base64, CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER, CRYPT_STRING_BASE64REQUESTHEADER, CRYPT_STRING_BASE64REQUESTHEADER, tests[i].toEncode, @@ -441,10 +443,8 @@ START_TEST(base64) { HMODULE lib = GetModuleHandleA("crypt32"); - pCryptBinaryToStringA = (CryptBinaryToStringAFunc)GetProcAddress(lib, - "CryptBinaryToStringA"); - pCryptStringToBinaryA = (CryptStringToBinaryAFunc)GetProcAddress(lib, - "CryptStringToBinaryA"); + pCryptBinaryToStringA = (void *)GetProcAddress(lib, "CryptBinaryToStringA"); + pCryptStringToBinaryA = (void *)GetProcAddress(lib, "CryptStringToBinaryA"); if (pCryptBinaryToStringA) testBinaryToStringA(); diff --git a/rostests/winetests/crypt32/cert.c b/rostests/winetests/crypt32/cert.c index d3b362c8a34..8239af8aea9 100644 --- a/rostests/winetests/crypt32/cert.c +++ b/rostests/winetests/crypt32/cert.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include + #include #include #include @@ -487,6 +487,8 @@ static void testCertProperties(void) size = sizeof(hashProperty); ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID, hashProperty, &size); + ok(ret, "CertGetCertificateContextProperty failed: %08x\n", + GetLastError()); ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n"); /* Delete the (bogus) hash, and get the real one */ ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0, @@ -632,6 +634,51 @@ static void testCertProperties(void) CertFreeCertificateContext(context); } +static void testCreateCert(void) +{ + PCCERT_CONTEXT cert, enumCert; + DWORD count, size; + BOOL ret; + + SetLastError(0xdeadbeef); + cert = CertCreateCertificateContext(0, NULL, 0); + ok(!cert && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + cert = CertCreateCertificateContext(0, selfSignedCert, + sizeof(selfSignedCert)); + ok(!cert && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + cert = CertCreateCertificateContext(X509_ASN_ENCODING, NULL, 0); + ok(!cert && + (GetLastError() == CRYPT_E_ASN1_EOD || + broken(GetLastError() == OSS_MORE_INPUT /* NT4 */)), + "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); + + cert = CertCreateCertificateContext(X509_ASN_ENCODING, + selfSignedCert, sizeof(selfSignedCert)); + ok(cert != NULL, "creating cert failed: %08x\n", GetLastError()); + /* Even in-memory certs are expected to have a store associated with them */ + todo_wine + ok(cert->hCertStore != NULL, "expected created cert to have a store\n"); + /* The cert doesn't have the archived property set (which would imply it + * doesn't show up in enumerations.) + */ + size = 0; + ret = CertGetCertificateContextProperty(cert, CERT_ARCHIVED_PROP_ID, + NULL, &size); + ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, + "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + /* Strangely, enumerating the certs in the store finds none. */ + enumCert = NULL; + count = 0; + while ((enumCert = CertEnumCertificatesInStore(cert->hCertStore, enumCert))) + count++; + ok(!count, "expected 0, got %d\n", count); + CertFreeCertificateContext(cert); +} + static void testDupCert(void) { HCERTSTORE store; @@ -1514,11 +1561,13 @@ static void testGetIssuerCert(void) /* With only the child certificate, no issuer will be found */ ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); ok(parent == NULL, "Expected no issuer\n"); /* Adding an issuer allows one (and only one) issuer to be found */ ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); ok(parent == cert1, "Expected cert1 to be the issuer\n"); parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); @@ -1529,6 +1578,7 @@ static void testGetIssuerCert(void) */ ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); ok(parent == cert2, "Expected cert2 to be the first issuer\n"); parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); @@ -1548,11 +1598,13 @@ static void testGetIssuerCert(void) /* With only the child certificate, no issuer will be found */ ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); ok(parent == NULL, "Expected no issuer\n"); /* Adding an issuer allows one (and only one) issuer to be found */ ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); ok(parent == cert1, "Expected cert1 to be the issuer\n"); parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); @@ -1563,6 +1615,7 @@ static void testGetIssuerCert(void) */ ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags); ok(parent == cert2, "Expected cert2 to be the first issuer\n"); parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags); @@ -1826,6 +1879,7 @@ static void testCertSigs(void) CryptReleaseContext(csp, 0); ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); } static const BYTE md5SignedEmptyCert[] = { @@ -2014,6 +2068,8 @@ static void testCreateSelfSignCert(void) CryptReleaseContext(csp, 0); ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError()); + /* do the same test with AT_KEYEXCHANGE and key info*/ memset(&info,0,sizeof(info)); @@ -2082,7 +2138,7 @@ static void testIntendedKeyUsage(void) if (0) { /* Crash */ - ret = CertGetIntendedKeyUsage(0, NULL, NULL, 0); + CertGetIntendedKeyUsage(0, NULL, NULL, 0); } ret = CertGetIntendedKeyUsage(0, &info, NULL, 0); ok(!ret, "expected failure\n"); @@ -2092,6 +2148,7 @@ static void testIntendedKeyUsage(void) ok(!ret, "expected failure\n"); ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, sizeof(usage_bytes)); + ok(!ret, "expected failure\n"); info.cExtension = 1; info.rgExtension = &ext; ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0); @@ -2250,6 +2307,8 @@ static void testKeyUsage(void) SetLastError(0xbaadcafe); size = sizeof(buf); ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size); + ok(ret || broken(!ret && GetLastError() == CRYPT_E_NOT_FOUND /* NT4 */), + "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError()); ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); @@ -2655,9 +2714,8 @@ static void testIsRDNAttrsInCertificateName(void) if (0) { /* Crash */ - ret = CertIsRDNAttrsInCertificateName(0, 0, NULL, NULL); - ret = CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, - NULL); + CertIsRDNAttrsInCertificateName(0, 0, NULL, NULL); + CertIsRDNAttrsInCertificateName(X509_ASN_ENCODING, 0, &name, NULL); } SetLastError(0xdeadbeef); ret = CertIsRDNAttrsInCertificateName(0, 0, &name, NULL); @@ -2931,7 +2989,7 @@ static void testHashToBeSigned(void) /* Crash */ if (0) { - ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL); + CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL); } SetLastError(0xdeadbeef); ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size); @@ -2972,6 +3030,9 @@ static void testHashToBeSigned(void) ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert, sizeof(md5SignedEmptyCert), hash, &size); + ok(ret || broken(!ret && GetLastError() == NTE_BAD_ALGID) /* NT4 */, + "CryptHashToBeSigned failed: %08x\n", GetLastError()); + ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n"); } @@ -2980,9 +3041,9 @@ static void testCompareCert(void) CERT_INFO info1 = { 0 }, info2 = { 0 }; BOOL ret; - /* Crashes - ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL); - */ + /* Crashes */ + if (0) + CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL); /* Certs with the same issuer and serial number are equal, even if they * differ in other respects (like subject). @@ -3618,6 +3679,7 @@ START_TEST(cert) testAddCert(); testCertProperties(); + testCreateCert(); testDupCert(); testFindCert(); testGetSubjectCert(); diff --git a/rostests/winetests/crypt32/chain.c b/rostests/winetests/crypt32/chain.c index a59a95a0bb1..669871b3298 100644 --- a/rostests/winetests/crypt32/chain.c +++ b/rostests/winetests/crypt32/chain.c @@ -17,13 +17,15 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include + #include #include + #include #include #include #include +#include #include "wine/test.h" @@ -139,175 +141,6 @@ static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; -static const BYTE iTunesCert0[] = { -0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75, -0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, -0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72, -0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35, -0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20, -0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20, -0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41, -0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30, -0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30, -0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b, -0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15, -0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e, -0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b, -0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73, -0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03, -0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75, -0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77, -0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d, -0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06, -0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20, -0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69, -0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82, -0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, -0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01, -0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10, -0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee, -0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51, -0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24, -0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22, -0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25, -0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd, -0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63, -0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47, -0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20, -0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c, -0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d, -0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd, -0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e, -0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53, -0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70, -0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44, -0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c, -0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01, -0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30, -0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17, -0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01, -0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76, -0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61, -0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24, -0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e, -0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63, -0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16, -0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b, -0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01, -0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48, -0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06, -0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30, -0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43, -0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55, -0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64, -0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06, -0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31, -0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30, -0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04, -0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c, -0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f, -0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6, -0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, -0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8, -0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c, -0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68, -0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96, -0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00, -0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0, -0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3, -0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88, -0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f, -0x5e,0xf6,0x7a,0xb5 }; -static const BYTE iTunesCert1[] = { -0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6, -0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, -0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65, -0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30, -0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67, -0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b, -0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d, -0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74, -0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69, -0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30, -0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72, -0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43, -0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30, -0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30, -0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32, -0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03, -0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04, -0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12, -0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74, -0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41, -0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20, -0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35, -0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73, -0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74, -0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64, -0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55, -0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75, -0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06, -0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, -0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84, -0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49, -0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35, -0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57, -0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07, -0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd, -0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d, -0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55, -0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c, -0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30, -0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55, -0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03, -0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f, -0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30, -0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e, -0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63, -0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39, -0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a, -0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68, -0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69, -0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06, -0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05, -0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01, -0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30, -0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e, -0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06, -0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70, -0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69, -0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f, -0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63, -0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14, -0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78, -0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8, -0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06, -0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00, -0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01, -0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64, -0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10, -0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35, -0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03, -0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3, -0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76, -0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40, -0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4, -0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b, -0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c, -0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d, -0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5, -0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9, -0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13, -0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64, -0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5, -0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52, -0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a }; static const BYTE verisignCA[] = { 0x30,0x82,0x02,0x3c,0x30,0x82,0x01,0xa5,0x02,0x10,0x70,0xba,0xe4,0x1d,0x10, 0xd9,0x29,0x34,0xb6,0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09, @@ -1273,7 +1106,7 @@ static const BYTE chain5_1[] = { * A chain whose end certificate is a CA. */ /* chain0_0 -> chain 7_1: - * A chain with a bad critical extension. + * A chain whose end cert has a bad critical extension. */ static const BYTE chain7_1[] = { 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, @@ -2503,6 +2336,103 @@ static const BYTE chain29_1[] = { 0x3a,0xe9,0x27,0xa4,0x57,0x27,0x34,0xa7,0x42,0xde,0x78,0x1a,0x71,0x80,0x23, 0xd6,0xd7,0x22,0xf0,0x24,0x0d,0x71,0xf1,0x2b,0xd0,0xd8,0x76,0x3d,0xef,0x4c, 0xce,0x1c,0x3b,0x83,0x1b,0x63,0x10,0x6c,0x63,0xe5,0x69 }; +/* chain0_0 -> chain30_1 -> chain30_2 + * A chain whose intermediate certificate has an unsupported critical + * extension. + */ +static const BYTE chain30_1[] = { +0x30,0x82,0x01,0xc0,0x30,0x82,0x01,0x2b,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f, +0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e, +0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe, +0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71, +0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87, +0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68, +0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36, +0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22, +0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01, +0x00,0x01,0xa3,0x30,0x30,0x2e,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x02,0x2a,0x03, +0x01,0x01,0xff,0x04,0x02,0x30,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x51,0x3e,0x35,0x1b,0x66,0x3c, +0xca,0x5e,0xf3,0xf9,0x1b,0xd5,0x03,0x13,0xf8,0xcf,0x87,0xdf,0xed,0x75,0xa6, +0xcd,0x4b,0x1c,0x15,0xd3,0xd8,0x58,0x85,0x85,0x2c,0x64,0x31,0xbd,0xbb,0xad, +0xff,0x38,0x64,0xc5,0x16,0x43,0x14,0x0e,0x71,0x35,0xf3,0xe9,0xca,0xf9,0xf4, +0x69,0xa7,0x67,0xa8,0x0f,0xc9,0xcf,0x6f,0x22,0xe5,0x39,0xb8,0xfc,0xe7,0x50, +0x82,0xf7,0xa4,0xaa,0x29,0xe1,0xa9,0xb5,0x03,0x5e,0x0b,0x5f,0x9c,0x8e,0x29, +0x64,0xe5,0xb6,0xed,0xde,0x04,0x0e,0xdb,0xad,0xa3,0xc6,0x2a,0xb0,0x12,0x86, +0x60,0xd4,0xff,0xd8,0xea,0x85,0x54,0x34,0xca,0xc1,0x85,0x4e,0xb5,0x15,0x96, +0xb7,0xa5,0x64,0x7b,0xc7,0x76,0xcb,0x04,0x75,0x9e,0x1e,0xbd,0x62,0x79,0xc5, +0x1f,0x32 }; +static const BYTE chain30_2[] = { +0x30,0x82,0x01,0x8d,0x30,0x81,0xf9,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,0x10, +0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74, +0x32,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30, +0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39, +0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13, +0x05,0x43,0x65,0x72,0x74,0x33,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02, +0x81,0x81,0x00,0xc3,0x31,0x35,0xc3,0x9d,0x8a,0x87,0x20,0xc6,0x32,0xe9,0xb1, +0xf6,0x8f,0xf9,0x05,0x73,0x1d,0xa7,0xde,0xab,0x15,0x8a,0x9c,0x7f,0x11,0x7e, +0x77,0xa0,0x42,0x80,0xf4,0x79,0xda,0x98,0x7b,0x00,0xfa,0x8f,0x0c,0xd0,0xeb, +0x8a,0x80,0xed,0x07,0xfc,0x64,0x71,0x03,0xc1,0xd6,0x2f,0x9b,0xde,0x42,0x63, +0xd9,0x79,0xea,0xdd,0x10,0xe8,0x68,0xc8,0x69,0x4f,0x4a,0x39,0x23,0x87,0xca, +0xd1,0xc9,0x77,0x14,0x30,0x85,0x9e,0xf7,0x79,0xf9,0x07,0xb7,0x7c,0x55,0xcb, +0xa7,0xd5,0xb8,0x44,0xb5,0x20,0xb5,0x01,0x5c,0xa2,0xd1,0xd5,0xad,0x0f,0x87, +0xaf,0x37,0xd1,0x39,0x0c,0x0d,0xd5,0xde,0x26,0x7a,0xed,0xf9,0x2a,0xb1,0x60, +0x65,0x2d,0x08,0x24,0x51,0x1d,0xb0,0x0a,0xb5,0x13,0xc7,0x02,0x03,0x01,0x00, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03, +0x81,0x81,0x00,0x14,0x75,0x85,0xcc,0x68,0xfe,0x98,0x6f,0xf6,0x67,0x00,0x5b, +0x0c,0xfc,0x36,0x18,0xf4,0x56,0x46,0x7c,0xb9,0xfa,0x6c,0xe6,0x37,0xaf,0x69, +0x37,0x93,0x8c,0x35,0x3a,0x1b,0x58,0x2f,0xe2,0x06,0x39,0x85,0x3f,0x73,0xcf, +0xe1,0x3f,0x27,0x19,0x60,0xc3,0x1b,0xf6,0x69,0x3b,0x8e,0x57,0x7b,0xd8,0xb9, +0xc6,0x9f,0x13,0x72,0x22,0x04,0x8f,0x5c,0x54,0x13,0x8c,0x63,0xe3,0x6b,0x70, +0x98,0xec,0xcc,0xe1,0x93,0xb1,0x4b,0x30,0x4c,0xde,0xe8,0x3c,0x68,0x38,0x44, +0x5e,0xe2,0x2b,0xf5,0xa1,0xee,0x02,0x7e,0x09,0x15,0xff,0xc9,0xf6,0xaf,0xf5, +0xcc,0xeb,0xfc,0xe7,0x3c,0x92,0xdb,0x31,0xab,0x1e,0xb8,0x9e,0xf0,0x5e,0xa3, +0x93,0xfe,0xab,0x26,0x7b,0x01,0xa8,0x98,0x88,0xbb,0xee }; +/* chain0_0 -> chain31_1: a chain whose end certificate has two CNs, a + * wildcard name "*.foo.com" and a non-wildcard name "foo.com". + */ +static const BYTE chain31_1[] = { +0x30,0x82,0x01,0xa2,0x30,0x82,0x01,0x0d,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x30,0x24,0x31,0x22,0x30,0x0e,0x06,0x03,0x55,0x04,0x03, +0x13,0x07,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x10,0x06,0x03,0x55,0x04, +0x03,0x13,0x09,0x2a,0x2e,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x81,0x9d, +0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81, +0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f, +0xe5,0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4, +0xc6,0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5, +0xa7,0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6, +0x8b,0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf, +0x6b,0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40, +0xfc,0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac, +0x85,0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23, +0xb2,0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98, +0x72,0xa3,0x02,0x03,0x01,0x00,0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0xa0,0x93,0x52,0x87,0x81,0xe2, +0xff,0x2a,0xc7,0xef,0x5f,0x3c,0xbc,0x88,0x99,0xc0,0x47,0x3e,0x13,0xe9,0x87, +0xfa,0x36,0xd7,0xb5,0xe8,0xdf,0x70,0xcc,0x36,0xe4,0x70,0x3c,0xcd,0xa2,0x0b, +0x31,0x6e,0x0a,0xb9,0x00,0xf0,0x4f,0xb6,0xc2,0xce,0xf4,0x33,0x1e,0xc0,0x29, +0xc0,0x73,0x0c,0xcf,0x28,0xa5,0x26,0x9d,0xc2,0xaf,0x85,0x30,0x81,0xbf,0xd1, +0x70,0x3f,0x69,0x15,0xc5,0x41,0x1d,0x8e,0xd4,0xfa,0x02,0xcd,0xba,0xf1,0xf2, +0x67,0xb5,0x45,0x29,0xad,0xe8,0x54,0x9a,0x0f,0x1a,0x8f,0xdf,0x16,0xf4,0xcb, +0x43,0x08,0xe5,0x78,0x2b,0x95,0xf3,0x75,0xb6,0x88,0xf0,0x6b,0x5c,0x5b,0x50, +0x04,0x91,0x3b,0x89,0x5a,0x60,0x1f,0xfc,0x36,0x53,0x32,0x36,0x0a,0x4d,0x03, +0x2c,0xd7 }; typedef struct _CONST_DATA_BLOB { @@ -2566,7 +2496,9 @@ static PCCERT_CHAIN_CONTEXT getChain(HCERTCHAINENGINE engine, CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; FILETIME fileTime; - SystemTimeToFileTime(checkTime, &fileTime); + ok(SystemTimeToFileTime(checkTime, &fileTime), + "SystemTimeToFileTime failed for day %d, month %d, year %d\n", + checkTime->wDay, checkTime->wMonth, checkTime->wYear); ret = pCertGetCertificateChain(engine, endCert, &fileTime, includeStore ? store : NULL, &chainPara, flags, NULL, &chain); if (todo & TODO_CHAIN) @@ -2590,62 +2522,64 @@ typedef struct _SimpleChainStatusCheck static void checkElementStatus(const CERT_TRUST_STATUS *expected, const CERT_TRUST_STATUS *got, const CERT_TRUST_STATUS *ignore, - DWORD todo, DWORD testIndex, DWORD chainIndex, DWORD elementIndex) + DWORD todo, LPCSTR testName, DWORD testIndex, DWORD chainIndex, + DWORD elementIndex) { if (got->dwErrorStatus == expected->dwErrorStatus) ok(got->dwErrorStatus == expected->dwErrorStatus, - "Chain %d, element [%d,%d]: expected error %08x, got %08x\n", - testIndex, chainIndex, elementIndex, expected->dwErrorStatus, + "%s[%d], element [%d,%d]: expected error %08x, got %08x\n", + testName, testIndex, chainIndex, elementIndex, expected->dwErrorStatus, got->dwErrorStatus); else if (todo & TODO_ERROR) todo_wine ok(got->dwErrorStatus == expected->dwErrorStatus || broken((got->dwErrorStatus & ~ignore->dwErrorStatus) == (expected->dwErrorStatus & ~ignore->dwErrorStatus)), - "Chain %d, element [%d,%d]: expected error %08x, got %08x\n", - testIndex, chainIndex, elementIndex, expected->dwErrorStatus, + "%s[%d], element [%d,%d]: expected error %08x, got %08x\n", + testName, testIndex, chainIndex, elementIndex, expected->dwErrorStatus, got->dwErrorStatus); else ok(got->dwErrorStatus == expected->dwErrorStatus || broken((got->dwErrorStatus & ~ignore->dwErrorStatus) == (expected->dwErrorStatus & ~ignore->dwErrorStatus)), - "Chain %d, element [%d,%d]: expected error %08x, got %08x. %08x is " + "%s[%d], element [%d,%d]: expected error %08x, got %08x. %08x is " "expected if no valid Verisign root certificate is available.\n", - testIndex, chainIndex, elementIndex, expected->dwErrorStatus, + testName, testIndex, chainIndex, elementIndex, expected->dwErrorStatus, got->dwErrorStatus, CERT_TRUST_IS_UNTRUSTED_ROOT); if (got->dwInfoStatus == expected->dwInfoStatus) ok(got->dwInfoStatus == expected->dwInfoStatus, - "Chain %d, element [%d,%d]: expected info %08x, got %08x\n", - testIndex, chainIndex, elementIndex, expected->dwInfoStatus, + "%s[%d], element [%d,%d]: expected info %08x, got %08x\n", + testName, testIndex, chainIndex, elementIndex, expected->dwInfoStatus, got->dwInfoStatus); else if (todo & TODO_INFO) todo_wine ok(got->dwInfoStatus == expected->dwInfoStatus || broken((got->dwInfoStatus & ~ignore->dwInfoStatus) == (expected->dwInfoStatus & ~ignore->dwInfoStatus)), - "Chain %d, element [%d,%d]: expected info %08x, got %08x\n", - testIndex, chainIndex, elementIndex, expected->dwInfoStatus, + "%s[%d], element [%d,%d]: expected info %08x, got %08x\n", + testName, testIndex, chainIndex, elementIndex, expected->dwInfoStatus, got->dwInfoStatus); else ok(got->dwInfoStatus == expected->dwInfoStatus || broken((got->dwInfoStatus & ~ignore->dwInfoStatus) == (expected->dwInfoStatus & ~ignore->dwInfoStatus)), - "Chain %d, element [%d,%d]: expected info %08x, got %08x\n", - testIndex, chainIndex, elementIndex, expected->dwInfoStatus, + "%s[%d], element [%d,%d]: expected info %08x, got %08x\n", + testName, testIndex, chainIndex, elementIndex, expected->dwInfoStatus, got->dwInfoStatus); } static void checkSimpleChainStatus(const CERT_SIMPLE_CHAIN *simpleChain, const SimpleChainStatusCheck *simpleChainStatus, - const CERT_TRUST_STATUS *ignore, DWORD todo, DWORD testIndex, DWORD chainIndex) + const CERT_TRUST_STATUS *ignore, DWORD todo, LPCSTR testName, DWORD testIndex, + DWORD chainIndex) { if (todo & TODO_ELEMENTS) todo_wine ok(simpleChain->cElement == simpleChainStatus->cElement, - "Chain %d: expected %d elements, got %d\n", testIndex, + "%s[%d]: expected %d elements, got %d\n", testName, testIndex, simpleChainStatus->cElement, simpleChain->cElement); else ok(simpleChain->cElement == simpleChainStatus->cElement, - "Chain %d: expected %d elements, got %d\n", testIndex, + "%s[%d]: expected %d elements, got %d\n", testName, testIndex, simpleChainStatus->cElement, simpleChain->cElement); if (simpleChain->cElement == simpleChainStatus->cElement) { @@ -2653,8 +2587,8 @@ static void checkSimpleChainStatus(const CERT_SIMPLE_CHAIN *simpleChain, for (i = 0; i < simpleChain->cElement; i++) checkElementStatus(&simpleChainStatus->rgElementStatus[i], - &simpleChain->rgpElement[i]->TrustStatus, ignore, todo, testIndex, - chainIndex, i); + &simpleChain->rgpElement[i]->TrustStatus, ignore, todo, testName, + testIndex, chainIndex, i); } } @@ -2667,10 +2601,11 @@ typedef struct _ChainStatusCheck } ChainStatusCheck; static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain, - const ChainStatusCheck *chainStatus, DWORD todo, DWORD testIndex) + const ChainStatusCheck *chainStatus, DWORD todo, LPCSTR testName, + DWORD testIndex) { ok(chain->cChain == chainStatus->cChain, - "Chain %d: expected %d simple chains, got %d\n", testIndex, + "%s[%d]: expected %d simple chains, got %d\n", testName, testIndex, chainStatus->cChain, chain->cChain); if (todo & TODO_ERROR && chain->TrustStatus.dwErrorStatus != chainStatus->status.dwErrorStatus) @@ -2680,8 +2615,8 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain, ~chainStatus->statusToIgnore.dwErrorStatus) == (chainStatus->status.dwErrorStatus & ~chainStatus->statusToIgnore.dwErrorStatus)), - "Chain %d: expected error %08x, got %08x\n", - testIndex, chainStatus->status.dwErrorStatus, + "%s[%d]: expected error %08x, got %08x\n", + testName, testIndex, chainStatus->status.dwErrorStatus, chain->TrustStatus.dwErrorStatus); else ok(chain->TrustStatus.dwErrorStatus == @@ -2690,9 +2625,9 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain, ~chainStatus->statusToIgnore.dwErrorStatus) == (chainStatus->status.dwErrorStatus & ~chainStatus->statusToIgnore.dwErrorStatus)), - "Chain %d: expected error %08x, got %08x. %08x is expected if no valid " + "%s[%d]: expected error %08x, got %08x. %08x is expected if no valid " "Verisign root certificate is available.\n", - testIndex, chainStatus->status.dwErrorStatus, + testName, testIndex, chainStatus->status.dwErrorStatus, chain->TrustStatus.dwErrorStatus, CERT_TRUST_IS_UNTRUSTED_ROOT); if (todo & TODO_INFO && chain->TrustStatus.dwInfoStatus != chainStatus->status.dwInfoStatus) @@ -2702,8 +2637,8 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain, ~chainStatus->statusToIgnore.dwInfoStatus) == (chainStatus->status.dwInfoStatus & ~chainStatus->statusToIgnore.dwInfoStatus)), - "Chain %d: expected info %08x, got %08x\n", - testIndex, chainStatus->status.dwInfoStatus, + "%s[%d]: expected info %08x, got %08x\n", + testName, testIndex, chainStatus->status.dwInfoStatus, chain->TrustStatus.dwInfoStatus); else ok(chain->TrustStatus.dwInfoStatus == @@ -2712,8 +2647,8 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain, ~chainStatus->statusToIgnore.dwInfoStatus) == (chainStatus->status.dwInfoStatus & ~chainStatus->statusToIgnore.dwInfoStatus)), - "Chain %d: expected info %08x, got %08x\n", - testIndex, chainStatus->status.dwInfoStatus, + "%s[%d]: expected info %08x, got %08x\n", + testName, testIndex, chainStatus->status.dwInfoStatus, chain->TrustStatus.dwInfoStatus); if (chain->cChain == chainStatus->cChain) { @@ -2722,7 +2657,7 @@ static void checkChainStatus(PCCERT_CHAIN_CONTEXT chain, for (i = 0; i < chain->cChain; i++) checkSimpleChainStatus(chain->rgpChain[i], &chainStatus->rgChainStatus[i], &chainStatus->statusToIgnore, - todo, testIndex, i); + todo, testName, testIndex, i); } } @@ -3112,6 +3047,25 @@ static const CERT_TRUST_STATUS elementStatus29[] = { static const SimpleChainStatusCheck simpleStatus29[] = { { sizeof(elementStatus29) / sizeof(elementStatus29[0]), elementStatus29 }, }; +static CONST_DATA_BLOB chain30[] = { + { sizeof(chain0_0), chain0_0 }, + { sizeof(chain30_1), chain30_1 }, + { sizeof(chain30_2), chain30_2 }, +}; +static const CERT_TRUST_STATUS elementStatus30[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_INVALID_EXTENSION | CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT, + CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus30[] = { + { sizeof(elementStatus30) / sizeof(elementStatus30[0]), elementStatus30 }, +}; +static CONST_DATA_BLOB chain31[] = { + { sizeof(chain0_0), chain0_0 }, + { sizeof(chain31_1), chain31_1 }, +}; static CONST_DATA_BLOB selfSignedChain[] = { { sizeof(selfSignedCert), selfSignedCert } }; @@ -3123,21 +3077,6 @@ static const SimpleChainStatusCheck selfSignedSimpleStatus[] = { { sizeof(selfSignedElementStatus) / sizeof(selfSignedElementStatus[0]), selfSignedElementStatus }, }; -static CONST_DATA_BLOB iTunesChain[] = { - { sizeof(verisignCA), verisignCA }, - { sizeof(iTunesCert0), iTunesCert0 }, - { sizeof(iTunesCert1), iTunesCert1 }, -}; -static const CERT_TRUST_STATUS iTunesElementStatus[] = { - { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, - { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_EXACT_MATCH_ISSUER }, - { CERT_TRUST_NO_ERROR, - CERT_TRUST_HAS_NAME_MATCH_ISSUER | CERT_TRUST_IS_SELF_SIGNED}, -}; -static const SimpleChainStatusCheck iTunesSimpleStatus[] = { - { sizeof(iTunesElementStatus) / sizeof(iTunesElementStatus[0]), - iTunesElementStatus }, -}; static CONST_DATA_BLOB googleChain[] = { { sizeof(verisignCA), verisignCA }, { sizeof(thawte_sgc_ca), thawte_sgc_ca }, @@ -3174,6 +3113,21 @@ static const SimpleChainStatusCheck opensslSimpleStatus[] = { { sizeof(opensslElementStatus) / sizeof(opensslElementStatus[0]), opensslElementStatus }, }; +/* The OpenSSL chain may not have its root trusted, in which case the chain + * is truncated (on Win98). + */ +static CONST_DATA_BLOB incompleteOpensslChain[] = { + { sizeof(global_sign_ca), global_sign_ca }, + { sizeof(openssl_org), openssl_org }, +}; +static const CERT_TRUST_STATUS incompleteOpensslElementStatus[] = { + { CERT_TRUST_IS_NOT_TIME_VALID, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck incompleteOpensslSimpleStatus[] = { + { sizeof(incompleteOpensslElementStatus) / sizeof(incompleteOpensslElementStatus[0]), + incompleteOpensslElementStatus }, +}; /* entrust_ca -> aaa_certificate_services -> cs_stanford_edu */ /* cs.stanford.edu's cert is only valid from 7/16/2009 to 7/16/2012, so with * the date tested (October 2007) it's not time valid. @@ -3398,29 +3352,33 @@ static ChainCheck chainCheck[] = { 1, simpleStatus28 }, 0 }, /* chain29 is handled separately elsewhere */ + /* Microsoft incorrectly ignores unknown/unsupported critical extensions on + * older Windows versions, so ignore the error on Windows. + */ + { { sizeof(chain30) / sizeof(chain30[0]), chain30 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT | + CERT_TRUST_INVALID_EXTENSION | + CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_INVALID_EXTENSION | + CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT, 0 }, + 1, simpleStatus30 }, + 0 }, { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain }, { { 0, CERT_TRUST_HAS_PREFERRED_ISSUER }, { CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, selfSignedSimpleStatus }, 0 }, - /* The iTunes chain may or may not have its root trusted, so ignore the - * error - */ - { { sizeof(iTunesChain) / sizeof(iTunesChain[0]), iTunesChain }, - { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, - { 0, 0 }, - 1, iTunesSimpleStatus }, 0 }, - /* The google chain may or may not have its root trusted, so ignore the error + /* The google chain may or may not have its root trusted, so ignore the error. + * The chain is also considered not time nested on Win98, so ignore that + * error too. */ { { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, - { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_TIME_NESTED, + CERT_TRUST_HAS_PREFERRED_ISSUER }, { CERT_TRUST_IS_NOT_TIME_VALID, 0 }, 1, googleSimpleStatus }, 0 }, - /* The openssl chain may or may not have its root trusted, so ignore the error - */ - { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, - { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, - { CERT_TRUST_IS_NOT_TIME_VALID, 0 }, - 1, opensslSimpleStatus }, 0 }, /* The stanford chain may or may not have its root trusted, so ignore the error */ { { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain }, @@ -3449,6 +3407,20 @@ static ChainCheck chainCheckNoStore[] = { 0 }, }; + /* The openssl chain may or may not have its root trusted, so ignore the error + */ +static ChainCheck opensslChainCheck = + { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, + { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_NOT_TIME_VALID, 0 }, + 1, opensslSimpleStatus }, 0 }; +static ChainCheck incompleteOpensslChainCheck = + { { sizeof(incompleteOpensslChain) / sizeof(incompleteOpensslChain[0]), + incompleteOpensslChain }, + { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_PARTIAL_CHAIN, 0 }, + 1, incompleteOpensslSimpleStatus }, 0 }; + /* Chain27 checks a certificate with a subject alternate name containing an * embedded NULL. Newer crypt32 versions fail to decode such alternate names, * correctly prohibiting them. Older crypt32 versions do not. Rather than @@ -3572,7 +3544,7 @@ static void testGetCertChain(void) { ok(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE, "expected CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n"); - CertFreeCertificateChain(chain); + pCertFreeCertificateChain(chain); } oids[0] = oid_server_auth; ret = pCertGetCertificateChain(NULL, cert, &fileTime, store, ¶, @@ -3583,7 +3555,7 @@ static void testGetCertChain(void) ok(!(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE), "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n"); - CertFreeCertificateChain(chain); + pCertFreeCertificateChain(chain); } oids[1] = one_two_three; para.RequestedUsage.Usage.cUsageIdentifier = 2; @@ -3595,7 +3567,7 @@ static void testGetCertChain(void) { ok(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE, "expected CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n"); - CertFreeCertificateChain(chain); + pCertFreeCertificateChain(chain); } para.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; ret = pCertGetCertificateChain(NULL, cert, &fileTime, store, ¶, @@ -3606,7 +3578,7 @@ static void testGetCertChain(void) ok(!(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE), "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n"); - CertFreeCertificateChain(chain); + pCertFreeCertificateChain(chain); } CertCloseStore(store, 0); CertFreeCertificateContext(cert); @@ -3618,10 +3590,32 @@ static void testGetCertChain(void) if (chain) { checkChainStatus(chain, &chainCheck[i].status, chainCheck[i].todo, - i); + "chainCheck", i); pCertFreeCertificateChain(chain); } } + chain = getChain(NULL, &opensslChainCheck.certs, 0, TRUE, &oct2007, + opensslChainCheck.todo, 0); + if (chain) + { + ok(chain->TrustStatus.dwErrorStatus == + opensslChainCheck.status.status.dwErrorStatus || + broken((chain->TrustStatus.dwErrorStatus & + ~incompleteOpensslChainCheck.status.statusToIgnore.dwErrorStatus) == + (incompleteOpensslChainCheck.status.status.dwErrorStatus & + ~incompleteOpensslChainCheck.status.statusToIgnore.dwErrorStatus)), + "unexpected chain error status %08x\n", + chain->TrustStatus.dwErrorStatus); + if (opensslChainCheck.status.status.dwErrorStatus == + chain->TrustStatus.dwErrorStatus) + checkChainStatus(chain, &opensslChainCheck.status, + opensslChainCheck.todo, "opensslChainCheck", 0); + else + checkChainStatus(chain, &incompleteOpensslChainCheck.status, + incompleteOpensslChainCheck.todo, "incompleteOpensslChainCheck", + 0); + pCertFreeCertificateChain(chain); + } for (i = 0; i < sizeof(chainCheckNoStore) / sizeof(chainCheckNoStore[0]); i++) { @@ -3630,7 +3624,7 @@ static void testGetCertChain(void) if (chain) { checkChainStatus(chain, &chainCheckNoStore[i].status, - chainCheckNoStore[i].todo, i); + chainCheckNoStore[i].todo, "chainCheckNoStore", i); pCertFreeCertificateChain(chain); } } @@ -3649,10 +3643,11 @@ static void testGetCertChain(void) if (chainCheckEmbeddedNull.status.status.dwErrorStatus == chain->TrustStatus.dwErrorStatus) checkChainStatus(chain, &chainCheckEmbeddedNull.status, - chainCheckEmbeddedNull.todo, 0); + chainCheckEmbeddedNull.todo, "chainCheckEmbeddedNull", 0); else checkChainStatus(chain, &chainCheckEmbeddedNullBroken.status, - chainCheckEmbeddedNullBroken.todo, 0); + chainCheckEmbeddedNullBroken.todo, "chainCheckEmbeddedNullBroken", + 0); pCertFreeCertificateChain(chain); } } @@ -3672,9 +3667,11 @@ static void test_CERT_CHAIN_PARA_cbSize(void) ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain0_0, sizeof(chain0_0), CERT_STORE_ADD_ALWAYS, NULL); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, chain0_1, sizeof(chain0_1), CERT_STORE_ADD_ALWAYS, &cert); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); for (i = 0; i < sizeof(CERT_CHAIN_PARA) + 2; i++) { @@ -3744,6 +3741,33 @@ static const ChainPolicyCheck basePolicyCheck[] = { { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 }, }; +/* Windows NT 4 has a different error code when the validity period doesn't + * nest. (It's arguably more correct than other Windows versions, but since + * others do not emulate its behavior, we mark its behavior broken.) + */ +static const CERT_CHAIN_POLICY_STATUS badDateNestingStatus = + { 0, CERT_E_VALIDITYPERIODNESTING, 0, 0, NULL }; + +static const ChainPolicyCheck ignoredBadDateNestingBasePolicyCheck = { + { sizeof(chain2) / sizeof(chain2[0]), chain2 }, + { 0, CERT_E_EXPIRED, 0, 1, NULL}, &badDateNestingStatus, TODO_ELEMENTS +}; + +static const ChainPolicyCheck ignoredInvalidDateBasePolicyCheck = { + { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, + { 0, CERT_E_EXPIRED, 0, 1, NULL}, &badDateNestingStatus, TODO_ELEMENTS +}; + +static const ChainPolicyCheck ignoredInvalidUsageBasePolicyCheck = { + { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { 0, CERT_E_EXPIRED, 0, 1, NULL}, NULL, TODO_ERROR +}; + +static const ChainPolicyCheck invalidUsageBasePolicyCheck = { + { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { 0, CERT_E_WRONG_USAGE, 0, 1, NULL}, NULL, 0 +}; + static const ChainPolicyCheck sslPolicyCheck[] = { { { sizeof(chain0) / sizeof(chain0[0]), chain0 }, { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, @@ -3787,33 +3811,41 @@ static const ChainPolicyCheck sslPolicyCheck[] = { { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 }, }; +static const ChainPolicyCheck ignoredUnknownCAPolicyCheck = { + { sizeof(chain0) / sizeof(chain0[0]), chain0 }, + { 0, CERT_E_EXPIRED, 0, 0, NULL }, NULL, 0 +}; + static const ChainPolicyCheck googlePolicyCheckWithMatchingNameExpired = { { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, { 0, CERT_E_EXPIRED, 0, 0, NULL}, NULL, 0 }; +/* Win98 sees the chain as expired, even though it isn't for the date tested */ +static const CERT_CHAIN_POLICY_STATUS expiredStatus = + { 0, CERT_E_EXPIRED, 0, 0, NULL }; + static const ChainPolicyCheck googlePolicyCheckWithMatchingName = { { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, - { 0, 0, -1, -1, NULL}, NULL, 0 + { 0, 0, -1, -1, NULL}, &expiredStatus, 0 }; /* Windows NT 4 has a different error code when the name doesn't match. */ static const CERT_CHAIN_POLICY_STATUS noMatchingNameBrokenStatus = { 0, CERT_E_ROLE, 0, 0, NULL }; -static const ChainPolicyCheck iTunesPolicyCheckWithoutMatchingName = { - { sizeof(iTunesChain) / sizeof(iTunesChain[0]), iTunesChain }, - { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &noMatchingNameBrokenStatus, 0 -}; +/* Win98 does not trust the root of the OpenSSL chain or the Stanford chain */ +static const CERT_CHAIN_POLICY_STATUS untrustedRootStatus = + { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }; static const ChainPolicyCheck opensslPolicyCheckWithMatchingName = { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, - { 0, 0, -1, -1, NULL}, NULL, 0 + { 0, 0, -1, -1, NULL}, &untrustedRootStatus, 0 }; static const ChainPolicyCheck opensslPolicyCheckWithoutMatchingName = { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, - { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0 + { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &untrustedRootStatus, 0 }; static const ChainPolicyCheck winehqPolicyCheckWithMatchingName = { @@ -3828,11 +3860,26 @@ static const ChainPolicyCheck winehqPolicyCheckWithoutMatchingName = { static const ChainPolicyCheck stanfordPolicyCheckWithMatchingName = { { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain }, - { 0, 0, -1, -1, NULL}, NULL, 0 + { 0, 0, -1, -1, NULL}, &untrustedRootStatus, 0 }; static const ChainPolicyCheck stanfordPolicyCheckWithoutMatchingName = { { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain }, + { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &untrustedRootStatus, 0 +}; + +static const ChainPolicyCheck invalidExtensionPolicyCheck = { + { sizeof(chain30) / sizeof(chain30[0]), chain30 }, + { 0, CERT_E_CRITICAL, 0, 1, NULL}, &badDateNestingStatus, 0 +}; + +static const ChainPolicyCheck fooPolicyCheckWithMatchingName = { + { sizeof(chain31) / sizeof(chain31[0]), chain31 }, + { 0, 0, -1, -1, NULL}, NULL, 0 +}; + +static const ChainPolicyCheck fooPolicyCheckWithoutMatchingName = { + { sizeof(chain31) / sizeof(chain31[0]), chain31 }, { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0 }; @@ -3938,8 +3985,8 @@ static const char *num_to_str(WORD num) } static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine, - const ChainPolicyCheck *check, DWORD testIndex, SYSTEMTIME *sysTime, - PCERT_CHAIN_POLICY_PARA para) + const ChainPolicyCheck *check, LPCSTR testName, DWORD testIndex, + SYSTEMTIME *sysTime, PCERT_CHAIN_POLICY_PARA para) { PCCERT_CHAIN_CONTEXT chain = getChain(engine, &check->certs, 0, TRUE, sysTime, check->todo, testIndex); @@ -3952,20 +3999,23 @@ static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine, if (check->todo & TODO_POLICY) todo_wine ok(ret, - "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n", + "%s[%d](%s): CertVerifyCertificateChainPolicy failed: %08x\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, GetLastError()); + GetLastError()); else { if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) { - skip("%d: missing policy %s, skipping test\n", testIndex, + skip("%s[%d]: missing policy %s, skipping test\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy); pCertFreeCertificateChain(chain); return; } - ok(ret, "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n", - IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex, + ok(ret, "%s[%d](%s): CertVerifyCertificateChainPolicy failed: %08x\n", + testName, testIndex, + IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, GetLastError()); } if (ret) @@ -3975,22 +4025,25 @@ static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine, broken(policyStatus.dwError == CERT_TRUST_NO_ERROR) || (check->brokenStatus && broken(policyStatus.dwError == check->brokenStatus->dwError)), - "%s[%d]: expected %08x, got %08x\n", + "%s[%d](%s): expected %08x, got %08x\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, check->status.dwError, policyStatus.dwError); + check->status.dwError, policyStatus.dwError); else ok(policyStatus.dwError == check->status.dwError || broken(policyStatus.dwError == CERT_TRUST_NO_ERROR) || (check->brokenStatus && broken(policyStatus.dwError == check->brokenStatus->dwError)), - "%s[%d]: expected %08x, got %08x\n", + "%s[%d](%s): expected %08x, got %08x\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, check->status.dwError, policyStatus.dwError); + check->status.dwError, policyStatus.dwError); if (policyStatus.dwError != check->status.dwError) { - skip("%s[%d]: error %08x doesn't match expected %08x, not checking indexes\n", + skip("%s[%d](%s): error %08x doesn't match expected %08x, not checking indexes\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, policyStatus.dwError, check->status.dwError); + policyStatus.dwError, check->status.dwError); pCertFreeCertificateChain(chain); return; } @@ -3999,43 +4052,114 @@ static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine, check->status.lChainIndex || (check->brokenStatus && broken(policyStatus.lChainIndex == check->brokenStatus->lChainIndex)), - "%s[%d]: expected %d, got %d\n", + "%s[%d](%s): expected %d, got %d\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, check->status.lChainIndex, - policyStatus.lChainIndex); + check->status.lChainIndex, policyStatus.lChainIndex); else ok(policyStatus.lChainIndex == check->status.lChainIndex || (check->brokenStatus && broken(policyStatus.lChainIndex == check->brokenStatus->lChainIndex)), - "%s[%d]: expected %d, got %d\n", + "%s[%d](%s): expected %d, got %d\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, check->status.lChainIndex, policyStatus.lChainIndex); if (check->todo & TODO_ELEMENTS) todo_wine ok(policyStatus.lElementIndex == check->status.lElementIndex || (check->brokenStatus && broken(policyStatus.lElementIndex == check->brokenStatus->lElementIndex)), - "%s[%d]: expected %d, got %d\n", + "%s[%d](%s): expected %d, got %d\n", + testName, testIndex, IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, check->status.lElementIndex, policyStatus.lElementIndex); else ok(policyStatus.lElementIndex == check->status.lElementIndex || (check->brokenStatus && broken(policyStatus.lElementIndex == check->brokenStatus->lElementIndex)), - "%s[%d]: expected %d, got %d\n", + testName, testIndex, + "%s[%d](%s): expected %d, got %d\n", IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, - testIndex, check->status.lElementIndex, policyStatus.lElementIndex); } pCertFreeCertificateChain(chain); } } +#define CHECK_CHAIN_POLICY_STATUS_ARRAY(policy, engine, array, date, para) \ + do { \ + DWORD i; \ + for (i = 0; i < sizeof(array) / sizeof(array)[0]; i++) \ + checkChainPolicyStatus((policy), (engine), &(array)[i], \ + #array, i, (date), (para)); \ + } while(0) + +#define CHECK_CHAIN_POLICY_STATUS(policy, engine, policyCheck, date, para) \ + checkChainPolicyStatus((policy), (engine), &(policyCheck), \ + #policyCheck, 0, (date), (para)) + +static void check_base_policy(void) +{ + CERT_CHAIN_POLICY_PARA policyPara = { 0 }; + + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_BASE, NULL, + basePolicyCheck, &oct2007, NULL); + policyPara.cbSize = sizeof(policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL, + ignoredUnknownCAPolicyCheck, &oct2007, &policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG | + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL, + ignoredBadDateNestingBasePolicyCheck, &oct2007, &policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL, + ignoredInvalidDateBasePolicyCheck, &oct2007, &policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG | + CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG; + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG | + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | + CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL, + ignoredInvalidUsageBasePolicyCheck, &oct2007, &policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG | + CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL, + invalidUsageBasePolicyCheck, &oct2007, &policyPara); + /* Test chain30, which has an invalid critical extension in an intermediate + * cert, against the base policy. + */ + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_BASE, NULL, + invalidExtensionPolicyCheck, &oct2007, &policyPara); +} + +static void check_authenticode_policy(void) +{ + CERT_CHAIN_POLICY_PARA policyPara = { 0 }; + SYSTEMTIME epochStart = { 0 }; + + /* The authenticode policy doesn't seem to check anything beyond the base + * policy. It might check for chains signed by the MS test cert, but none + * of these chains is. + */ + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_AUTHENTICODE, NULL, + authenticodePolicyCheck, &oct2007, NULL); + policyPara.cbSize = sizeof(policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_AUTHENTICODE, NULL, + ignoredUnknownCAPolicyCheck, &oct2007, &policyPara); + epochStart.wDay = epochStart.wMonth = 1; + epochStart.wYear = 1601; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_AUTHENTICODE, NULL, + ignoredUnknownCAPolicyCheck, &epochStart, &policyPara); + policyPara.dwFlags = CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_AUTHENTICODE, NULL, + ignoredInvalidDateBasePolicyCheck, &oct2007, &policyPara); +} + static void check_ssl_policy(void) { - DWORD i; CERT_CHAIN_POLICY_PARA policyPara = { 0 }; SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslPolicyPara = { { 0 } }; WCHAR winehq[] = { 'w','i','n','e','h','q','.','o','r','g',0 }; @@ -4058,120 +4182,114 @@ static void check_ssl_policy(void) 'w','i','n','e','h','q','.','o','r','g',0 }; WCHAR a_dot_b_dot_winehq_dot_org[] = { 'a','.','b','.', 'w','i','n','e','h','q','.','o','r','g',0 }; + WCHAR foo_dot_com[] = { 'f','o','o','.','c','o','m',0 }; + WCHAR afoo_dot_com[] = { 'a','f','o','o','.','c','o','m',0 }; + WCHAR a_dot_foo_dot_com[] = { 'a','.','f','o','o','.','c','o','m',0 }; HCERTSTORE testRoot; CERT_CHAIN_ENGINE_CONFIG engineConfig = { sizeof(engineConfig), 0 }; HCERTCHAINENGINE engine; /* Check ssl policy with no parameter */ - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, NULL); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, NULL); /* Check again with a policy parameter that specifies nothing */ - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* Check yet again, but specify an empty SSL_EXTRA_CERT_CHAIN_POLICY_PARA * argument. */ policyPara.pvExtraPolicyPara = &sslPolicyPara; - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* And again, but specify the auth type as a client */ sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT; - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* And again, but specify the auth type as a server */ sslPolicyPara.dwAuthType = AUTHTYPE_SERVER; - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* And again authenticating a client, but specify the size of the policy * parameter. */ U(sslPolicyPara).cbSize = sizeof(sslPolicyCheck); sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT; - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* One more time authenticating a client, but specify winehq.org as the * server name. */ sslPolicyPara.pwszServerName = winehq; - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* And again authenticating a server, still specifying winehq.org as the * server name. */ sslPolicyPara.dwAuthType = AUTHTYPE_SERVER; - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); /* And again authenticating a server, this time specifying the size of the * policy param. */ policyPara.cbSize = sizeof(policyPara); - for (i = 0; - i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i], - i, &oct2007, &policyPara); - /* Yet again, but checking the iTunes chain, which contains a name - * extension. + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_SSL, NULL, sslPolicyCheck, + &oct2007, &policyPara); + /* And again, specifying a chain with an untrusted root, but ignoring + * unknown CAs. */ - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &iTunesPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara); + sslPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + ignoredUnknownCAPolicyCheck, &oct2007, &policyPara); + sslPolicyPara.fdwChecks = 0; /* And again, but checking the Google chain at a bad date */ sslPolicyPara.pwszServerName = google_dot_com; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &googlePolicyCheckWithMatchingNameExpired, 0, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + googlePolicyCheckWithMatchingNameExpired, &oct2007, &policyPara); + /* Again checking the Google chain at a bad date, but ignoring date + * errors. + */ + sslPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + googlePolicyCheckWithMatchingName, &oct2007, &policyPara); + sslPolicyPara.fdwChecks = 0; /* And again, but checking the Google chain at a good date */ sslPolicyPara.pwszServerName = google_dot_com; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &googlePolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + googlePolicyCheckWithMatchingName, &oct2009, &policyPara); /* Check again with the openssl cert, which has a wildcard in its name, * with various combinations of matching and non-matching names. * With "a.openssl.org": match */ sslPolicyPara.pwszServerName = a_dot_openssl_dot_org; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &opensslPolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + opensslPolicyCheckWithMatchingName, &oct2009, &policyPara); /* With "openssl.org": no match */ sslPolicyPara.pwszServerName = openssl_dot_org; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + opensslPolicyCheckWithoutMatchingName, &oct2009, &policyPara); /* With "fopenssl.org": no match */ sslPolicyPara.pwszServerName = fopenssl_dot_org; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + opensslPolicyCheckWithoutMatchingName, &oct2009, &policyPara); /* with "a.b.openssl.org": no match */ sslPolicyPara.pwszServerName = a_dot_b_dot_openssl_dot_org; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + opensslPolicyCheckWithoutMatchingName, &oct2009, &policyPara); /* Check again with the cs.stanford.edu, which has both cs.stanford.edu * and www.cs.stanford.edu in its subject alternative name. * With "cs.stanford.edu": match */ sslPolicyPara.pwszServerName = cs_dot_stanford_dot_edu; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + stanfordPolicyCheckWithMatchingName, &oct2009, &policyPara); /* With "www.cs.stanford.edu": match */ sslPolicyPara.pwszServerName = www_dot_cs_dot_stanford_dot_edu; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + stanfordPolicyCheckWithMatchingName, &oct2009, &policyPara); /* With "a.cs.stanford.edu": no match */ sslPolicyPara.pwszServerName = a_dot_cs_dot_stanford_dot_edu; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, - &stanfordPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + stanfordPolicyCheckWithoutMatchingName, &oct2009, &policyPara); /* Check chain29, which has a wildcard in its subject alternative name, * but not in its distinguished name. * Step 1: create a chain engine that trusts chain29's root. @@ -4181,25 +4299,49 @@ static void check_ssl_policy(void) CertAddEncodedCertificateToStore(testRoot, X509_ASN_ENCODING, chain0_0, sizeof(chain0_0), CERT_STORE_ADD_ALWAYS, NULL); engineConfig.hExclusiveRoot = testRoot; - if (!CertCreateCertificateChainEngine(&engineConfig, &engine)) + if (!pCertCreateCertificateChainEngine(&engineConfig, &engine)) { skip("Couldn't create chain engine\n"); return; } /* With "winehq.org": no match */ sslPolicyPara.pwszServerName = winehq; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine, - &winehqPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine, + winehqPolicyCheckWithoutMatchingName, &oct2007, &policyPara); /* With "test.winehq.org": match */ sslPolicyPara.pwszServerName = test_dot_winehq_dot_org; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine, - &winehqPolicyCheckWithMatchingName, 0, &oct2007, &policyPara); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine, + winehqPolicyCheckWithMatchingName, &oct2007, &policyPara); /* With "a.b.winehq.org": no match */ sslPolicyPara.pwszServerName = a_dot_b_dot_winehq_dot_org; - checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine, - &winehqPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara); - CertFreeCertificateChainEngine(engine); + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine, + winehqPolicyCheckWithoutMatchingName, &oct2007, &policyPara); + /* When specifying to ignore name mismatch: match */ + sslPolicyPara.fdwChecks |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, engine, + winehqPolicyCheckWithMatchingName, &oct2007, &policyPara); + pCertFreeCertificateChainEngine(engine); CertCloseStore(testRoot, 0); + /* Test chain30, which has an invalid critical extension in an intermediate + * cert, against the SSL policy. + */ + sslPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA; + sslPolicyPara.pwszServerName = NULL; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + invalidExtensionPolicyCheck, &oct2007, &policyPara); + /* Test chain31, which has two CNs, "*.foo.com" and "foo.com", against + * some names that match one of the CNs: + */ + sslPolicyPara.pwszServerName = foo_dot_com; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + fooPolicyCheckWithMatchingName, &oct2007, &policyPara); + sslPolicyPara.pwszServerName = a_dot_foo_dot_com; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + fooPolicyCheckWithMatchingName, &oct2007, &policyPara); + /* and against a name that doesn't match either CN: */ + sslPolicyPara.pwszServerName = afoo_dot_com; + CHECK_CHAIN_POLICY_STATUS(CERT_CHAIN_POLICY_SSL, NULL, + fooPolicyCheckWithoutMatchingName, &oct2007, &policyPara); } static void testVerifyCertChainPolicy(void) @@ -4210,7 +4352,6 @@ static void testVerifyCertChainPolicy(void) PCCERT_CHAIN_CONTEXT chain; CERT_CHAIN_POLICY_STATUS policyStatus = { 0 }; CERT_CHAIN_POLICY_PARA policyPara = { 0 }; - DWORD i; if (!pCertVerifyCertificateChainPolicy) { @@ -4264,24 +4405,11 @@ static void testVerifyCertChainPolicy(void) pCertFreeCertificateChain(chain); CertFreeCertificateContext(cert); - for (i = 0; - i < sizeof(basePolicyCheck) / sizeof(basePolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_BASE, NULL, - &basePolicyCheck[i], i, &oct2007, NULL); + check_base_policy(); check_ssl_policy(); - /* The authenticode policy doesn't seem to check anything beyond the base - * policy. It might check for chains signed by the MS test cert, but none - * of these chains is. - */ - for (i = 0; i < - sizeof(authenticodePolicyCheck) / sizeof(authenticodePolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_AUTHENTICODE, NULL, - &authenticodePolicyCheck[i], i, &oct2007, NULL); - for (i = 0; i < - sizeof(basicConstraintsPolicyCheck) / sizeof(basicConstraintsPolicyCheck[0]); - i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, NULL, - &basicConstraintsPolicyCheck[i], i, &oct2007, NULL); + check_authenticode_policy(); + CHECK_CHAIN_POLICY_STATUS_ARRAY(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, NULL, + basicConstraintsPolicyCheck, &oct2007, NULL); } START_TEST(chain) @@ -4294,9 +4422,9 @@ START_TEST(chain) pCertVerifyCertificateChainPolicy = (void*)GetProcAddress(hCrypt32, "CertVerifyCertificateChainPolicy"); testCreateCertChainEngine(); - if (!pCertGetCertificateChain) + if (!pCertGetCertificateChain || !pCertFreeCertificateChain) { - win_skip("CertGetCertificateChain() is not available\n"); + win_skip("Cert*CertificateChain functions not available\n"); } else { diff --git a/rostests/winetests/crypt32/crl.c b/rostests/winetests/crypt32/crl.c index bb622198aa7..313ebb3cf30 100644 --- a/rostests/winetests/crypt32/crl.c +++ b/rostests/winetests/crypt32/crl.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include + #include #include #include @@ -102,7 +102,6 @@ static void testCreateCRL(void) ok(!context && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT), "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE); context = CertCreateCRLContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); - GLE = GetLastError(); ok(!context, "Expected failure\n"); context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL, sizeof(signedCRL) - 1); @@ -205,6 +204,7 @@ static void testAddCRL(void) /* Normal cases: a "signed" CRL is okay.. */ ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL); + ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError()); /* and an unsigned one is too. */ ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL), CERT_STORE_ADD_ALWAYS, NULL); @@ -408,9 +408,9 @@ static void testFindCRL(void) BOOL ret; if (!store) return; - if (!pCertFindCRLInStore) + if (!pCertFindCRLInStore || !pCertFindCertificateInCRL) { - win_skip("CertFindCRLInStore() is not available\n"); + win_skip("CertFindCRLInStore or CertFindCertificateInCRL not available\n"); return; } @@ -477,9 +477,9 @@ static void testFindCRL(void) if (0) { /* Crash or return NULL/STATUS_ACCESS_VIOLATION */ - context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR, NULL, + pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR, NULL, NULL); - context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR, + pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR, &issuedForPara, NULL); } /* Test whether the cert matches the CRL in the store */ @@ -521,7 +521,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(cert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -557,7 +557,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(cert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -586,7 +586,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(cert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -626,7 +626,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -646,7 +646,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -663,7 +663,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -680,7 +680,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -697,7 +697,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(rootCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(rootCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -716,7 +716,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -734,7 +734,7 @@ static void testFindCRL(void) PCRL_ENTRY entry; count++; - if (CertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && + if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) && entry) revoked_count++; } @@ -906,6 +906,7 @@ static void testCRLProperties(void) size = sizeof(hashProperty); ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, hashProperty, &size); + ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError()); ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n"); /* Delete the (bogus) hash, and get the real one */ ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL); diff --git a/rostests/winetests/crypt32/ctl.c b/rostests/winetests/crypt32/ctl.c index 8ee26526289..f292a4c06d6 100644 --- a/rostests/winetests/crypt32/ctl.c +++ b/rostests/winetests/crypt32/ctl.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include + #include #include #include @@ -213,6 +213,7 @@ static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID, memset(hashProperty, 0, sizeof(hashProperty)); size = sizeof(hash); ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size); + ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError()); ret = CertGetCTLContextProperty(context, propID, hashProperty, &size); ok(ret, "CertGetCTLContextProperty failed: %08x\n", GetLastError()); if (ret) diff --git a/rostests/winetests/crypt32/encode.c b/rostests/winetests/crypt32/encode.c index cc59a59e6a5..5d9e76be04f 100644 --- a/rostests/winetests/crypt32/encode.c +++ b/rostests/winetests/crypt32/encode.c @@ -121,7 +121,7 @@ static void test_encodeInt(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); - if (buf) + if (ret) { ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", buf[0]); @@ -140,7 +140,7 @@ static void test_encodeInt(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); - if (buf) + if (ret) { ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", buf[0]); @@ -164,7 +164,7 @@ static void test_encodeInt(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); - if (buf) + if (ret) { ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", buf[0]); @@ -187,7 +187,7 @@ static void test_encodeInt(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); - if (buf) + if (ret) { ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n", buf[0]); @@ -256,7 +256,7 @@ static void test_decodeInt(DWORD dwEncoding) ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize); ok(buf != NULL, "Expected allocated buffer\n"); - if (buf) + if (ret) { ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n", ints[i].val, *(int *)buf); @@ -276,7 +276,7 @@ static void test_decodeInt(DWORD dwEncoding) ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize); ok(buf != NULL, "Expected allocated buffer\n"); - if (buf) + if (ret) { CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; @@ -301,7 +301,7 @@ static void test_decodeInt(DWORD dwEncoding) ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError()); ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize); ok(buf != NULL, "Expected allocated buffer\n"); - if (buf) + if (ret) { CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; @@ -317,7 +317,7 @@ static void test_decodeInt(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm, sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf); LocalFree(buf); @@ -326,7 +326,7 @@ static void test_decodeInt(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes, sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf); LocalFree(buf); @@ -388,7 +388,7 @@ static void test_encodeEnumerated(DWORD dwEncoding) &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); - if (buf) + if (ret) { ok(buf[0] == 0xa, "Got unexpected type %d for enumerated (expected 0xa)\n", @@ -456,7 +456,7 @@ static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType, ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(), GetLastError()); ok(buf != NULL, "Expected an allocated buffer\n"); - if (buf) + if (ret) { ok(buf[0] == time->encodedTime[0], "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0], @@ -765,7 +765,7 @@ static void test_encodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), "Got unexpected encoding for empty name\n"); @@ -788,7 +788,7 @@ static void test_encodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)), "Got unexpected encoding for empty RDN array\n"); @@ -831,7 +831,7 @@ static void test_encodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)), "Got unexpected encoding for two RDN array\n"); @@ -845,7 +845,7 @@ static void test_encodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size); ok(!memcmp(buf, encodedTwoRDNs, size), @@ -915,7 +915,7 @@ static void test_encodeUnicodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), "Got unexpected encoding for empty name\n"); @@ -955,7 +955,7 @@ static void test_encodeUnicodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)), "Got unexpected encoding for two RDN array\n"); @@ -969,7 +969,7 @@ static void test_encodeUnicodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size); ok(!memcmp(buf, encodedTwoRDNs, size), @@ -982,7 +982,7 @@ static void test_encodeUnicodeName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(anyType), "Unexpected size %d\n", size); ok(!memcmp(buf, anyType, size), "Unexpected value\n"); @@ -1081,7 +1081,7 @@ static void test_decodeName(DWORD dwEncoding) /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My * decoder works the same way, so only test the count. */ - if (buf) + if (ret) { ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize); ok(((CERT_NAME_INFO *)buf)->cRDN == 0, @@ -1109,7 +1109,7 @@ static void test_decodeName(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf; @@ -1125,7 +1125,7 @@ static void test_decodeName(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { static CHAR oid_sur_name[] = szOID_SUR_NAME, oid_common_name[] = szOID_COMMON_NAME; @@ -1177,7 +1177,7 @@ static void test_decodeUnicodeName(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == sizeof(CERT_NAME_INFO), "Got wrong bufSize %d\n", bufSize); @@ -1193,7 +1193,7 @@ static void test_decodeUnicodeName(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf; @@ -1209,7 +1209,7 @@ static void test_decodeUnicodeName(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { static CHAR oid_sur_name[] = szOID_SUR_NAME, oid_common_name[] = szOID_COMMON_NAME; @@ -1322,7 +1322,7 @@ static void test_encodeNameValue(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n", size); @@ -1459,7 +1459,7 @@ static void test_encodeAltName(DWORD dwEncoding) /* Test with empty info */ ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "Wrong size %d\n", size); ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); @@ -1476,7 +1476,7 @@ static void test_encodeAltName(DWORD dwEncoding) entry.dwAltNameChoice = CERT_ALT_NAME_URL; ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(emptyURL), "Wrong size %d\n", size); ok(!memcmp(buf, emptyURL, size), "Unexpected value\n"); @@ -1486,7 +1486,7 @@ static void test_encodeAltName(DWORD dwEncoding) U(entry).pwszURL = (LPWSTR)url; ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(encodedURL), "Wrong size %d\n", size); ok(!memcmp(buf, encodedURL, size), "Unexpected value\n"); @@ -1507,7 +1507,7 @@ static void test_encodeAltName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { /* This succeeds, but it shouldn't, so don't worry about conforming */ LocalFree(buf); @@ -1517,7 +1517,7 @@ static void test_encodeAltName(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size); ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n"); @@ -1529,7 +1529,7 @@ static void test_encodeAltName(DWORD dwEncoding) U(entry).IPAddress.pbData = (LPBYTE)localhost; ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size); ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n"); @@ -1540,7 +1540,7 @@ static void test_encodeAltName(DWORD dwEncoding) U(entry).pszRegisteredID = oid; ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(encodedOidName), "Wrong size %d\n", size); ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n"); @@ -1552,7 +1552,7 @@ static void test_encodeAltName(DWORD dwEncoding) U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName; ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size); ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n"); @@ -1596,7 +1596,7 @@ static void test_decodeAltName(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1607,7 +1607,7 @@ static void test_decodeAltName(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL, emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1626,7 +1626,7 @@ static void test_decodeAltName(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL, encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1641,7 +1641,7 @@ static void test_decodeAltName(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName, encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1657,7 +1657,7 @@ static void test_decodeAltName(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr, encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1676,7 +1676,7 @@ static void test_decodeAltName(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName, sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1693,7 +1693,7 @@ static void test_decodeAltName(DWORD dwEncoding) encodedDirectoryName, sizeof(encodedDirectoryName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { info = (CERT_ALT_NAME_INFO *)buf; @@ -1887,7 +1887,7 @@ static void test_encodeUnicodeNameValue(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */), "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == unicodeResults[i].encoded.cbData, "Value type %d: expected size %d, got %d\n", @@ -1908,7 +1908,7 @@ static void test_encodeUnicodeNameValue(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == unicodeWeirdness[i].encoded.cbData, "Value type %d: expected size %d, got %d\n", @@ -1995,7 +1995,7 @@ static void test_encodeOctets(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError()); - if (buf) + if (ret) { ok(buf[0] == 4, "Got unexpected type %d for octet string (expected 4)\n", buf[0]); @@ -2026,7 +2026,7 @@ static void test_decodeOctets(DWORD dwEncoding) "Expected size >= %d, got %d\n", (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize); ok(buf != NULL, "Expected allocated buffer\n"); - if (buf) + if (ret) { CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf; @@ -2081,7 +2081,7 @@ static void test_encodeBits(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == bits[i].encoded[1] + 2, "%d: Got unexpected size %d, expected %d\n", i, bufSize, @@ -2109,7 +2109,7 @@ static void test_decodeBits(DWORD dwEncoding) bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRYPT_BIT_BLOB *blob; @@ -2131,7 +2131,7 @@ static void test_decodeBits(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRYPT_BIT_BLOB *blob; @@ -2196,7 +2196,7 @@ static void test_encodeBasicConstraints(DWORD dwEncoding) &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == constraints2[i].encoded[1] + 2, "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2, @@ -2214,7 +2214,7 @@ static void test_encodeBasicConstraints(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize); ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)), @@ -2230,7 +2230,7 @@ static void test_encodeBasicConstraints(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize); ok(!memcmp(buf, constraintWithDomainName, @@ -2260,7 +2260,7 @@ static void test_decodeBasicConstraints(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i, GetLastError()); - if (buf) + if (ret) { CERT_BASIC_CONSTRAINTS2_INFO *info = (CERT_BASIC_CONSTRAINTS2_INFO *)buf; @@ -2285,7 +2285,7 @@ static void test_decodeBasicConstraints(DWORD dwEncoding) badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_BASIC_CONSTRAINTS2_INFO *info = (CERT_BASIC_CONSTRAINTS2_INFO *)buf; @@ -2306,7 +2306,7 @@ static void test_decodeBasicConstraints(DWORD dwEncoding) emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf; @@ -2319,7 +2319,7 @@ static void test_decodeBasicConstraints(DWORD dwEncoding) constraintWithDomainName, sizeof(constraintWithDomainName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf; @@ -2356,7 +2356,7 @@ struct EncodedRSAPubKey size_t decodedModulusLen; }; -struct EncodedRSAPubKey rsaPubKeys[] = { +static const struct EncodedRSAPubKey rsaPubKeys[] = { { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) }, { modulus2, sizeof(modulus2), mod2_encoded, 5 }, { modulus3, sizeof(modulus3), mod3_encoded, 5 }, @@ -2392,7 +2392,7 @@ static void test_encodeRsaPublicKey(DWORD dwEncoding) hdr->reserved = 1; ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); - if (buf) + if (ret) { ok(bufSize == rsaPubKeys[0].encoded[1] + 2, "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); @@ -2404,7 +2404,7 @@ static void test_encodeRsaPublicKey(DWORD dwEncoding) hdr->bVersion = 0; ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); - if (buf) + if (ret) { ok(bufSize == rsaPubKeys[0].encoded[1] + 2, "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); @@ -2416,7 +2416,7 @@ static void test_encodeRsaPublicKey(DWORD dwEncoding) hdr->aiKeyAlg = CALG_DES; ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); - if (buf) + if (ret) { ok(bufSize == rsaPubKeys[0].encoded[1] + 2, "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize); @@ -2442,7 +2442,7 @@ static void test_encodeRsaPublicKey(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB, toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == rsaPubKeys[i].encoded[1] + 2, "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2, @@ -2488,7 +2488,7 @@ static void test_decodeRsaPublicKey(DWORD dwEncoding) rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { BLOBHEADER *hdr = (BLOBHEADER *)buf; RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER)); @@ -2550,7 +2550,7 @@ static void test_encodeSequenceOfAny(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize); ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n"); @@ -2564,7 +2564,7 @@ static void test_encodeSequenceOfAny(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize); ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2), @@ -2582,7 +2582,7 @@ static void test_decodeSequenceOfAny(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence, intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf; DWORD i; @@ -2603,7 +2603,7 @@ static void test_decodeSequenceOfAny(DWORD dwEncoding) mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf; @@ -2663,7 +2663,7 @@ static void test_encodeExtensions(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == exts[i].encoded[1] + 2, "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize); @@ -2688,7 +2688,7 @@ static void test_decodeExtensions(DWORD dwEncoding) exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf; DWORD j; @@ -2710,6 +2710,17 @@ static void test_decodeExtensions(DWORD dwEncoding) } LocalFree(buf); } + ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, + exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, NULL, &bufSize); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); + if (buf) + { + ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS, + exts[i].encoded, exts[i].encoded[1] + 2, 0, NULL, buf, &bufSize); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, buf); + } } } @@ -2792,7 +2803,7 @@ static void test_encodePublicKeyInfo(DWORD dwEncoding) &bufSize); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == pubKeys[i].encoded[1] + 2, "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize); @@ -2844,7 +2855,7 @@ static void test_decodePublicKeyInfo(DWORD dwEncoding) pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { comparePublicKeyInfo(&pubKeys[i].decoded, (CERT_PUBLIC_KEY_INFO *)buf); @@ -2855,7 +2866,7 @@ static void test_decodePublicKeyInfo(DWORD dwEncoding) pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf); LocalFree(buf); @@ -3003,7 +3014,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n", v1Cert[1] + 2, size); @@ -3016,7 +3027,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v2Cert), "Wrong size %d\n", size); ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n"); @@ -3028,7 +3039,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v3Cert), "Wrong size %d\n", size); ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n"); @@ -3038,7 +3049,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */ ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(v4Cert), "Wrong size %d\n", size); ok(!memcmp(buf, v4Cert, size), "Unexpected value\n"); @@ -3054,7 +3065,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size); ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n"); @@ -3065,7 +3076,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) info.SerialNumber.pbData = (BYTE *)serialNum; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size); ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n"); @@ -3080,7 +3091,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */), "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size); ok(!memcmp(buf, v1CertWithIssuerUniqueId, size), @@ -3098,7 +3109,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) info.Subject.pbData = (BYTE *)encodedCommonName; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(bigCert), "Wrong size %d\n", size); ok(!memcmp(buf, bigCert, size), "Got unexpected value\n"); @@ -3110,7 +3121,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(v1CertWithPubKey) || size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size); @@ -3127,7 +3138,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) || size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull), @@ -3156,7 +3167,7 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) info.rgExtension = &ext; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size); ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n"); @@ -3240,7 +3251,7 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert, sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_INFO *info = (CERT_INFO *)buf; @@ -3265,7 +3276,7 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding) v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_INFO *info = (CERT_INFO *)buf; @@ -3326,7 +3337,7 @@ static void test_encodeCert(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize); ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n"); @@ -3343,7 +3354,7 @@ static void test_decodeCert(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert, sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf; @@ -3361,7 +3372,7 @@ static void test_decodeCert(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert, sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_INFO *info = (CERT_INFO *)buf; @@ -3420,7 +3431,7 @@ static void test_encodeCRLDistPoints(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size); ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n"); @@ -3445,7 +3456,7 @@ static void test_encodeCRLDistPoints(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size); ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n"); @@ -3458,7 +3469,7 @@ static void test_encodeCRLDistPoints(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size); ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n"); @@ -3471,7 +3482,7 @@ static void test_encodeCRLDistPoints(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size); ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n"); @@ -3482,7 +3493,7 @@ static void test_encodeCRLDistPoints(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(distPointWithUrlAndIssuer), "Wrong size %d\n", size); @@ -3601,6 +3612,19 @@ static void test_decodeCRLDistPoints(DWORD dwEncoding) ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n"); LocalFree(buf); } + ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, + distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0, + NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (buf) + { + ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, + distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2, 0, + NULL, buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, buf); + } } static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff }; @@ -3629,7 +3653,7 @@ static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); @@ -3641,7 +3665,7 @@ static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size); ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n"); @@ -3660,7 +3684,7 @@ static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size); ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n"); @@ -3674,7 +3698,7 @@ static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(urlIDP), "Unexpected size %d\n", size); ok(!memcmp(buf, urlIDP, size), "Unexpected value\n"); @@ -3866,7 +3890,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CRL), "Wrong size %d\n", size); ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n"); @@ -3878,7 +3902,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n", v2CRL[1] + 2, size); @@ -3892,7 +3916,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size); ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n"); @@ -3912,7 +3936,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) info.rgCRLEntry = &entry; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry), "Wrong size %d\n", size); @@ -3925,7 +3949,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) entry.SerialNumber.pbData = (BYTE *)serialNum; ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(v1CRLWithIssuerAndEntry), "Wrong size %d\n", size); @@ -3939,7 +3963,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size); ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n"); @@ -3952,7 +3976,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size); ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n"); @@ -3964,7 +3988,7 @@ static void test_encodeCRLToBeSigned(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size); ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n"); @@ -4539,7 +4563,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRL_INFO *info = (CRL_INFO *)buf; @@ -4565,7 +4589,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRL_INFO *info = (CRL_INFO *)buf; CRL_ENTRY *entry; @@ -4592,7 +4616,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRL_INFO *info = (CRL_INFO *)buf; @@ -4609,7 +4633,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRL_INFO *info = (CRL_INFO *)buf; @@ -4625,7 +4649,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRL_INFO *info = (CRL_INFO *)buf; CRL_ENTRY *entry; @@ -4653,7 +4677,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding) v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CRL_INFO *info = (CRL_INFO *)buf; @@ -4682,7 +4706,7 @@ static void test_encodeEnhancedKeyUsage(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "Wrong size %d\n", size); ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n"); @@ -4694,7 +4718,7 @@ static void test_encodeEnhancedKeyUsage(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(encodedUsage), "Wrong size %d\n", size); ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n"); @@ -4712,7 +4736,7 @@ static void test_decodeEnhancedKeyUsage(DWORD dwEncoding) emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf; @@ -4726,7 +4750,7 @@ static void test_decodeEnhancedKeyUsage(DWORD dwEncoding) encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf; DWORD i; @@ -4741,6 +4765,17 @@ static void test_decodeEnhancedKeyUsage(DWORD dwEncoding) usage->rgpszUsageIdentifier[i]); LocalFree(buf); } + ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, + encodedUsage, sizeof(encodedUsage), 0, NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (buf) + { + ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, + encodedUsage, sizeof(encodedUsage), 0, NULL, buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, buf); + } } static BYTE keyId[] = { 1,2,3,4 }; @@ -4762,7 +4797,7 @@ static void test_encodeAuthorityKeyId(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); @@ -4774,7 +4809,7 @@ static void test_encodeAuthorityKeyId(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size); ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n"); @@ -4787,7 +4822,7 @@ static void test_encodeAuthorityKeyId(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n", size); @@ -4801,7 +4836,7 @@ static void test_encodeAuthorityKeyId(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n", size); @@ -4820,7 +4855,7 @@ static void test_decodeAuthorityKeyId(DWORD dwEncoding) emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; @@ -4835,7 +4870,7 @@ static void test_decodeAuthorityKeyId(DWORD dwEncoding) authorityKeyIdWithId, sizeof(authorityKeyIdWithId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; @@ -4852,7 +4887,7 @@ static void test_decodeAuthorityKeyId(DWORD dwEncoding) authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; @@ -4870,7 +4905,7 @@ static void test_decodeAuthorityKeyId(DWORD dwEncoding) authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf; @@ -4902,7 +4937,7 @@ static void test_encodeAuthorityKeyId2(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "Unexpected size %d\n", size); ok(!memcmp(buf, emptySequence, size), "Unexpected value\n"); @@ -4914,7 +4949,7 @@ static void test_encodeAuthorityKeyId2(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size); @@ -4935,7 +4970,7 @@ static void test_encodeAuthorityKeyId2(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n", size); @@ -4950,7 +4985,7 @@ static void test_encodeAuthorityKeyId2(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n", size); @@ -4969,7 +5004,7 @@ static void test_decodeAuthorityKeyId2(DWORD dwEncoding) emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; @@ -4986,7 +5021,7 @@ static void test_decodeAuthorityKeyId2(DWORD dwEncoding) authorityKeyIdWithId, sizeof(authorityKeyIdWithId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; @@ -5005,7 +5040,7 @@ static void test_decodeAuthorityKeyId2(DWORD dwEncoding) authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; @@ -5028,7 +5063,7 @@ static void test_decodeAuthorityKeyId2(DWORD dwEncoding) authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf; @@ -5070,7 +5105,7 @@ static void test_encodeAuthorityInfoAccess(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "unexpected size %d\n", size); ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); @@ -5097,7 +5132,7 @@ static void test_encodeAuthorityInfoAccess(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n", size); @@ -5117,7 +5152,7 @@ static void test_encodeAuthorityInfoAccess(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr), "unexpected size %d\n", size); @@ -5160,7 +5195,7 @@ static void test_decodeAuthorityInfoAccess(DWORD dwEncoding) emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL }; @@ -5173,7 +5208,7 @@ static void test_decodeAuthorityInfoAccess(DWORD dwEncoding) authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { CERT_ACCESS_DESCRIPTION accessDescription; CERT_AUTHORITY_INFO_ACCESS aia; @@ -5193,7 +5228,7 @@ static void test_decodeAuthorityInfoAccess(DWORD dwEncoding) sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { CERT_ACCESS_DESCRIPTION accessDescription[2]; CERT_AUTHORITY_INFO_ACCESS aia; @@ -5215,6 +5250,19 @@ static void test_decodeAuthorityInfoAccess(DWORD dwEncoding) LocalFree(buf); buf = NULL; } + ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, + authorityInfoAccessWithUrlAndIPAddr, + sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (buf) + { + ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, + authorityInfoAccessWithUrlAndIPAddr, + sizeof(authorityInfoAccessWithUrlAndIPAddr), 0, NULL, buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, buf); + } } static const BYTE emptyCTL[] = { @@ -5275,7 +5323,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyCTL), "unexpected size %d\n", size); ok(!memcmp(buf, emptyCTL, size), "unexpected value\n"); @@ -5286,7 +5334,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size); ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n"); @@ -5299,7 +5347,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n", size); @@ -5313,7 +5361,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size); ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n"); @@ -5326,7 +5374,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n", size); @@ -5339,7 +5387,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size); ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n"); @@ -5350,7 +5398,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n", size); @@ -5364,7 +5412,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size); ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n"); @@ -5389,7 +5437,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size); ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n"); @@ -5401,7 +5449,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size); ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n"); @@ -5421,7 +5469,7 @@ static void test_encodeCTL(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size); ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n"); @@ -5611,7 +5659,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5622,7 +5670,7 @@ static void test_decodeCTL(DWORD dwEncoding) sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5635,7 +5683,7 @@ static void test_decodeCTL(DWORD dwEncoding) sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5647,7 +5695,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier, sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5659,7 +5707,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber, sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5670,7 +5718,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate, sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5681,7 +5729,7 @@ static void test_decodeCTL(DWORD dwEncoding) sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5695,7 +5743,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId, sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5730,7 +5778,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry, sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5749,7 +5797,7 @@ static void test_decodeCTL(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries, sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf); LocalFree(buf); @@ -5809,7 +5857,7 @@ static void test_encodePKCSContentInfo(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size); ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n"); @@ -5820,7 +5868,7 @@ static void test_encodePKCSContentInfo(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size); ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n"); @@ -5830,7 +5878,7 @@ static void test_encodePKCSContentInfo(DWORD dwEncoding) info.Content.cbData = ints[0].encoded[1] + 2; ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size); ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n"); @@ -5879,7 +5927,7 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding) emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CRYPT_CONTENT_INFO *)buf; @@ -5908,7 +5956,7 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding) intPKCSContentInfo, sizeof(intPKCSContentInfo), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CRYPT_CONTENT_INFO *)buf; @@ -5924,7 +5972,7 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding) indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CRYPT_CONTENT_INFO *)buf; @@ -5971,7 +6019,7 @@ static void test_encodePKCSAttribute(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size); ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n"); @@ -5984,7 +6032,7 @@ static void test_encodePKCSAttribute(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size); ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n"); @@ -5994,7 +6042,7 @@ static void test_encodePKCSAttribute(DWORD dwEncoding) blob.cbData = ints[0].encoded[1] + 2; ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size); ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n"); @@ -6013,7 +6061,7 @@ static void test_decodePKCSAttribute(DWORD dwEncoding) emptyPKCSAttr, sizeof(emptyPKCSAttr), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { attr = (CRYPT_ATTRIBUTE *)buf; @@ -6038,7 +6086,7 @@ static void test_decodePKCSAttribute(DWORD dwEncoding) intPKCSAttr, sizeof(intPKCSAttr), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { attr = (CRYPT_ATTRIBUTE *)buf; @@ -6072,7 +6120,7 @@ static void test_encodePKCSAttributes(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size); ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n"); @@ -6089,7 +6137,7 @@ static void test_encodePKCSAttributes(DWORD dwEncoding) attr[0].pszObjId = oid1; ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size); ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n"); @@ -6104,7 +6152,7 @@ static void test_encodePKCSAttributes(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size); ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n"); @@ -6123,7 +6171,7 @@ static void test_decodePKCSAttributes(DWORD dwEncoding) emptyPKCSAttributes, sizeof(emptyPKCSAttributes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { attributes = (CRYPT_ATTRIBUTES *)buf; ok(attributes->cAttr == 0, "Expected no attributes, got %d\n", @@ -6134,7 +6182,7 @@ static void test_decodePKCSAttributes(DWORD dwEncoding) singlePKCSAttributes, sizeof(singlePKCSAttributes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { attributes = (CRYPT_ATTRIBUTES *)buf; ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n", @@ -6149,7 +6197,7 @@ static void test_decodePKCSAttributes(DWORD dwEncoding) doublePKCSAttributes, sizeof(doublePKCSAttributes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { attributes = (CRYPT_ATTRIBUTES *)buf; ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n", @@ -6168,6 +6216,17 @@ static void test_decodePKCSAttributes(DWORD dwEncoding) attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n"); LocalFree(buf); } + ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, + doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (buf) + { + ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, + doublePKCSAttributes, sizeof(doublePKCSAttributes), 0, NULL, buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, buf); + } } static const BYTE singleCapability[] = { @@ -6191,7 +6250,7 @@ static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(emptySequence), "unexpected size %d\n", size); ok(!memcmp(buf, emptySequence, size), "unexpected value\n"); @@ -6214,7 +6273,7 @@ static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(singleCapability), "unexpected size %d\n", size); ok(!memcmp(buf, singleCapability, size), "unexpected value\n"); @@ -6226,7 +6285,7 @@ static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding) ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size); ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n"); @@ -6325,6 +6384,19 @@ static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding) compareSMimeCapabilities("two capabilities", &capabilities, ptr); LocalFree(ptr); } + SetLastError(0xdeadbeef); + ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, + twoCapabilities, sizeof(twoCapabilities), 0, NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (ptr) + { + SetLastError(0xdeadbeef); + ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES, + twoCapabilities, sizeof(twoCapabilities), 0, NULL, ptr, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, ptr); + } } static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10, @@ -6403,7 +6475,7 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding) { ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); if (size == sizeof(minimalPKCSSigner)) @@ -6425,7 +6497,7 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding) { ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", size); @@ -6448,7 +6520,7 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding) { ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */), "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", size); @@ -6470,7 +6542,7 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), "Unexpected size %d\n", size); @@ -6493,7 +6565,7 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", size); @@ -6516,7 +6588,7 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n", size); @@ -6551,7 +6623,7 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding) CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret || broken(GetLastError() == OSS_DATA_ERROR), "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CMSG_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6569,7 +6641,7 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { info = (CMSG_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6590,7 +6662,7 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding) PKCSSignerWithHashAndEncryptionAlgo, sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { info = (CMSG_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6612,7 +6684,7 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, PKCSSignerWithHash, sizeof(PKCSSignerWithHash), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { info = (CMSG_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6638,7 +6710,7 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding) ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); - if (buf) + if (ret) { info = (CMSG_SIGNER_INFO *)buf; ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n", @@ -6709,7 +6781,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size); ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n"); @@ -6727,7 +6799,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n", size); @@ -6747,7 +6819,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n", size); @@ -6782,7 +6854,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n", size); @@ -6801,7 +6873,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo), "Unexpected size %d\n", size); @@ -6821,7 +6893,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) else { ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n", size); @@ -6856,7 +6928,7 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding) PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CMSG_CMS_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6882,7 +6954,7 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding) PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CMSG_CMS_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6911,7 +6983,7 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding) sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CMSG_CMS_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6941,7 +7013,7 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding) PKCSSignerWithHash, sizeof(PKCSSignerWithHash), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CMSG_CMS_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -6975,7 +7047,7 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding) CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError()); - if (buf) + if (ret) { info = (CMSG_CMS_SIGNER_INFO *)buf; ok(info->dwVersion == 0, "Expected version 0, got %d\n", @@ -7137,7 +7209,7 @@ static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = { static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = { { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 }; -struct EncodedNameConstraints encodedNameConstraints[] = { +static const struct EncodedNameConstraints encodedNameConstraints[] = { { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } }, { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints }, { 1, &emptyDNSSubtree, 0, NULL } }, @@ -7487,6 +7559,17 @@ static void test_decodeCertPolicies(DWORD dwEncoding) "unexpected qualifier value\n"); LocalFree(info); } + ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, + twoPolicies, sizeof(twoPolicies), 0, NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (info) + { + ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES, + twoPolicies, sizeof(twoPolicies), 0, NULL, info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, info); + } } static const BYTE policyMappingWithOneMapping[] = { @@ -7630,6 +7713,19 @@ static void test_decodeCertPolicyMappings(DWORD dwEncoding) info->rgPolicyMapping[1].pszSubjectDomainPolicy); LocalFree(info); } + ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], + policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0, + NULL, NULL, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (info) + { + ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], + policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), 0, + NULL, info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, info); + } } } diff --git a/rostests/winetests/crypt32/main.c b/rostests/winetests/crypt32/main.c index 7c11e8e2ee3..8c5b41e08cd 100644 --- a/rostests/winetests/crypt32/main.c +++ b/rostests/winetests/crypt32/main.c @@ -28,7 +28,7 @@ #include "wine/test.h" -HMODULE hCrypt; +static HMODULE hCrypt; static void test_findAttribute(void) { @@ -47,8 +47,7 @@ static void test_findAttribute(void) if (0) { /* crashes */ - SetLastError(0xdeadbeef); - ret = CertFindAttribute(NULL, 1, NULL); + CertFindAttribute(NULL, 1, NULL); /* returns NULL, last error is ERROR_INVALID_PARAMETER * crashes on Vista */ @@ -93,7 +92,7 @@ static void test_findExtension(void) { /* crashes */ SetLastError(0xdeadbeef); - ret = CertFindExtension(NULL, 1, NULL); + CertFindExtension(NULL, 1, NULL); /* returns NULL, last error is ERROR_INVALID_PARAMETER * crashes on Vista */ @@ -138,7 +137,7 @@ static void test_findRDNAttr(void) { /* crashes */ SetLastError(0xdeadbeef); - ret = CertFindRDNAttr(NULL, NULL); + CertFindRDNAttr(NULL, NULL); /* returns NULL, last error is ERROR_INVALID_PARAMETER * crashes on Vista */ @@ -395,7 +394,7 @@ static void test_format_object(void) /* Crash */ if (0) { - ret = pCryptFormatObject(0, 0, 0, NULL, NULL, NULL, 0, NULL, NULL); + pCryptFormatObject(0, 0, 0, NULL, NULL, NULL, 0, NULL, NULL); } /* When called with any but the default encoding, it fails to find a * formatting function. diff --git a/rostests/winetests/crypt32/message.c b/rostests/winetests/crypt32/message.c index fa8df0e5951..be3a03b8dd2 100644 --- a/rostests/winetests/crypt32/message.c +++ b/rostests/winetests/crypt32/message.c @@ -27,6 +27,23 @@ #include "wine/test.h" +static BOOL (WINAPI * pCryptAcquireContextA) + (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD); + +static void init_function_pointers(void) +{ + HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll"); + +#define GET_PROC(dll, func) \ + p ## func = (void *)GetProcAddress(dll, #func); \ + if(!p ## func) \ + trace("GetProcAddress(%s) failed\n", #func); + + GET_PROC(hAdvapi32, CryptAcquireContextA) + +#undef GET_PROC +} + static const BYTE dataEmptyBareContent[] = { 0x04,0x00 }; static const BYTE dataEmptyContent[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02, @@ -107,7 +124,7 @@ static void test_verify_detached_message_hash(void) if (0) { - ret = CryptVerifyDetachedMessageHash(NULL, NULL, 0, 0, NULL, NULL, NULL, + CryptVerifyDetachedMessageHash(NULL, NULL, 0, 0, NULL, NULL, NULL, NULL); } memset(¶, 0, sizeof(para)); @@ -453,6 +470,34 @@ static const BYTE signedWithCertWithPubKeyContent[] = { 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20, 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48, 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 }; +static const BYTE signedWithCertWithValidPubKeyContent[] = { +0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, +0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01, +0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,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,0x30,0x22,0x18,0x0f,0x31,0x36, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, +0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, +0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, +0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48, +0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4, +0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb, +0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc, +0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30, +0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30, +0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06, +0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a, +0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75, +0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08, +0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05, +0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a, +0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e, +0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64, +0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4, +0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; static void test_verify_message_signature(void) { @@ -460,11 +505,19 @@ static void test_verify_message_signature(void) CRYPT_VERIFY_MESSAGE_PARA para = { 0 }; PCCERT_CONTEXT cert; DWORD cbDecoded; + BYTE decoded[sizeof(msgData)]; SetLastError(0xdeadbeef); ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL); ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); + /* Is cbDecoded set when invalid parameters are passed? */ + cbDecoded = 0xdeadbeef; + ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, &cbDecoded, + NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + ok(cbDecoded == 0, "expected 0, got %08x\n", cbDecoded); SetLastError(0xdeadbeef); ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, NULL); ok(!ret && GetLastError() == E_INVALIDARG, @@ -490,15 +543,24 @@ static void test_verify_message_signature(void) /* Check whether cert is set on error */ cert = (PCCERT_CONTEXT)0xdeadbeef; ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, 0, &cert); + ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || + GetLastError() == OSS_BAD_ARG /* NT40 */), + "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); ok(cert == NULL, "Expected NULL cert\n"); /* Check whether cbDecoded is set on error */ cbDecoded = 0xdeadbeef; ret = CryptVerifyMessageSignature(¶, 0, NULL, 0, NULL, &cbDecoded, NULL); + ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || + GetLastError() == OSS_BAD_ARG /* NT40 */), + "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); ok(!cbDecoded, "Expected 0\n"); SetLastError(0xdeadbeef); ret = CryptVerifyMessageSignature(¶, 0, dataEmptyBareContent, sizeof(dataEmptyBareContent), NULL, 0, NULL); + ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || + GetLastError() == OSS_PDU_MISMATCH /* NT40 */), + "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); ok(GetLastError() == CRYPT_E_ASN1_BADTAG || GetLastError() == OSS_PDU_MISMATCH, /* win9x */ "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); @@ -542,6 +604,34 @@ static void test_verify_message_signature(void) ret = CryptVerifyMessageSignature(¶, 0, signedWithCertWithPubKeyContent, sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL); ok(!ret, "Expected failure\n"); + /* Apparently, an output pcbDecoded parameter is expected. */ + ret = CryptVerifyMessageSignature(¶, 0, + signedWithCertWithValidPubKeyContent, + sizeof(signedWithCertWithValidPubKeyContent), NULL, 0, NULL); + ok(!ret, "Expected failure\n"); + /* Finally, a message signed with a valid public key verifies successfully + */ + cbDecoded = 0xdeadbeef; + ret = CryptVerifyMessageSignature(¶, 0, + signedWithCertWithValidPubKeyContent, + sizeof(signedWithCertWithValidPubKeyContent), NULL, &cbDecoded, NULL); + ok(ret, "CryptVerifyMessageSignature failed: %08x\n", GetLastError()); + ok(cbDecoded == sizeof(msgData), "expected 4, got %d\n", cbDecoded); + cbDecoded = 0; + ret = CryptVerifyMessageSignature(¶, 0, + signedWithCertWithValidPubKeyContent, + sizeof(signedWithCertWithValidPubKeyContent), NULL, &cbDecoded, NULL); + /* Setting cbDecoded to 0 succeeds when a NULL buffer is provided */ + ok(ret, "CryptVerifyMessageSignature failed: %08x\n", GetLastError()); + ok(cbDecoded == sizeof(msgData), "expected 4, got %d\n", cbDecoded); + cbDecoded = 0; + ret = CryptVerifyMessageSignature(¶, 0, + signedWithCertWithValidPubKeyContent, + sizeof(signedWithCertWithValidPubKeyContent), decoded, &cbDecoded, NULL); + /* When a non-NULL buffer is provided, cbDecoded must not be too small */ + ok(!ret && GetLastError() == ERROR_MORE_DATA, + "expected ERROR_MORE_DATA, got %d (%08x)\n", GetLastError(), + GetLastError()); } static const BYTE detachedHashBlob[] = { @@ -600,6 +690,7 @@ static void test_hash_message(void) SetLastError(0xdeadbeef); ret = CryptHashMessage(¶, FALSE, 2, toHash, hashSize, NULL, NULL, NULL, NULL); + ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); /* Try again with a valid encoding type */ para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; SetLastError(0xdeadbeef); @@ -615,7 +706,7 @@ static void test_hash_message(void) */ if (0) { - ret = CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, + CryptHashMessage(¶, FALSE, 2, NULL, NULL, NULL, &hashedBlobSize, NULL, NULL); } /* Passing a valid pointer for the data to hash fails, as the hash @@ -702,6 +793,7 @@ static void test_hash_message(void) SetLastError(0xdeadbeef); ret = CryptHashMessage(¶, TRUE, 2, toHash, hashSize, NULL, &hashedBlobSize, computedHash, &computedHashSize); + ok(ret, "CryptHashMessage failed: 0x%08x\n", GetLastError()); ok(computedHashSize == sizeof(hashVal), "unexpected size of hash value %d\n", computedHashSize); ok(!memcmp(computedHash, hashVal, computedHashSize), @@ -710,12 +802,576 @@ static void test_hash_message(void) } } +static const BYTE publicPrivateKeyPair[] = { +0x07,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x02,0x00, +0x00,0x01,0x00,0x01,0x00,0x9b,0xd9,0x60,0xd9,0x5b,0x09,0x50,0x9e,0x09,0x94, +0x1e,0x6a,0x06,0x1d,0xdd,0x39,0xc5,0x96,0x17,0xe3,0xb9,0x0c,0x71,0x9c,0xf7, +0xc1,0x07,0x7b,0xd7,0x4a,0xaa,0x8a,0x3e,0xcd,0x78,0x3c,0x4c,0x95,0x98,0x28, +0x29,0x2d,0xe0,0xfc,0xe6,0x4f,0x95,0xca,0x87,0x92,0xdd,0xa3,0x8d,0xf0,0x39, +0xf3,0x1b,0x87,0x64,0x82,0x99,0xc0,0xa9,0xe8,0x87,0x86,0x2e,0x72,0x07,0x07, +0x8f,0x45,0x54,0x51,0x2f,0x51,0xd0,0x60,0x97,0x48,0x54,0x0e,0x78,0xb5,0x7e, +0x2b,0x9d,0xca,0x81,0xa8,0xa8,0x00,0x57,0x69,0xa6,0xf7,0x4d,0x45,0xe0,0xf7, +0xfa,0xd2,0xeb,0xaa,0xb8,0x06,0x34,0xce,0xf0,0x9d,0x2b,0x76,0x8a,0x4f,0x70, +0x51,0x90,0x33,0x72,0xcb,0x81,0x85,0x7e,0x35,0x2e,0xfb,0x81,0xf0,0xc7,0x85, +0xa5,0x75,0xf9,0x2d,0x00,0x71,0x66,0x36,0xfe,0x22,0xd6,0xc9,0x36,0x61,0x9b, +0x64,0x92,0xe8,0x25,0x38,0x35,0xeb,0x0c,0x84,0x83,0x76,0x42,0x90,0xf7,0x73, +0x91,0xdc,0x43,0x83,0x07,0x77,0xc9,0x1b,0x3f,0x74,0xc0,0xbe,0x18,0x97,0xd6, +0x86,0xe5,0xfa,0x28,0x7c,0xf7,0x8d,0x89,0xb1,0x93,0xac,0x48,0x3c,0xa1,0x02, +0xfa,0xc6,0x1c,0xa0,0xb5,0xe8,0x4f,0xd7,0xd1,0x33,0x63,0x8b,0x7e,0xf1,0x94, +0x56,0x07,0xbc,0x6e,0x0c,0xbd,0xa0,0x15,0xba,0x99,0x5d,0xb7,0x5e,0x09,0xf2, +0x1b,0x46,0x85,0x61,0x91,0x6a,0x78,0x31,0xb5,0xf0,0xba,0x20,0xf5,0x7a,0xb4, +0x8e,0xd3,0x50,0x87,0xf8,0xf3,0xe4,0xd9,0xab,0x6f,0x0e,0x59,0x42,0xac,0x7d, +0xb1,0x8c,0xea,0x33,0x54,0x08,0x38,0xc9,0xcd,0xac,0x10,0x19,0x4a,0xba,0x89, +0xdc,0xb6,0x73,0xef,0xec,0x56,0x93,0xd6,0xf2,0x4b,0xba,0x50,0x2d,0x8f,0x15, +0xed,0x8b,0xb5,0x67,0xc8,0xfc,0x51,0x5f }; +static const BYTE cert1[] = { +0x30,0x81,0xd0,0x30,0x81,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x20,0x42, +0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30, +0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x0c,0x31,0x0a,0x30, +0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x20,0x17,0x0d,0x31,0x30, +0x30,0x39,0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x18,0x0f,0x33,0x30, +0x31,0x30,0x30,0x39,0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x30,0x0c, +0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x5c,0x30, +0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03, +0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe8,0xa9,0xc0,0x99,0x82,0x64,0x87,0x1b, +0xf3,0x39,0xf0,0x8d,0xa3,0xdd,0x92,0x87,0xca,0x95,0x4f,0xe6,0xfc,0xe0,0x2d, +0x29,0x28,0x98,0x95,0x4c,0x3c,0x78,0xcd,0x3e,0x8a,0xaa,0x4a,0xd7,0x7b,0x07, +0xc1,0xf7,0x9c,0x71,0x0c,0xb9,0xe3,0x17,0x96,0xc5,0x39,0xdd,0x1d,0x06,0x6a, +0x1e,0x94,0x09,0x9e,0x50,0x09,0x5b,0xd9,0x60,0xd9,0x9b,0x02,0x03,0x01,0x00, +0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x02,0x00, +0xc1 }; +static const BYTE cert2[] = { +0x30,0x82,0x01,0x15,0x30,0x82,0x01,0x02,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,0xd7,0xe1,0x6c,0x84,0x85,0xcd, +0x2e,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x0c,0x31, +0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58,0x30,0x20,0x17,0x0d, +0x31,0x30,0x30,0x37,0x31,0x32,0x31,0x31,0x33,0x37,0x35,0x36,0x5a,0x18,0x0f, +0x33,0x30,0x31,0x30,0x30,0x37,0x31,0x32,0x31,0x31,0x33,0x37,0x35,0x36,0x5a, +0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58,0x30, +0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, +0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xab,0xed, +0x6e,0xe0,0x00,0x3c,0xcf,0x2d,0x2b,0xda,0x05,0x88,0x6a,0x7e,0xed,0x60,0x30, +0x24,0xef,0x6c,0x6b,0xad,0x28,0x9b,0x14,0x90,0xf6,0xd0,0x96,0x79,0x6d,0xad, +0xac,0x46,0x14,0x7b,0x0e,0xfe,0xa9,0x8a,0x05,0x5a,0xc8,0x84,0x38,0x44,0xf9, +0xce,0xb2,0xe6,0xde,0x5b,0x80,0x0b,0x15,0xff,0x1b,0x60,0x3f,0xba,0xb2,0xfe, +0x6e,0xf5,0xdc,0x54,0x33,0xfc,0xfc,0x79,0x0a,0x10,0xa4,0x23,0x6d,0x67,0xeb, +0x16,0xb2,0x92,0xbf,0x63,0x42,0x17,0x0a,0xde,0xe6,0xab,0x8e,0xf7,0x8e,0x41, +0x8c,0x04,0xe8,0xe2,0x38,0x73,0xd3,0x82,0xd7,0xd1,0xee,0xd3,0xa6,0x54,0x8c, +0xcd,0x0b,0x93,0xda,0x63,0x55,0x0d,0x1f,0x68,0x5c,0x30,0xee,0xad,0x2d,0xd5, +0x40,0x56,0xe0,0xd8,0xc7,0xef,0x02,0x03,0x01,0x00,0x01,0x30,0x09,0x06,0x05, +0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x02,0x00,0x06 }; +static const BYTE crl[] = { +0x30,0x81,0xc2,0x30,0x7e,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x3c,0x31,0x0b,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x52,0x55,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55, +0x04,0x08,0x13,0x03,0x53,0x50,0x62,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04, +0x07,0x13,0x03,0x53,0x50,0x62,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x0a, +0x13,0x08,0x45,0x74,0x65,0x72,0x73,0x6f,0x66,0x74,0x17,0x0d,0x31,0x30,0x30, +0x36,0x32,0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0x17,0x0d,0x31,0x30,0x30, +0x37,0x32,0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0xa0,0x0e,0x30,0x0c,0x30, +0x0a,0x06,0x03,0x55,0x1d,0x14,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09, +0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x31,0x00,0x83, +0x35,0x9c,0xf5,0x35,0x5c,0xc1,0x20,0x81,0x80,0x5c,0x35,0x56,0xaf,0xb3,0x27, +0x15,0xc6,0xdd,0x24,0xe1,0xff,0xb9,0xf9,0x19,0x21,0xed,0x5e,0x1b,0xff,0x72, +0xc3,0x33,0xf6,0x9f,0xcb,0xde,0x84,0x0b,0x12,0x84,0xad,0x48,0x90,0x9d,0xdd, +0x89,0xbb }; +static const BYTE signedHashForEmptyMessage[] = { +0x30,0x81,0xbb,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, +0x81,0xad,0x30,0x81,0xaa,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01, +0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13, +0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0, +0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x04,0x40,0xe1,0xee,0xca,0x98,0x16,0x23,0x5a,0x34,0xfd, +0x91,0x69,0x97,0x1e,0x16,0xe4,0x57,0x45,0xad,0xc9,0x5d,0x2e,0xda,0x92,0xbf, +0xee,0x2f,0xb1,0xaa,0x32,0xfa,0x07,0x4e,0x63,0xfd,0xe1,0x52,0x17,0xd0,0xa4, +0x49,0x30,0x54,0x4d,0x12,0xa0,0x6a,0x1c,0x64,0xea,0xc7,0x50,0x49,0xa5,0xca, +0xc3,0x71,0xa4,0xf7,0x8c,0x25,0xe4,0x1a,0xca,0x89 }; +static const BYTE signedEmptyMessage[] = { +0x30,0x81,0xbb,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, +0x81,0xad,0x30,0x81,0xaa,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01, +0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13, +0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0, +0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x04,0x40,0xe1,0xee,0xca,0x98,0x16,0x23,0x5a,0x34,0xfd, +0x91,0x69,0x97,0x1e,0x16,0xe4,0x57,0x45,0xad,0xc9,0x5d,0x2e,0xda,0x92,0xbf, +0xee,0x2f,0xb1,0xaa,0x32,0xfa,0x07,0x4e,0x63,0xfd,0xe1,0x52,0x17,0xd0,0xa4, +0x49,0x30,0x54,0x4d,0x12,0xa0,0x6a,0x1c,0x64,0xea,0xc7,0x50,0x49,0xa5,0xca, +0xc3,0x71,0xa4,0xf7,0x8c,0x25,0xe4,0x1a,0xca,0x89 }; +static const BYTE signedHash[] = { +0x30,0x81,0xbb,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, +0x81,0xad,0x30,0x81,0xaa,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01, +0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13, +0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0, +0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x04,0x40,0x1e,0x04,0xa4,0xe3,0x90,0x54,0xed,0xcb,0x94, +0xa2,0xbe,0x81,0x73,0x7e,0x05,0xf2,0x82,0xd3,0x3a,0x26,0x96,0x7a,0x53,0xcd, +0x05,0xc3,0x09,0x69,0x3d,0x12,0x6c,0xb1,0xb0,0xab,0x0e,0xa1,0xec,0x1b,0xa1, +0xff,0x01,0x9c,0x49,0x9f,0x4b,0x69,0x59,0x74,0x20,0x9f,0xb0,0x19,0x95,0xe7, +0xed,0x1e,0x84,0xeb,0xe2,0x53,0x2c,0xa6,0x43,0xdf }; +static const BYTE signedHashWithCert[] = { +0x30,0x82,0x01,0x93,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, +0xa0,0x82,0x01,0x84,0x30,0x82,0x01,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x81,0xd3,0x30,0x81, +0xd0,0x30,0x81,0xbe,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x20,0x42,0x68,0x69, +0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x09,0x06, +0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06, +0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x20,0x17,0x0d,0x31,0x30,0x30,0x39, +0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x18,0x0f,0x33,0x30,0x31,0x30, +0x30,0x39,0x31,0x34,0x31,0x33,0x31,0x39,0x30,0x39,0x5a,0x30,0x0c,0x31,0x0a, +0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x30,0x5c,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00, +0x30,0x48,0x02,0x41,0x00,0xe8,0xa9,0xc0,0x99,0x82,0x64,0x87,0x1b,0xf3,0x39, +0xf0,0x8d,0xa3,0xdd,0x92,0x87,0xca,0x95,0x4f,0xe6,0xfc,0xe0,0x2d,0x29,0x28, +0x98,0x95,0x4c,0x3c,0x78,0xcd,0x3e,0x8a,0xaa,0x4a,0xd7,0x7b,0x07,0xc1,0xf7, +0x9c,0x71,0x0c,0xb9,0xe3,0x17,0x96,0xc5,0x39,0xdd,0x1d,0x06,0x6a,0x1e,0x94, +0x09,0x9e,0x50,0x09,0x5b,0xd9,0x60,0xd9,0x9b,0x02,0x03,0x01,0x00,0x01,0x30, +0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x02,0x00,0xc1,0x31, +0x81,0x87,0x30,0x81,0x84,0x02,0x01,0x01,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30, +0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x20,0x42,0x68,0x69, +0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c,0x06, +0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0d,0x06,0x09, +0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x40,0x1e,0x04, +0xa4,0xe3,0x90,0x54,0xed,0xcb,0x94,0xa2,0xbe,0x81,0x73,0x7e,0x05,0xf2,0x82, +0xd3,0x3a,0x26,0x96,0x7a,0x53,0xcd,0x05,0xc3,0x09,0x69,0x3d,0x12,0x6c,0xb1, +0xb0,0xab,0x0e,0xa1,0xec,0x1b,0xa1,0xff,0x01,0x9c,0x49,0x9f,0x4b,0x69,0x59, +0x74,0x20,0x9f,0xb0,0x19,0x95,0xe7,0xed,0x1e,0x84,0xeb,0xe2,0x53,0x2c,0xa6, +0x43,0xdf }; +static const BYTE signedHashWithCRL[] = { +0x30,0x82,0x01,0x85,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, +0xa0,0x82,0x01,0x76,0x30,0x82,0x01,0x72,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa1,0x81,0xc5,0x30,0x81, +0xc2,0x30,0x7e,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, +0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x3c,0x31,0x0b,0x30,0x09,0x06,0x03,0x55, +0x04,0x06,0x13,0x02,0x52,0x55,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x08, +0x13,0x03,0x53,0x50,0x62,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x07,0x13, +0x03,0x53,0x50,0x62,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x0a,0x13,0x08, +0x45,0x74,0x65,0x72,0x73,0x6f,0x66,0x74,0x17,0x0d,0x31,0x30,0x30,0x36,0x32, +0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0x17,0x0d,0x31,0x30,0x30,0x37,0x32, +0x38,0x31,0x32,0x35,0x31,0x32,0x37,0x5a,0xa0,0x0e,0x30,0x0c,0x30,0x0a,0x06, +0x03,0x55,0x1d,0x14,0x04,0x03,0x02,0x01,0x00,0x30,0x0d,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x31,0x00,0x83,0x35,0x9c, +0xf5,0x35,0x5c,0xc1,0x20,0x81,0x80,0x5c,0x35,0x56,0xaf,0xb3,0x27,0x15,0xc6, +0xdd,0x24,0xe1,0xff,0xb9,0xf9,0x19,0x21,0xed,0x5e,0x1b,0xff,0x72,0xc3,0x33, +0xf6,0x9f,0xcb,0xde,0x84,0x0b,0x12,0x84,0xad,0x48,0x90,0x9d,0xdd,0x89,0xbb, +0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01,0x01,0x30,0x20,0x30,0x0c,0x31,0x0a, +0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x20,0x42,0x68, +0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x40,0x1e, +0x04,0xa4,0xe3,0x90,0x54,0xed,0xcb,0x94,0xa2,0xbe,0x81,0x73,0x7e,0x05,0xf2, +0x82,0xd3,0x3a,0x26,0x96,0x7a,0x53,0xcd,0x05,0xc3,0x09,0x69,0x3d,0x12,0x6c, +0xb1,0xb0,0xab,0x0e,0xa1,0xec,0x1b,0xa1,0xff,0x01,0x9c,0x49,0x9f,0x4b,0x69, +0x59,0x74,0x20,0x9f,0xb0,0x19,0x95,0xe7,0xed,0x1e,0x84,0xeb,0xe2,0x53,0x2c, +0xa6,0x43,0xdf }; +static const BYTE signedData[] = { +0x30,0x81,0xc3,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, +0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04, +0x31,0x81,0x87,0x30,0x81,0x84,0x02,0x01,0x01,0x30,0x20,0x30,0x0c,0x31,0x0a, +0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x20,0x42,0x68, +0x69,0xe9,0xea,0x61,0x83,0x11,0xdf,0xc0,0x24,0x2f,0x3b,0xad,0x40,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x40,0xe4, +0x69,0xf5,0x62,0xfb,0x3a,0x7d,0x1c,0x7b,0x8b,0xcc,0xfc,0x6e,0x8e,0x91,0x85, +0xcf,0x3c,0xb8,0xfd,0x8a,0xac,0x81,0x96,0xa0,0x42,0xac,0x88,0xc4,0x48,0xe8, +0x43,0x64,0xd1,0x38,0xd2,0x6c,0xc4,0xd4,0x9b,0x9a,0xd4,0x33,0x02,0xef,0x88, +0xef,0x98,0x2d,0xac,0xad,0xc1,0x93,0x60,0xc4,0x3a,0xdc,0xa7,0xd6,0x97,0x70, +0x01,0xc1,0x84 }; + +static void test_sign_message(void) +{ + BOOL ret; + CRYPT_SIGN_MESSAGE_PARA para; + static char oid_rsa_md5[] = szOID_RSA_MD5; + static const BYTE blob1[] = { 0x01, 0x02, 0x03, 0x04 }; + static const BYTE blob2[] = { 0x11, 0x12, 0x13, 0x14 }; + const BYTE *toSign[] = { blob1, blob2 }; + DWORD signSize[] = { sizeof(blob1), sizeof(blob2) }; + LPBYTE signedBlob; + DWORD signedBlobSize; + PCCRL_CONTEXT crlContext; + CERT_KEY_CONTEXT keyContext; + HCRYPTPROV hCryptProv = 0; + HCRYPTKEY hKey = 0; + + memset(¶, 0, sizeof(para)); + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); + ok(!ret && + (GetLastError() == E_INVALIDARG || + GetLastError() == ERROR_ARITHMETIC_OVERFLOW), /* Win7 */ + "expected E_INVALIDARG or ERROR_ARITHMETIC_OVERFLOW, got %08x\n", + GetLastError()); + para.cbSize = sizeof(para); + para.dwMsgEncodingType = X509_ASN_ENCODING; + SetLastError(0xdeadbeef); + signedBlobSize = 255; + ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + ok(!signedBlobSize, "unexpected size %d\n", signedBlobSize); + para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + todo_wine + ok(signedBlobSize, "bad size\n"); + + SetLastError(0xdeadbeef); + ret = pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptImportKey(hCryptProv, publicPrivateKeyPair, + sizeof(publicPrivateKeyPair), 0, 0, &hKey); + if (!ret && GetLastError() == NTE_PERM) /* Win9x */ + { + skip("Failed to import a key\n"); + if (hCryptProv) + CryptReleaseContext(hCryptProv, 0); + return; + } + ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); + + para.dwMsgEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; + SetLastError(0xdeadbeef); + para.pSigningCert = CertCreateCertificateContext(X509_ASN_ENCODING | + PKCS_7_ASN_ENCODING, cert1, sizeof(cert1)); + ok(para.pSigningCert != NULL, "CertCreateCertificateContext failed: %08x\n", + GetLastError()); + para.HashAlgorithm.pszObjId = oid_rsa_md5; + + memset(&keyContext, 0, sizeof(keyContext)); + keyContext.cbSize = sizeof(keyContext); + keyContext.hCryptProv = hCryptProv; + keyContext.dwKeySpec = AT_SIGNATURE; + SetLastError(0xdeadbeef); + ret = CertSetCertificateContextProperty(para.pSigningCert, + CERT_KEY_CONTEXT_PROP_ID, 0, &keyContext); + ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError()); + + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, TRUE, 0, NULL, NULL, NULL, &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + signedBlob = CryptMemAlloc(signedBlobSize); + if (signedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, TRUE, 0, NULL, NULL, signedBlob, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + ok(signedBlobSize == sizeof(signedHashForEmptyMessage), + "unexpected size %d\n", signedBlobSize); + ok(!memcmp(signedBlob, signedHashForEmptyMessage, signedBlobSize), + "unexpected value\n"); + CryptMemFree(signedBlob); + } + + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, NULL, &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + signedBlob = CryptMemAlloc(signedBlobSize); + if (signedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, FALSE, 0, NULL, NULL, signedBlob, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + ok(signedBlobSize == sizeof(signedEmptyMessage), "unexpected size %d\n", + signedBlobSize); + ok(!memcmp(signedBlob, signedEmptyMessage, signedBlobSize), + "unexpected value\n"); + CryptMemFree(signedBlob); + } + + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, NULL, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + signedBlob = CryptMemAlloc(signedBlobSize); + if (signedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, signedBlob, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + ok(signedBlobSize == sizeof(signedHash), + "unexpected size of signed blob %d\n", signedBlobSize); + ok(!memcmp(signedBlob, signedHash, signedBlobSize), + "unexpected value\n"); + CryptMemFree(signedBlob); + } + + para.cMsgCert = 1; + para.rgpMsgCert = ¶.pSigningCert; + + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, NULL, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + signedBlob = CryptMemAlloc(signedBlobSize); + if (signedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, signedBlob, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + ok(signedBlobSize == sizeof(signedHashWithCert), + "unexpected size of signed blob %d\n", signedBlobSize); + ok(!memcmp(signedBlob, signedHashWithCert, signedBlobSize), + "unexpected value\n"); + CryptMemFree(signedBlob); + } + + para.cMsgCert = 0; + para.rgpMsgCert = NULL; + para.cMsgCrl = 1; + SetLastError(0xdeadbeef); + crlContext = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + crl, sizeof(crl)); + ok(crlContext != NULL, "CertCreateCRLContext failed: %08x\n", + GetLastError()); + para.rgpMsgCrl = &crlContext; + + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, NULL, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + signedBlob = CryptMemAlloc(signedBlobSize); + if (signedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, TRUE, 2, toSign, signSize, signedBlob, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + ok(signedBlobSize == sizeof(signedHashWithCRL), + "unexpected size of signed blob %d\n", signedBlobSize); + ok(!memcmp(signedBlob, signedHashWithCRL, signedBlobSize), + "unexpected value\n"); + CryptMemFree(signedBlob); + } + + CertFreeCRLContext(crlContext); + para.cMsgCrl = 0; + para.rgpMsgCrl = NULL; + + SetLastError(0xdeadbeef); + signedBlobSize = 0; + ret = CryptSignMessage(¶, FALSE, 1, toSign, signSize, NULL, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + signedBlob = CryptMemAlloc(signedBlobSize); + if (signedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptSignMessage(¶, FALSE, 1, toSign, signSize, signedBlob, + &signedBlobSize); + ok(ret, "CryptSignMessage failed: %08x\n", GetLastError()); + ok(signedBlobSize == sizeof(signedData), + "unexpected size of signed blob %d\n", signedBlobSize); + ok(!memcmp(signedBlob, signedData, signedBlobSize), + "unexpected value\n"); + CryptMemFree(signedBlob); + } + + if (para.pSigningCert) + CertFreeCertificateContext(para.pSigningCert); + if (hKey) + CryptDestroyKey(hKey); + if (hCryptProv) + CryptReleaseContext(hCryptProv, 0); +} + +static const BYTE encryptedMessage[] = { +0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24, +0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x03,0x04,0x05,0x00,0x80,0x00 }; + +static void test_encrypt_message(void) +{ + BOOL ret; + CRYPT_ENCRYPT_MESSAGE_PARA para; + static char oid_rsa_rc4[] = szOID_RSA_RC4; + static const BYTE blob[] = { 0x01, 0x02, 0x03, 0x04 }; + PCCERT_CONTEXT certs[2]; + HCRYPTPROV hCryptProv = 0; + LPBYTE encryptedBlob; + DWORD encryptedBlobSize; + + SetLastError(0xdeadbeef); + ret = pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); + + SetLastError(0xdeadbeef); + certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING | + PKCS_7_ASN_ENCODING, cert1, sizeof(cert1)); + ok(certs[0] != NULL, "CertCreateCertificateContext failed: %08x\n", + GetLastError()); + SetLastError(0xdeadbeef); + certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING | + PKCS_7_ASN_ENCODING, cert2, sizeof(cert2)); + ok(certs[1] != NULL, "CertCreateCertificateContext failed: %08x\n", + GetLastError()); + + memset(¶, 0, sizeof(para)); + SetLastError(0xdeadbeef); + encryptedBlobSize = 255; + ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, + &encryptedBlobSize); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + ok(!encryptedBlobSize, "unexpected size %d\n", encryptedBlobSize); + para.cbSize = sizeof(para); + para.dwMsgEncodingType = X509_ASN_ENCODING; + SetLastError(0xdeadbeef); + encryptedBlobSize = 255; + ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, + &encryptedBlobSize); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + ok(!encryptedBlobSize, "unexpected size %d\n", encryptedBlobSize); + para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; + SetLastError(0xdeadbeef); + encryptedBlobSize = 255; + ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, + &encryptedBlobSize); + ok(!ret && + (GetLastError() == CRYPT_E_UNKNOWN_ALGO || + GetLastError() == E_INVALIDARG), /* Win9x */ + "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", + GetLastError()); + ok(!encryptedBlobSize, "unexpected size %d\n", encryptedBlobSize); + + para.hCryptProv = hCryptProv; + para.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4; + + SetLastError(0xdeadbeef); + encryptedBlobSize = 0; + ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, NULL, + &encryptedBlobSize); + ok(ret || + broken(!ret) /* Win9x */, + "CryptEncryptMessage failed: %08x\n", GetLastError()); + if (ret) + { + encryptedBlob = CryptMemAlloc(encryptedBlobSize); + if (encryptedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptEncryptMessage(¶, 0, NULL, NULL, 0, encryptedBlob, + &encryptedBlobSize); + ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); + ok(encryptedBlobSize == sizeof(encryptedMessage), + "unexpected size of encrypted blob %d\n", encryptedBlobSize); + ok(!memcmp(encryptedBlob, encryptedMessage, encryptedBlobSize), + "unexpected value\n"); + CryptMemFree(encryptedBlob); + } + } + + SetLastError(0xdeadbeef); + encryptedBlobSize = 0; + ret = CryptEncryptMessage(¶, 2, certs, NULL, 0, NULL, + &encryptedBlobSize); + ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); + if (ret) + { + encryptedBlob = CryptMemAlloc(encryptedBlobSize); + if (encryptedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptEncryptMessage(¶, 2, certs, NULL, 0, encryptedBlob, + &encryptedBlobSize); + ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); + CryptMemFree(encryptedBlob); + } + } + + SetLastError(0xdeadbeef); + encryptedBlobSize = 0; + ret = CryptEncryptMessage(¶, 0, NULL, blob, sizeof(blob), NULL, + &encryptedBlobSize); + ok(ret || + broken(!ret) /* Win9x */, + "CryptEncryptMessage failed: %08x\n", GetLastError()); + if (ret) + { + encryptedBlob = CryptMemAlloc(encryptedBlobSize); + if (encryptedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptEncryptMessage(¶, 0, NULL, blob, sizeof(blob), + encryptedBlob, &encryptedBlobSize); + ok(ret || + broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ + "CryptEncryptMessage failed: %08x\n", GetLastError()); + if (ret) + { + ok(encryptedBlobSize == 55, + "unexpected size of encrypted blob %d\n", encryptedBlobSize); + } + CryptMemFree(encryptedBlob); + } + } + + SetLastError(0xdeadbeef); + encryptedBlobSize = 0; + ret = CryptEncryptMessage(¶, 2, certs, blob, sizeof(blob), NULL, + &encryptedBlobSize); + ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError()); + if (ret) + { + encryptedBlob = CryptMemAlloc(encryptedBlobSize); + if (encryptedBlob) + { + SetLastError(0xdeadbeef); + ret = CryptEncryptMessage(¶, 2, certs, blob, sizeof(blob), + encryptedBlob, &encryptedBlobSize); + ok(ret || + broken(!ret), /* some Win95 and some NT4 */ + "CryptEncryptMessage failed: %08x\n", GetLastError()); + CryptMemFree(encryptedBlob); + } + } + + if (certs[0]) + CertFreeCertificateContext(certs[0]); + if (certs[1]) + CertFreeCertificateContext(certs[1]); + if (hCryptProv) + CryptReleaseContext(hCryptProv, 0); +} + START_TEST(message) { + init_function_pointers(); + test_msg_get_signer_count(); test_verify_detached_message_hash(); test_verify_message_hash(); test_verify_detached_message_signature(); test_verify_message_signature(); test_hash_message(); + test_sign_message(); + test_encrypt_message(); } diff --git a/rostests/winetests/crypt32/msg.c b/rostests/winetests/crypt32/msg.c index 39662ebe8f2..d5d5309c828 100644 --- a/rostests/winetests/crypt32/msg.c +++ b/rostests/winetests/crypt32/msg.c @@ -365,6 +365,8 @@ static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb, return TRUE; } +static const BYTE dataEmptyBareContent[] = { 0x04,0x00 }; + static void test_data_msg_update(void) { HCRYPTMSG msg; @@ -390,20 +392,35 @@ static void test_data_msg_update(void) msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL, NULL); - /* Can't update a message with no data */ - SetLastError(0xdeadbeef); + /* Starting with Vista, can update a message with no data. */ ret = CryptMsgUpdate(msg, NULL, 0, TRUE); - /* This test returns FALSE on XP and earlier but TRUE on Vista, so can't be tested. - * GetLastError is either E_INVALIDARG (NT) or unset (9x/Vista), so it doesn't - * make sense to test this. - */ + ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError()); + if (ret) + { + DWORD size; - /* Curiously, a valid update will now fail as well, presumably because of - * the last (invalid, but final) update. - */ - ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); - ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, - "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); + ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size); + ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + if (ret) + { + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf, + &size); + ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + if (ret) + { + ok(size == sizeof(dataEmptyBareContent), + "unexpected size %d\n", size); + ok(!memcmp(buf, dataEmptyBareContent, size), + "unexpected value\n"); + } + CryptMemFree(buf); + } + } + } CryptMsgClose(msg); msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, @@ -510,7 +527,6 @@ static void test_data_msg_get_param(void) CryptMsgClose(msg); } -static const BYTE dataEmptyBareContent[] = { 0x04,0x00 }; static const BYTE dataEmptyContent[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02, 0x04,0x00 }; @@ -837,6 +853,8 @@ static void test_hash_msg_get_param(void) ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); ok(size == sizeof(buf), "Unexpected size %d\n", size); ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size); + ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + ok(size == sizeof(buf), "Unexpected size %d\n", size); if (size == sizeof(buf)) ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n"); /* By getting the hash, further updates are not allowed */ @@ -1820,6 +1838,7 @@ static void test_signed_msg_encoding(void) CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent, sizeof(signedWithCertWithValidPubKeyEmptyContent)); ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); check_param("signedWithCertWithValidPubKeyContent", msg, CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent, sizeof(signedWithCertWithValidPubKeyContent)); @@ -2031,6 +2050,239 @@ static void test_signed_msg(void) test_signed_msg_get_param(); } +static char oid_rsa_rc4[] = szOID_RSA_RC4; + +static void test_enveloped_msg_open(void) +{ + HCRYPTMSG msg; + BOOL ret; + CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 }; + PCCERT_CONTEXT context; + + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(!msg && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + + envelopedInfo.cbSize = sizeof(envelopedInfo); + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(!msg && + (GetLastError() == CRYPT_E_UNKNOWN_ALGO || + GetLastError() == E_INVALIDARG), /* Win9x */ + "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError()); + + envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4; + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + + envelopedInfo.cRecipients = 1; + if (!old_crypt32) + { + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(!msg && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + } + + context = CertCreateCertificateContext(X509_ASN_ENCODING, + v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey)); + if (context) + { + envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo; + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + SetLastError(0xdeadbeef); + ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + CryptReleaseContext(envelopedInfo.hCryptProv, 0); + CertFreeCertificateContext(context); + } + else + win_skip("failed to create certificate context, skipping tests\n"); +} + +static void test_enveloped_msg_update(void) +{ + HCRYPTMSG msg; + BOOL ret; + CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0, + { oid_rsa_rc4, { 0, NULL } }, NULL }; + CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL }; + + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, FALSE); + ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, + "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, + "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); + CryptMsgClose(msg); + } + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); + ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, + "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + ok(ret || + broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ + "CryptMsgUpdate failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, + "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); + CryptMsgClose(msg); + } + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, + CMSG_ENVELOPED, &envelopedInfo, NULL, NULL); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, FALSE); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + } + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, + CMSG_ENVELOPED, &envelopedInfo, NULL, NULL); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + ok(ret || + broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ + "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + } + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, &streamInfo); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, FALSE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + } + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, &streamInfo); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + ok(ret || + broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */ + "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + } +} + +static const BYTE envelopedEmptyBareContent[] = { +0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x03,0x04,0x05,0x00,0x80,0x00 }; +static const BYTE envelopedEmptyContent[] = { +0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24, +0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x03,0x04,0x05,0x00,0x80,0x00 }; + +static void test_enveloped_msg_encoding(void) +{ + HCRYPTMSG msg; + CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0, + { oid_rsa_rc4, { 0, NULL } }, NULL }; + + SetLastError(0xdeadbeef); + msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, + &envelopedInfo, NULL, NULL); + ok(msg != NULL || + broken(!msg), /* Win9x */ + "CryptMsgOpenToEncode failed: %08x\n", GetLastError()); + if (msg) + { + check_param("enveloped empty bare content", msg, + CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent, + sizeof(envelopedEmptyBareContent)); + check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, + envelopedEmptyContent, sizeof(envelopedEmptyContent)); + CryptMsgClose(msg); + } +} + +static void test_enveloped_msg(void) +{ + test_enveloped_msg_open(); + test_enveloped_msg_update(); + test_enveloped_msg_encoding(); +} + static CRYPT_DATA_BLOB b4 = { 0, NULL }; static const struct update_accum a4 = { 1, &b4 }; @@ -2043,6 +2295,22 @@ static const BYTE bogusHashContent[] = { 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0, 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; +static const BYTE envelopedBareContentWithoutData[] = { +0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00, +0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01, +0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01, +0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b, +0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f, +0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94, +0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72, +0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18, +0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3, +0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6, +0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49, +0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e, +0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 }; static void test_decode_msg_update(void) { @@ -2343,6 +2611,50 @@ static void test_decode_msg_update(void) ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError()); CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedEmptyBareContent, + sizeof(envelopedEmptyBareContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedEmptyContent, + sizeof(envelopedEmptyContent), TRUE); + ok(!ret && + (GetLastError() == CRYPT_E_ASN1_BADTAG || + GetLastError() == OSS_DATA_ERROR), /* Win9x */ + "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedEmptyBareContent, + sizeof(envelopedEmptyBareContent), TRUE); + ok(!ret && + (GetLastError() == CRYPT_E_ASN1_BADTAG || + GetLastError() == OSS_DATA_ERROR), /* Win9x */ + "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedEmptyContent, + sizeof(envelopedEmptyContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData, + sizeof(envelopedBareContentWithoutData), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + CryptMsgClose(msg); } static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1, @@ -2416,13 +2728,140 @@ static const BYTE signedWithCertAndCrlComputedHash[] = { static BYTE keyIdIssuer[] = { 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37, 0x0a,0x07,0x01,0x04,0x01,0x01 }; +static const BYTE publicPrivateKeyPair[] = { +0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00, +0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b, +0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50, +0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54, +0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39, +0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7, +0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48, +0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17, +0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54, +0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33, +0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52, +0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e, +0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61, +0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb, +0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02, +0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90, +0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e, +0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce, +0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14, +0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5, +0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5, +0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94, +0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68, +0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71, +0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25, +0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc, +0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a, +0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64, +0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77, +0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68, +0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab, +0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9, +0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed, +0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01, +0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e, +0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71, +0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0, +0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87, +0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b, +0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e }; +static const BYTE envelopedMessage[] = { +0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0, +0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02, +0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03, +0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5, +0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, +0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65, +0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae, +0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1, +0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51, +0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf, +0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b, +0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e, +0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e, +0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70, +0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01, +0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80, +0x04,0x5f,0x80,0xf2,0x17 }; +static const BYTE envelopedBareMessage[] = { +0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00, +0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01, +0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01, +0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d, +0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d, +0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5, +0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e, +0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2, +0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4, +0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70, +0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c, +0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55, +0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c, +0x2d,0xa3,0x6e }; +static const BYTE envelopedMessageWith3Recps[] = { +0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03, +0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e, +0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06, +0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36, +0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e, +0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba, +0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f, +0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5, +0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21, +0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae, +0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0, +0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96, +0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae, +0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30, +0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10, +0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6, +0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05, +0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf, +0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9, +0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3, +0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02, +0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70, +0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3, +0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74, +0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94, +0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7, +0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04, +0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a, +0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98, +0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5, +0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9, +0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3, +0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8, +0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac, +0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc, +0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5, +0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1, +0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07, +0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00, +0x80,0x04,0x4e,0x99,0x9d,0x4c }; +static const BYTE serialNumber[] = { +0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2, +0x1c }; +static const BYTE issuer[] = { +0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 }; static void test_decode_msg_get_param(void) { HCRYPTMSG msg; + HCRYPTPROV hCryptProv; + HCRYPTKEY key = 0; BOOL ret; DWORD size = 0, value; LPBYTE buf; + CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 }; msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); SetLastError(0xdeadbeef); @@ -2430,6 +2869,7 @@ static void test_decode_msg_get_param(void) ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); check_param("data content", msg, CMSG_CONTENT_PARAM, msgData, sizeof(msgData)); CryptMsgClose(msg); @@ -2447,6 +2887,7 @@ static void test_decode_msg_get_param(void) CryptMsgClose(msg); msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData, sizeof(msgData)); check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam, @@ -2466,6 +2907,7 @@ static void test_decode_msg_get_param(void) if (buf) { ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size); + ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); ok(size == sizeof(hashParam), "Unexpected size %d\n", size); ok(!memcmp(buf, hashParam, size), "Unexpected value\n"); CryptMemFree(buf); @@ -2632,6 +3074,114 @@ static void test_decode_msg_get_param(void) CryptMemFree(buf); } CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + CryptMsgUpdate(msg, envelopedEmptyBareContent, + sizeof(envelopedEmptyBareContent), TRUE); + check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL, + 0); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); + CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent), + TRUE); + check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0); + CryptMsgClose(msg); + + pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT); + SetLastError(0xdeadbeef); + ret = CryptImportKey(hCryptProv, publicPrivateKeyPair, + sizeof(publicPrivateKeyPair), 0, 0, &key); + ok(ret || + broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */ + "CryptImportKey failed: %08x\n", GetLastError()); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); + CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE); + check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM, + envelopedMessage + sizeof(envelopedMessage) - 4, 4); + if (key) + { + decryptPara.hCryptProv = hCryptProv; + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); + decryptPara.hCryptProv = 0; + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED, + "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError()); + check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData, + sizeof(msgData)); + } + else + win_skip("failed to import a key, skipping tests\n"); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage), + TRUE); + check_param("enveloped bare message before decrypting", msg, + CMSG_CONTENT_PARAM, envelopedBareMessage + + sizeof(envelopedBareMessage) - 4, 4); + if (key) + { + decryptPara.hCryptProv = hCryptProv; + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); + check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData, + sizeof(msgData)); + } + else + win_skip("failed to import a key, skipping tests\n"); + CryptMsgClose(msg); + + if (key) + CryptDestroyKey(key); + CryptReleaseContext(hCryptProv, 0); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); + CryptMsgUpdate(msg, envelopedMessageWith3Recps, + sizeof(envelopedMessageWith3Recps), TRUE); + value = 3; + check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM, + (const BYTE *)&value, sizeof(value)); + size = 0; + SetLastError(0xdeadbeef); + ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size); + ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, + "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError()); + size = 0; + SetLastError(0xdeadbeef); + ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size); + ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + ok(size >= 142, "unexpected size: %u\n", size); + if (ret) + buf = CryptMemAlloc(size); + else + buf = NULL; + if (buf) + { + CERT_INFO *certInfo = (CERT_INFO *)buf; + + SetLastError(0xdeadbeef); + ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size); + ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError()); + ok(certInfo->SerialNumber.cbData == sizeof(serialNumber), + "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData); + ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber, + sizeof(serialNumber)), "unexpected serial number\n"); + ok(certInfo->Issuer.cbData == sizeof(issuer), + "unexpected issuer size: %u\n", certInfo->Issuer.cbData); + ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)), + "unexpected issuer\n"); + CryptMemFree(buf); + } + CryptMsgClose(msg); } static void test_decode_msg(void) @@ -2677,7 +3227,8 @@ static void test_msg_control(void) ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); } - ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); /* or after an update. */ for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { @@ -2702,6 +3253,7 @@ static void test_msg_control(void) "Expected E_INVALIDARG, got %08x\n", GetLastError()); } ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); /* or after an update. */ for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { @@ -2725,6 +3277,7 @@ static void test_msg_control(void) "Expected E_INVALIDARG, got %08x\n", GetLastError()); } ret = CryptMsgUpdate(msg, NULL, 0, TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); /* or after an update. */ for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++) { @@ -3003,6 +3556,43 @@ static void test_msg_control(void) ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */), "CryptMsgControl failed: %08x\n", GetLastError()); CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + decryptPara.cbSize = 0; + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + decryptPara.cbSize = sizeof(decryptPara); + if (!old_crypt32) + { + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, + "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError()); + } + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedEmptyBareContent, + sizeof(envelopedEmptyBareContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX, + "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError()); + CryptMsgClose(msg); + + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL, + NULL); + SetLastError(0xdeadbeef); + ret = CryptMsgUpdate(msg, envelopedBareMessage, + sizeof(envelopedBareMessage), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + CryptMsgClose(msg); } /* win9x has much less parameter checks and will crash on many tests @@ -3052,8 +3642,8 @@ static void test_msg_get_and_verify_signer(void) /* Crash */ if (0) { - ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL); - ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex); + CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL); + CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex); } msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); @@ -3192,6 +3782,7 @@ START_TEST(msg) test_data_msg(); test_hash_msg(); test_signed_msg(); + test_enveloped_msg(); test_decode_msg(); test_msg_get_and_verify_signer(); diff --git a/rostests/winetests/crypt32/oid.c b/rostests/winetests/crypt32/oid.c index 030a548ac1a..b6614071aba 100644 --- a/rostests/winetests/crypt32/oid.c +++ b/rostests/winetests/crypt32/oid.c @@ -451,6 +451,7 @@ static void test_registerDefaultOIDFunction(void) /* Repeat a few tests on the normal encoding type */ ret = CryptRegisterDefaultOIDFunction(X509_ASN_ENCODING, "CertDllOpenStoreProv", 0, bogusDll); + ok(ret, "CryptRegisterDefaultOIDFunction failed\n"); ret = CryptUnregisterDefaultOIDFunction(X509_ASN_ENCODING, "CertDllOpenStoreProv", bogusDll); ok(ret, "CryptUnregisterDefaultOIDFunction failed\n"); diff --git a/rostests/winetests/crypt32/protectdata.c b/rostests/winetests/crypt32/protectdata.c index 29d04e81aa6..70a8ba86b05 100644 --- a/rostests/winetests/crypt32/protectdata.c +++ b/rostests/winetests/crypt32/protectdata.c @@ -244,7 +244,6 @@ static void test_simpleroundtrip(const char *plaintext) START_TEST(protectdata) { HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll"); - hCrypt32 = GetModuleHandleA("crypt32.dll"); pCryptProtectData = (void*)GetProcAddress(hCrypt32, "CryptProtectData"); pCryptUnprotectData = (void*)GetProcAddress(hCrypt32, "CryptUnprotectData"); if (!pCryptProtectData || !pCryptUnprotectData) diff --git a/rostests/winetests/crypt32/store.c b/rostests/winetests/crypt32/store.c index 10a85a346fe..40d407a41a0 100644 --- a/rostests/winetests/crypt32/store.c +++ b/rostests/winetests/crypt32/store.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include + #include #include #include @@ -102,6 +102,7 @@ static BOOL (WINAPI *pCertEnumSystemStore)(DWORD,void*,void*,PFN_CERT_ENUM_SYSTE static BOOL (WINAPI *pCertGetStoreProperty)(HCERTSTORE,DWORD,void*,DWORD*); static void (WINAPI *pCertRemoveStoreFromCollection)(HCERTSTORE,HCERTSTORE); static BOOL (WINAPI *pCertSetStoreProperty)(HCERTSTORE,DWORD,DWORD,const void*); +static BOOL (WINAPI *pCertAddCertificateLinkToStore)(HCERTSTORE,PCCERT_CONTEXT,DWORD,PCCERT_CONTEXT*); static void testMemStore(void) { @@ -199,6 +200,7 @@ static void testMemStore(void) if (buf) { ret = CertSerializeCertificateStoreElement(context, 0, buf, &size); + ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError()); ok(size == sizeof(serializedCert), "Wrong size %d\n", size); ok(!memcmp(serializedCert, buf, size), "Unexpected serialized cert\n"); @@ -633,7 +635,7 @@ static void testCollectionStore(void) ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); CertDeleteCertificateFromStore(context); - CertAddStoreToCollection(collection, store1, + pCertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, @@ -958,7 +960,7 @@ static void testRegStore(void) certCount++; } while (context != NULL); ok(certCount == 1 || - broken(certCount == 2), /* win9x */ + broken(certCount == 2) /* NT4 */ , "Expected 1 certificates, got %d\n", certCount); /* Try again with the correct hash... */ @@ -1074,6 +1076,7 @@ static void testSystemRegStore(void) /* Now check whether deleting is allowed */ store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW); + ok(!store, "CertOpenStore failed: %08x\n", GetLastError()); RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 0, NULL); @@ -1158,10 +1161,7 @@ static void testSystemStore(void) /* Check opening a bogus store */ store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW); - ok((!store || - broken(store != 0)) && /* win9x */ - GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); + ok(!store, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, BogusW); ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError()); @@ -1170,6 +1170,7 @@ static void testSystemStore(void) /* Now check whether deleting is allowed */ store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW); + ok(!store, "Didn't expect a store to be returned when deleting\n"); RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); } @@ -1760,7 +1761,7 @@ static void testMessageStore(void) store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob); ok(!store && (GetLastError() == CRYPT_E_ASN1_BADTAG || - GetLastError() == OSS_DATA_ERROR), /* win9x */ + broken(GetLastError() == OSS_DATA_ERROR)), /* NT4 */ "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError()); } @@ -1842,7 +1843,7 @@ static void testCertOpenSystemStore(void) if (store) CertCloseStore(store, 0); /* Delete it so other tests succeed next time around */ - store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, + CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW); RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); } @@ -2189,26 +2190,32 @@ static void testAddCertificateLink(void) WCHAR filename1[MAX_PATH], filename2[MAX_PATH]; HANDLE file; + if (!pCertAddCertificateLinkToStore) + { + win_skip("CertAddCertificateLinkToStore not found\n"); + return; + } + if (0) { /* Crashes, i.e. the store is dereferenced without checking. */ - ret = CertAddCertificateLinkToStore(NULL, NULL, 0, NULL); + ret = pCertAddCertificateLinkToStore(NULL, NULL, 0, NULL); } /* Adding a certificate link to a store requires a valid add disposition */ store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); SetLastError(0xdeadbeef); - ret = CertAddCertificateLinkToStore(store1, NULL, 0, NULL); + ret = pCertAddCertificateLinkToStore(store1, NULL, 0, NULL); ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); SetLastError(0xdeadbeef); - ret = CertAddCertificateLinkToStore(store1, source, 0, NULL); + ret = pCertAddCertificateLinkToStore(store1, source, 0, NULL); ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); - ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, NULL); ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); if (0) @@ -2216,14 +2223,14 @@ static void testAddCertificateLink(void) /* Crashes, i.e. the source certificate is dereferenced without * checking when a valid add disposition is given. */ - ret = CertAddCertificateLinkToStore(store1, NULL, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store1, NULL, CERT_STORE_ADD_ALWAYS, NULL); } CertCloseStore(store1, 0); store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); - ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, &linked); ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); if (ret) @@ -2236,6 +2243,8 @@ static void testAddCertificateLink(void) if (buf) { ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size); + ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", + GetLastError()); /* The serialized linked certificate is identical to the serialized * original certificate. */ @@ -2261,6 +2270,8 @@ static void testAddCertificateLink(void) { ret = CertGetCertificateContextProperty(linked, CERT_FRIENDLY_NAME_PROP_ID, buf, &size); + ok(ret, "CertGetCertificateContextProperty failed: %08x\n", + GetLastError()); ok(!lstrcmpW((LPCWSTR)buf, WineTestW), "unexpected friendly name\n"); HeapFree(GetProcessHeap(), 0, buf); @@ -2295,7 +2306,7 @@ static void testAddCertificateLink(void) /* Test adding a link to a memory store. */ store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); - ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, &linked); ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); if (ret) @@ -2311,6 +2322,7 @@ static void testAddCertificateLink(void) /* The serialized linked certificate is identical to the serialized * original certificate. */ + ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError()); ok(size == sizeof(serializedCert), "Wrong size %d\n", size); ok(!memcmp(serializedCert, buf, size), "Unexpected serialized cert\n"); @@ -2333,6 +2345,7 @@ static void testAddCertificateLink(void) { ret = CertGetCertificateContextProperty(linked, CERT_FRIENDLY_NAME_PROP_ID, buf, &size); + ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError()); ok(!lstrcmpW((LPCWSTR)buf, WineTestW), "unexpected friendly name\n"); HeapFree(GetProcessHeap(), 0, buf); @@ -2355,7 +2368,7 @@ static void testAddCertificateLink(void) ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); CloseHandle(file); /* Test adding a link to a file store. */ - ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, &linked); ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); if (ret) @@ -2397,7 +2410,7 @@ static void testAddCertificateLink(void) source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); SetLastError(0xdeadbeef); - ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS, &linked); ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); @@ -2424,7 +2437,7 @@ static void testAddCertificateLink(void) ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); CloseHandle(file); - ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, &linked); ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); if (ret) @@ -2447,7 +2460,7 @@ static void testAddCertificateLink(void) store2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, WineTestW); ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); - ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, + ret = pCertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS, &linked); ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError()); if (ret) @@ -2573,6 +2586,7 @@ START_TEST(store) pCertGetStoreProperty = (void*)GetProcAddress(hdll, "CertGetStoreProperty"); pCertRemoveStoreFromCollection = (void*)GetProcAddress(hdll, "CertRemoveStoreFromCollection"); pCertSetStoreProperty = (void*)GetProcAddress(hdll, "CertSetStoreProperty"); + pCertAddCertificateLinkToStore = (void*)GetProcAddress(hdll, "CertAddCertificateLinkToStore"); /* various combinations of CertOpenStore */ testMemStore(); diff --git a/rostests/winetests/crypt32/str.c b/rostests/winetests/crypt32/str.c index ebc334240ae..14435975422 100644 --- a/rostests/winetests/crypt32/str.c +++ b/rostests/winetests/crypt32/str.c @@ -26,16 +26,12 @@ #include "wine/test.h" -/*#define DUMP_STRINGS*/ -#ifdef DUMP_STRINGS -#include "wine/debug.h" -#endif - typedef struct _CertRDNAttrEncoding { LPCSTR pszObjId; DWORD dwValueType; CERT_RDN_VALUE_BLOB Value; LPCSTR str; + BOOL todo; } CertRDNAttrEncoding, *PCertRDNAttrEncoding; typedef struct _CertRDNAttrEncodingW { @@ -43,6 +39,7 @@ typedef struct _CertRDNAttrEncodingW { DWORD dwValueType; CERT_RDN_VALUE_BLOB Value; LPCWSTR str; + BOOL todo; } CertRDNAttrEncodingW, *PCertRDNAttrEncodingW; static BYTE bin1[] = { 0x55, 0x53 }; @@ -58,6 +55,18 @@ static BYTE bin6[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74 }; static BYTE bin7[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d }; +static BYTE bin8[] = { +0x65,0x00,0x50,0x00,0x4b,0x00,0x49,0x00,0x20,0x00,0x52,0x00,0x6f,0x00,0x6f, +0x00,0x74,0x00,0x20,0x00,0x43,0x00,0x65,0x00,0x72,0x00,0x74,0x00,0x69,0x00, +0x66,0x00,0x69,0x00,0x63,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6f,0x00,0x6e, +0x00,0x20,0x00,0x41,0x00,0x75,0x00,0x74,0x00,0x68,0x00,0x6f,0x00,0x72,0x00, +0x69,0x00,0x74,0x00,0x79,0x00 }; +static BYTE bin9[] = { 0x61, 0x62, 0x63, 0x22, 0x64, 0x65, 0x66 }; +static BYTE bin10[] = { 0x61, 0x62, 0x63, 0x27, 0x64, 0x65, 0x66 }; +static BYTE bin11[] = { 0x61, 0x62, 0x63, 0x2c, 0x20, 0x64, 0x65, 0x66 }; +static BYTE bin12[] = { 0x20, 0x61, 0x62, 0x63, 0x20 }; +static BYTE bin13[] = { 0x22, 0x64, 0x65, 0x66, 0x22 }; +static BYTE bin14[] = { 0x31, 0x3b, 0x33 }; static const BYTE cert[] = {0x30,0x82,0x2,0xbb,0x30,0x82,0x2,0x24,0x2,0x9,0x0,0xe3,0x5a,0x10,0xf1,0xfc, @@ -190,8 +199,10 @@ typedef BOOL (WINAPI *CertStrToNameAFunc)(DWORD dwCertEncodingType, typedef BOOL (WINAPI *CertStrToNameWFunc)(DWORD dwCertEncodingType, LPCWSTR pszX500, DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, LPCWSTR *ppszError); +typedef DWORD (WINAPI *CertGetNameStringAFunc)(PCCERT_CONTEXT cert, DWORD type, + DWORD flags, void *typePara, LPSTR str, DWORD cch); -HMODULE dll; +static HMODULE dll; static CertNameToStrAFunc pCertNameToStrA; static CertNameToStrWFunc pCertNameToStrW; static CryptDecodeObjectFunc pCryptDecodeObject; @@ -199,28 +210,42 @@ static CertRDNValueToStrAFunc pCertRDNValueToStrA; static CertRDNValueToStrWFunc pCertRDNValueToStrW; static CertStrToNameAFunc pCertStrToNameA; static CertStrToNameWFunc pCertStrToNameW; +static CertGetNameStringAFunc pCertGetNameStringA; static void test_CertRDNValueToStrA(void) { CertRDNAttrEncoding attrs[] = { { "2.5.4.6", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin1), bin1 }, "US" }, + { sizeof(bin1), bin1 }, "US", FALSE }, { "2.5.4.8", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin2), bin2 }, "Minnesota" }, + { sizeof(bin2), bin2 }, "Minnesota", FALSE }, { "2.5.4.7", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin3), bin3 }, "Minneapolis" }, + { sizeof(bin3), bin3 }, "Minneapolis", FALSE }, { "2.5.4.10", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin4), bin4 }, "CodeWeavers" }, + { sizeof(bin4), bin4 }, "CodeWeavers", FALSE }, { "2.5.4.11", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin5), bin5 }, "Wine Development" }, + { sizeof(bin5), bin5 }, "Wine Development", FALSE }, { "2.5.4.3", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin6), bin6 }, "localhost" }, + { sizeof(bin6), bin6 }, "localhost", FALSE }, { "1.2.840.113549.1.9.1", CERT_RDN_IA5_STRING, - { sizeof(bin7), bin7 }, "aric@codeweavers.com" }, + { sizeof(bin7), bin7 }, "aric@codeweavers.com", FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin9), bin9 }, "abc\"def", FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin10), bin10 }, "abc'def", FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin11), bin11 }, "abc, def", FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin12), bin12 }, " abc ", FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin13), bin13 }, "\"def\"", FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin14), bin14 }, "1;3", FALSE }, }; DWORD i, ret; char buffer[2000]; CERT_RDN_VALUE_BLOB blob = { 0, NULL }; + static const char ePKI[] = "ePKI Root Certification Authority"; if (!pCertRDNValueToStrA) return; @@ -239,11 +264,31 @@ static void test_CertRDNValueToStrA(void) { ret = pCertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value, buffer, sizeof(buffer)); - ok(ret == strlen(attrs[i].str) + 1, "Expected length %d, got %d\n", - lstrlenA(attrs[i].str) + 1, ret); - ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n", attrs[i].str, - buffer); + if (attrs[i].todo) + { + todo_wine + ok(ret == strlen(attrs[i].str) + 1, "Expected length %d, got %d\n", + lstrlenA(attrs[i].str) + 1, ret); + todo_wine + ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n", + attrs[i].str, buffer); + } + else + { + ok(ret == strlen(attrs[i].str) + 1, "Expected length %d, got %d\n", + lstrlenA(attrs[i].str) + 1, ret); + ok(!strcmp(buffer, attrs[i].str), "Expected %s, got %s\n", + attrs[i].str, buffer); + } } + blob.pbData = bin8; + blob.cbData = sizeof(bin8); + ret = pCertRDNValueToStrA(CERT_RDN_UTF8_STRING, &blob, buffer, + sizeof(buffer)); + ok(ret == strlen(ePKI) + 1 || broken(ret != strlen(ePKI) + 1), + "Expected length %d, got %d\n", lstrlenA(ePKI), ret); + if (ret == strlen(ePKI) + 1) + ok(!strcmp(buffer, ePKI), "Expected %s, got %s\n", ePKI, buffer); } static void test_CertRDNValueToStrW(void) @@ -259,21 +304,44 @@ static void test_CertRDNValueToStrW(void) static const WCHAR localhostW[] = { 'l','o','c','a','l','h','o','s','t',0 }; static const WCHAR aricW[] = { 'a','r','i','c','@','c','o','d','e','w','e', 'a','v','e','r','s','.','c','o','m',0 }; + static const WCHAR ePKIW[] = { 'e','P','K','I',' ','R','o','o','t',' ', + 'C','e','r','t','i','f','i','c','a','t','i','o','n',' ','A','u','t','h', + 'o','r','i','t','y',0 }; + static const WCHAR embeddedDoubleQuoteW[] = { 'a','b','c','"','d','e','f', + 0 }; + static const WCHAR embeddedSingleQuoteW[] = { 'a','b','c','\'','d','e','f', + 0 }; + static const WCHAR embeddedCommaW[] = { 'a','b','c',',',' ','d','e','f',0 }; + static const WCHAR trailingAndEndingSpaceW[] = { ' ','a','b','c',' ',0 }; + static const WCHAR enclosingQuotesW[] = { '"','d','e','f','"',0 }; + static const WCHAR embeddedSemiW[] = { '1',';','3',0 }; CertRDNAttrEncodingW attrs[] = { { "2.5.4.6", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin1), bin1 }, usW }, + { sizeof(bin1), bin1 }, usW, FALSE }, { "2.5.4.8", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin2), bin2 }, minnesotaW }, + { sizeof(bin2), bin2 }, minnesotaW, FALSE }, { "2.5.4.7", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin3), bin3 }, minneapolisW }, + { sizeof(bin3), bin3 }, minneapolisW, FALSE }, { "2.5.4.10", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin4), bin4 }, codeweaversW }, + { sizeof(bin4), bin4 }, codeweaversW, FALSE }, { "2.5.4.11", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin5), bin5 }, wineDevW }, + { sizeof(bin5), bin5 }, wineDevW, FALSE }, { "2.5.4.3", CERT_RDN_PRINTABLE_STRING, - { sizeof(bin6), bin6 }, localhostW }, + { sizeof(bin6), bin6 }, localhostW, FALSE }, { "1.2.840.113549.1.9.1", CERT_RDN_IA5_STRING, - { sizeof(bin7), bin7 }, aricW }, + { sizeof(bin7), bin7 }, aricW, FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin9), bin9 }, embeddedDoubleQuoteW, FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin10), bin10 }, embeddedSingleQuoteW, FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin11), bin11 }, embeddedCommaW, FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin12), bin12 }, trailingAndEndingSpaceW, FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin13), bin13 }, enclosingQuotesW, FALSE }, + { "0", CERT_RDN_PRINTABLE_STRING, + { sizeof(bin14), bin14 }, embeddedSemiW, FALSE }, }; DWORD i, ret; WCHAR buffer[2000]; @@ -301,35 +369,102 @@ static void test_CertRDNValueToStrW(void) { ret = pCertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value, buffer, sizeof(buffer) / sizeof(buffer[0])); - ok(ret == lstrlenW(attrs[i].str) + 1, "Expected length %d, got %d\n", - lstrlenW(attrs[i].str) + 1, ret); - ok(!lstrcmpW(buffer, attrs[i].str), "Unexpected value\n"); -#ifdef DUMP_STRINGS - trace("Expected %s, got %s\n", - wine_dbgstr_w(attrs[i].str), wine_dbgstr_w(buffer)); -#endif + if (attrs[i].todo) + { + todo_wine + ok(ret == lstrlenW(attrs[i].str) + 1, + "Expected length %d, got %d\n", lstrlenW(attrs[i].str) + 1, ret); + todo_wine + ok(!lstrcmpW(buffer, attrs[i].str), "Expected %s, got %s\n", + wine_dbgstr_w(attrs[i].str), wine_dbgstr_w(buffer)); + } + else + { + ok(ret == lstrlenW(attrs[i].str) + 1, + "Expected length %d, got %d\n", lstrlenW(attrs[i].str) + 1, ret); + ok(!lstrcmpW(buffer, attrs[i].str), "Expected %s, got %s\n", + wine_dbgstr_w(attrs[i].str), wine_dbgstr_w(buffer)); + } } + blob.pbData = bin8; + blob.cbData = sizeof(bin8); + ret = pCertRDNValueToStrW(CERT_RDN_UTF8_STRING, &blob, buffer, + sizeof(buffer)); + ok(ret == lstrlenW(ePKIW) + 1 || broken(ret != lstrlenW(ePKIW) + 1), + "Expected length %d, got %d\n", lstrlenW(ePKIW), ret); + if (ret == lstrlenW(ePKIW) + 1) + ok(!lstrcmpW(buffer, ePKIW), "Expected %s, got %s\n", + wine_dbgstr_w(ePKIW), wine_dbgstr_w(buffer)); } static void test_NameToStrConversionA(PCERT_NAME_BLOB pName, DWORD dwStrType, - LPCSTR expected) + LPCSTR expected, BOOL todo) { char buffer[2000] = { 0 }; DWORD i; i = pCertNameToStrA(X509_ASN_ENCODING, pName, dwStrType, NULL, 0); - ok(i == strlen(expected) + 1, "Expected %d chars, got %d\n", - lstrlenA(expected) + 1, i); + if (todo) + todo_wine + ok(i == strlen(expected) + 1, "Expected %d chars, got %d\n", + lstrlenA(expected) + 1, i); + else + ok(i == strlen(expected) + 1, "Expected %d chars, got %d\n", + lstrlenA(expected) + 1, i); i = pCertNameToStrA(X509_ASN_ENCODING,pName, dwStrType, buffer, sizeof(buffer)); - ok(i == strlen(expected) + 1, "Expected %d chars, got %d\n", - lstrlenA(expected) + 1, i); - ok(!strcmp(buffer, expected), "Expected %s, got %s\n", expected, buffer); + if (todo) + todo_wine + ok(i == strlen(expected) + 1, "Expected %d chars, got %d\n", + lstrlenA(expected) + 1, i); + else + ok(i == strlen(expected) + 1, "Expected %d chars, got %d\n", + lstrlenA(expected) + 1, i); + if (todo) + todo_wine + ok(!strcmp(buffer, expected), "Expected %s, got %s\n", expected, + buffer); + else + ok(!strcmp(buffer, expected), "Expected %s, got %s\n", expected, + buffer); } +static BYTE encodedSimpleCN[] = { +0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x31 }; +static BYTE encodedSingleQuotedCN[] = { 0x30,0x0e,0x31,0x0c,0x30,0x0a, + 0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x27,0x31,0x27 }; +static BYTE encodedSpacedCN[] = { 0x30,0x0e,0x31,0x0c,0x30,0x0a,0x06,0x03, + 0x55,0x04,0x03,0x13,0x03,0x20,0x31,0x20 }; +static BYTE encodedQuotedCN[] = { 0x30,0x11,0x31,0x0f,0x30,0x0d,0x06,0x03, + 0x55, 0x04,0x03,0x1e,0x06,0x00,0x22,0x00,0x31,0x00,0x22, }; +static BYTE encodedMultipleAttrCN[] = { 0x30,0x0e,0x31,0x0c,0x30,0x0a, + 0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x31,0x2b,0x32 }; +static BYTE encodedCommaCN[] = { +0x30,0x0e,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x61,0x2c, +0x62 }; +static BYTE encodedEqualCN[] = { +0x30,0x0e,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x61,0x3d, +0x62 }; +static BYTE encodedLessThanCN[] = { +0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x1e,0x02,0x00,0x3c +}; +static BYTE encodedGreaterThanCN[] = { +0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x1e,0x02,0x00,0x3e +}; +static BYTE encodedHashCN[] = { +0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x1e,0x02,0x00,0x23 +}; +static BYTE encodedSemiCN[] = { +0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x03,0x1e,0x02,0x00,0x3b +}; +static BYTE encodedNewlineCN[] = { +0x30,0x11,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x03,0x1e,0x06,0x00,0x61, +0x00,0x0a,0x00,0x62 }; + static void test_CertNameToStrA(void) { PCCERT_CONTEXT context; + CERT_NAME_BLOB blob; if (!pCertNameToStrA) { @@ -362,53 +497,137 @@ static void test_CertNameToStrA(void) ret, GetLastError()); test_NameToStrConversionA(&context->pCertInfo->Issuer, - CERT_SIMPLE_NAME_STR, issuerStr); + CERT_SIMPLE_NAME_STR, issuerStr, FALSE); test_NameToStrConversionA(&context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG, - issuerStrSemicolon); + issuerStrSemicolon, FALSE); test_NameToStrConversionA(&context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR | CERT_NAME_STR_CRLF_FLAG, - issuerStrCRLF); + issuerStrCRLF, FALSE); test_NameToStrConversionA(&context->pCertInfo->Subject, - CERT_OID_NAME_STR, subjectStr); + CERT_OID_NAME_STR, subjectStr, FALSE); test_NameToStrConversionA(&context->pCertInfo->Subject, CERT_OID_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG, - subjectStrSemicolon); + subjectStrSemicolon, FALSE); test_NameToStrConversionA(&context->pCertInfo->Subject, CERT_OID_NAME_STR | CERT_NAME_STR_CRLF_FLAG, - subjectStrCRLF); + subjectStrCRLF, FALSE); test_NameToStrConversionA(&context->pCertInfo->Subject, - CERT_X500_NAME_STR, x500SubjectStr); + CERT_X500_NAME_STR, x500SubjectStr, FALSE); test_NameToStrConversionA(&context->pCertInfo->Subject, - CERT_X500_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG | CERT_NAME_STR_REVERSE_FLAG, x500SubjectStrSemicolonReverse); + CERT_X500_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG | CERT_NAME_STR_REVERSE_FLAG, + x500SubjectStrSemicolonReverse, FALSE); CertFreeCertificateContext(context); } + blob.pbData = encodedSimpleCN; + blob.cbData = sizeof(encodedSimpleCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=1", FALSE); + blob.pbData = encodedSingleQuotedCN; + blob.cbData = sizeof(encodedSingleQuotedCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN='1'", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "'1'", FALSE); + blob.pbData = encodedSpacedCN; + blob.cbData = sizeof(encodedSpacedCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\" 1 \"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\" 1 \"", FALSE); + blob.pbData = encodedQuotedCN; + blob.cbData = sizeof(encodedQuotedCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"\"\"1\"\"\"", + FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"\"\"1\"\"\"", + FALSE); + blob.pbData = encodedMultipleAttrCN; + blob.cbData = sizeof(encodedMultipleAttrCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"1+2\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"1+2\"", FALSE); + blob.pbData = encodedCommaCN; + blob.cbData = sizeof(encodedCommaCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"a,b\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"a,b\"", FALSE); + blob.pbData = encodedEqualCN; + blob.cbData = sizeof(encodedEqualCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"a=b\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"a=b\"", FALSE); + blob.pbData = encodedLessThanCN; + blob.cbData = sizeof(encodedLessThanCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"<\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"<\"", FALSE); + blob.pbData = encodedGreaterThanCN; + blob.cbData = sizeof(encodedGreaterThanCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\">\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\">\"", FALSE); + blob.pbData = encodedHashCN; + blob.cbData = sizeof(encodedHashCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"#\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"#\"", FALSE); + blob.pbData = encodedSemiCN; + blob.cbData = sizeof(encodedSemiCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\";\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\";\"", FALSE); + blob.pbData = encodedNewlineCN; + blob.cbData = sizeof(encodedNewlineCN); + test_NameToStrConversionA(&blob, CERT_X500_NAME_STR, "CN=\"a\nb\"", FALSE); + test_NameToStrConversionA(&blob, CERT_SIMPLE_NAME_STR, "\"a\nb\"", FALSE); } static void test_NameToStrConversionW(PCERT_NAME_BLOB pName, DWORD dwStrType, - LPCWSTR expected) + LPCWSTR expected, BOOL todo) { WCHAR buffer[2000] = { 0 }; DWORD i; i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, NULL, 0); - ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n", - lstrlenW(expected) + 1, i); + if (todo) + todo_wine ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n", + lstrlenW(expected) + 1, i); + else + ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n", + lstrlenW(expected) + 1, i); i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, buffer, sizeof(buffer) / sizeof(buffer[0])); - ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n", - lstrlenW(expected) + 1, i); - ok(!lstrcmpW(buffer, expected), "Unexpected value\n"); -#ifdef DUMP_STRINGS - trace("Expected %s, got %s\n", - wine_dbgstr_w(expected), wine_dbgstr_w(buffer)); -#endif + if (todo) + todo_wine ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n", + lstrlenW(expected) + 1, i); + else + ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n", + lstrlenW(expected) + 1, i); + if (todo) + todo_wine ok(!lstrcmpW(buffer, expected), "Expected %s, got %s\n", + wine_dbgstr_w(expected), wine_dbgstr_w(buffer)); + else + ok(!lstrcmpW(buffer, expected), "Expected %s, got %s\n", + wine_dbgstr_w(expected), wine_dbgstr_w(buffer)); } +static const WCHAR simpleCN_W[] = { 'C','N','=','1',0 }; +static const WCHAR singledQuotedCN_W[] = { 'C','N','=','\'','1','\'',0 }; +static const WCHAR simpleSingleQuotedCN_W[] = { '\'','1','\'',0 }; +static const WCHAR spacedCN_W[] = { 'C','N','=','"',' ','1',' ','"',0 }; +static const WCHAR simpleSpacedCN_W[] = { '"',' ','1',' ','"',0 }; +static const WCHAR quotedCN_W[] = { 'C','N','=','"','"','"','1','"','"','"',0 }; +static const WCHAR simpleQuotedCN_W[] = { '"','"','"','1','"','"','"',0 }; +static const WCHAR multipleAttrCN_W[] = { 'C','N','=','"','1','+','2','"',0 }; +static const WCHAR simpleMultipleAttrCN_W[] = { '"','1','+','2','"',0 }; +static const WCHAR commaCN_W[] = { 'C','N','=','"','a',',','b','"',0 }; +static const WCHAR simpleCommaCN_W[] = { '"','a',',','b','"',0 }; +static const WCHAR equalCN_W[] = { 'C','N','=','"','a','=','b','"',0 }; +static const WCHAR simpleEqualCN_W[] = { '"','a','=','b','"',0 }; +static const WCHAR lessThanCN_W[] = { 'C','N','=','"','<','"',0 }; +static const WCHAR simpleLessThanCN_W[] = { '"','<','"',0 }; +static const WCHAR greaterThanCN_W[] = { 'C','N','=','"','>','"',0 }; +static const WCHAR simpleGreaterThanCN_W[] = { '"','>','"',0 }; +static const WCHAR hashCN_W[] = { 'C','N','=','"','#','"',0 }; +static const WCHAR simpleHashCN_W[] = { '"','#','"',0 }; +static const WCHAR semiCN_W[] = { 'C','N','=','"',';','"',0 }; +static const WCHAR simpleSemiCN_W[] = { '"',';','"',0 }; +static const WCHAR newlineCN_W[] = { 'C','N','=','"','a','\n','b','"',0 }; +static const WCHAR simpleNewlineCN_W[] = { '"','a','\n','b','"',0 }; + static void test_CertNameToStrW(void) { PCCERT_CONTEXT context; + CERT_NAME_BLOB blob; if (!pCertNameToStrW) { @@ -441,26 +660,89 @@ static void test_CertNameToStrW(void) ret, GetLastError()); test_NameToStrConversionW(&context->pCertInfo->Issuer, - CERT_SIMPLE_NAME_STR, issuerStrW); + CERT_SIMPLE_NAME_STR, issuerStrW, FALSE); test_NameToStrConversionW(&context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG, - issuerStrSemicolonW); + issuerStrSemicolonW, FALSE); test_NameToStrConversionW(&context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR | CERT_NAME_STR_CRLF_FLAG, - issuerStrCRLFW); + issuerStrCRLFW, FALSE); test_NameToStrConversionW(&context->pCertInfo->Subject, - CERT_OID_NAME_STR, subjectStrW); + CERT_OID_NAME_STR, subjectStrW, FALSE); test_NameToStrConversionW(&context->pCertInfo->Subject, CERT_OID_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG, - subjectStrSemicolonW); + subjectStrSemicolonW, FALSE); test_NameToStrConversionW(&context->pCertInfo->Subject, CERT_OID_NAME_STR | CERT_NAME_STR_CRLF_FLAG, - subjectStrCRLFW); + subjectStrCRLFW, FALSE); test_NameToStrConversionW(&context->pCertInfo->Subject, - CERT_X500_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG | CERT_NAME_STR_REVERSE_FLAG, x500SubjectStrSemicolonReverseW); + CERT_X500_NAME_STR | CERT_NAME_STR_SEMICOLON_FLAG | CERT_NAME_STR_REVERSE_FLAG, + x500SubjectStrSemicolonReverseW, FALSE); CertFreeCertificateContext(context); } + blob.pbData = encodedSimpleCN; + blob.cbData = sizeof(encodedSimpleCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, simpleCN_W, FALSE); + blob.pbData = encodedSingleQuotedCN; + blob.cbData = sizeof(encodedSingleQuotedCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, singledQuotedCN_W, + FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, + simpleSingleQuotedCN_W, FALSE); + blob.pbData = encodedSpacedCN; + blob.cbData = sizeof(encodedSpacedCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, spacedCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleSpacedCN_W, + FALSE); + blob.pbData = encodedQuotedCN; + blob.cbData = sizeof(encodedQuotedCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, quotedCN_W, + FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleQuotedCN_W, + FALSE); + blob.pbData = encodedMultipleAttrCN; + blob.cbData = sizeof(encodedMultipleAttrCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, multipleAttrCN_W, + FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, + simpleMultipleAttrCN_W, FALSE); + blob.pbData = encodedCommaCN; + blob.cbData = sizeof(encodedCommaCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, commaCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleCommaCN_W, + FALSE); + blob.pbData = encodedEqualCN; + blob.cbData = sizeof(encodedEqualCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, equalCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleEqualCN_W, + FALSE); + blob.pbData = encodedLessThanCN; + blob.cbData = sizeof(encodedLessThanCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, lessThanCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleLessThanCN_W, + FALSE); + blob.pbData = encodedGreaterThanCN; + blob.cbData = sizeof(encodedGreaterThanCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, greaterThanCN_W, + FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, + simpleGreaterThanCN_W, FALSE); + blob.pbData = encodedHashCN; + blob.cbData = sizeof(encodedHashCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, hashCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleHashCN_W, + FALSE); + blob.pbData = encodedSemiCN; + blob.cbData = sizeof(encodedSemiCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, semiCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleSemiCN_W, + FALSE); + blob.pbData = encodedNewlineCN; + blob.cbData = sizeof(encodedNewlineCN); + test_NameToStrConversionW(&blob, CERT_X500_NAME_STR, newlineCN_W, FALSE); + test_NameToStrConversionW(&blob, CERT_SIMPLE_NAME_STR, simpleNewlineCN_W, + FALSE); } struct StrToNameA @@ -470,18 +752,7 @@ struct StrToNameA const BYTE *encoded; }; -const BYTE encodedSimpleCN[] = { -0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x31 }; -static const BYTE encodedSingleQuotedCN[] = { 0x30,0x0e,0x31,0x0c,0x30,0x0a, - 0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x27,0x31,0x27 }; -static const BYTE encodedSpacedCN[] = { 0x30,0x0e,0x31,0x0c,0x30,0x0a,0x06,0x03, - 0x55,0x04,0x03,0x13,0x03,0x20,0x31,0x20 }; -static const BYTE encodedQuotedCN[] = { 0x30,0x11,0x31,0x0f,0x30,0x0d,0x06,0x03, - 0x55, 0x04,0x03,0x1e,0x06,0x00,0x22,0x00,0x31,0x00,0x22, }; -static const BYTE encodedMultipleAttrCN[] = { 0x30,0x0e,0x31,0x0c,0x30,0x0a, - 0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x31,0x2b,0x32 }; - -struct StrToNameA namesA[] = { +static const struct StrToNameA namesA[] = { { "CN=1", sizeof(encodedSimpleCN), encodedSimpleCN }, { "CN=\"1\"", sizeof(encodedSimpleCN), encodedSimpleCN }, { "CN = \"1\"", sizeof(encodedSimpleCN), encodedSimpleCN }, @@ -489,6 +760,12 @@ struct StrToNameA namesA[] = { { "CN=\" 1 \"", sizeof(encodedSpacedCN), encodedSpacedCN }, { "CN=\"\"\"1\"\"\"", sizeof(encodedQuotedCN), encodedQuotedCN }, { "CN=\"1+2\"", sizeof(encodedMultipleAttrCN), encodedMultipleAttrCN }, + { "CN=\"a,b\"", sizeof(encodedCommaCN), encodedCommaCN }, + { "CN=\"a=b\"", sizeof(encodedEqualCN), encodedEqualCN }, + { "CN=\"<\"", sizeof(encodedLessThanCN), encodedLessThanCN }, + { "CN=\">\"", sizeof(encodedGreaterThanCN), encodedGreaterThanCN }, + { "CN=\"#\"", sizeof(encodedHashCN), encodedHashCN }, + { "CN=\";\"", sizeof(encodedSemiCN), encodedSemiCN }, }; static void test_CertStrToNameA(void) @@ -526,8 +803,36 @@ static void test_CertStrToNameA(void) "Expected CRYPT_E_INVALID_X500_STRING, got %08x\n", GetLastError()); ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=1+2", 0, NULL, buf, &size, NULL); - todo_wine ok(!ret && GetLastError() == CRYPT_E_INVALID_X500_STRING, + ok(!ret && GetLastError() == CRYPT_E_INVALID_X500_STRING, "Expected CRYPT_E_INVALID_X500_STRING, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=1+2", CERT_NAME_STR_NO_PLUS_FLAG, NULL, buf, + &size, NULL); + ok(ret && GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=1,2", CERT_NAME_STR_NO_QUOTING_FLAG, NULL, buf, + &size, NULL); + ok(!ret && GetLastError() == CRYPT_E_INVALID_X500_STRING, + "Expected CRYPT_E_INVALID_X500_STRING, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=\"1,2;3,4\"", CERT_NAME_STR_NO_QUOTING_FLAG, NULL, buf, + &size, NULL); + ok(!ret && GetLastError() == CRYPT_E_INVALID_X500_STRING, + "Expected CRYPT_E_INVALID_X500_STRING, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=abc", 0, NULL, buf, + &size, NULL); + ok(ret && GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=abc", CERT_NAME_STR_NO_QUOTING_FLAG, NULL, buf, + &size, NULL); + ok(ret && GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=\"abc\"", 0, NULL, buf, + &size, NULL); + ok(ret && GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); + ret = pCertStrToNameA(X509_ASN_ENCODING, "CN=\"abc\"", CERT_NAME_STR_NO_QUOTING_FLAG, NULL, buf, + &size, NULL); + ok(!ret && GetLastError() == ERROR_MORE_DATA, + "Expected ERROR_MORE_DATA, got %08x\n", GetLastError()); for (i = 0; i < sizeof(namesA) / sizeof(namesA[0]); i++) { size = sizeof(buf); @@ -551,18 +856,13 @@ struct StrToNameW }; static const WCHAR badlyQuotedCN_W[] = { 'C','N','=','"','"','1','"','"',0 }; -static const WCHAR simpleCN_W[] = { 'C','N','=','1',0 }; static const WCHAR simpleCN2_W[] = { 'C','N','=','"','1','"',0 }; static const WCHAR simpleCN3_W[] = { 'C','N',' ','=',' ','"','1','"',0 }; -static const WCHAR singledQuotedCN_W[] = { 'C','N','=','\'','1','\'',0 }; -static const WCHAR spacedCN_W[] = { 'C','N','=','"',' ','1',' ','"',0 }; -static const WCHAR quotedCN_W[] = { 'C','N','=','"','"','"','1','"','"','"',0 }; -static const WCHAR multipleAttrCN_W[] = { 'C','N','=','"','1','+','2','"',0 }; static const WCHAR japaneseCN_W[] = { 'C','N','=',0x226f,0x575b,0 }; static const BYTE encodedJapaneseCN[] = { 0x30,0x0f,0x31,0x0d,0x30,0x0b,0x06, 0x03,0x55,0x04,0x03,0x1e,0x04,0x22,0x6f,0x57,0x5b }; -struct StrToNameW namesW[] = { +static const struct StrToNameW namesW[] = { { simpleCN_W, sizeof(encodedSimpleCN), encodedSimpleCN }, { simpleCN2_W, sizeof(encodedSimpleCN), encodedSimpleCN }, { simpleCN3_W, sizeof(encodedSimpleCN), encodedSimpleCN }, @@ -571,6 +871,12 @@ struct StrToNameW namesW[] = { { quotedCN_W, sizeof(encodedQuotedCN), encodedQuotedCN }, { multipleAttrCN_W, sizeof(encodedMultipleAttrCN), encodedMultipleAttrCN }, { japaneseCN_W, sizeof(encodedJapaneseCN), encodedJapaneseCN }, + { commaCN_W, sizeof(encodedCommaCN), encodedCommaCN }, + { equalCN_W, sizeof(encodedEqualCN), encodedEqualCN }, + { lessThanCN_W, sizeof(encodedLessThanCN), encodedLessThanCN }, + { greaterThanCN_W, sizeof(encodedGreaterThanCN), encodedGreaterThanCN }, + { hashCN_W, sizeof(encodedHashCN), encodedHashCN }, + { semiCN_W, sizeof(encodedSemiCN), encodedSemiCN }, }; static void test_CertStrToNameW(void) @@ -630,6 +936,162 @@ static void test_CertStrToNameW(void) } } +static void test_CertGetNameStringA(void) +{ + PCCERT_CONTEXT context; + + if (!pCertGetNameStringA) + { + win_skip("CertGetNameStringA is not available\n"); + return; + } + + context = CertCreateCertificateContext(X509_ASN_ENCODING, cert, + sizeof(cert)); + ok(context != NULL, "CertCreateCertificateContext failed: %08x\n", + GetLastError()); + if (context) + { + static const char aric[] = "aric@codeweavers.com"; + static const char localhost[] = "localhost"; + DWORD len, type; + LPSTR str; + + /* Bad string types/types missing from the cert */ + len = pCertGetNameStringA(NULL, 0, 0, NULL, NULL, 0); + ok(len == 1, "expected 1, got %d\n", len); + len = pCertGetNameStringA(context, 0, 0, NULL, NULL, 0); + ok(len == 1, "expected 1, got %d\n", len); + len = pCertGetNameStringA(context, CERT_NAME_URL_TYPE, 0, NULL, NULL, + 0); + ok(len == 1, "expected 1, got %d\n", len); + + len = pCertGetNameStringA(context, CERT_NAME_EMAIL_TYPE, 0, NULL, NULL, + 0); + ok(len == strlen(aric) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_EMAIL_TYPE, 0, NULL, + str, len); + ok(!strcmp(str, aric), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + + len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, NULL, NULL, + 0); + ok(len == strlen(issuerStr) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, NULL, + str, len); + ok(!strcmp(str, issuerStr), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + type = 0; + len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type, NULL, + 0); + ok(len == strlen(issuerStr) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type, + str, len); + ok(!strcmp(str, issuerStr), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + type = CERT_OID_NAME_STR; + len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type, NULL, + 0); + ok(len == strlen(subjectStr) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_RDN_TYPE, 0, &type, + str, len); + ok(!strcmp(str, subjectStr), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + + len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, NULL, NULL, + 0); + ok(len == strlen(aric) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, NULL, + str, len); + ok(!strcmp(str, aric), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, + (void *)szOID_RSA_emailAddr, NULL, 0); + ok(len == strlen(aric) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, + (void *)szOID_RSA_emailAddr, str, len); + ok(!strcmp(str, aric), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, + (void *)szOID_COMMON_NAME, NULL, 0); + ok(len == strlen(localhost) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_ATTR_TYPE, 0, + (void *)szOID_COMMON_NAME, str, len); + ok(!strcmp(str, localhost), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + + len = pCertGetNameStringA(context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, + NULL, NULL, 0); + ok(len == strlen(localhost) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_SIMPLE_DISPLAY_TYPE, + 0, NULL, str, len); + ok(!strcmp(str, localhost), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + + len = pCertGetNameStringA(context, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, + NULL, NULL, 0); + ok(len == strlen(localhost) + 1, "unexpected length %d\n", len); + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_FRIENDLY_DISPLAY_TYPE, + 0, NULL, str, len); + ok(!strcmp(str, localhost), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + + len = pCertGetNameStringA(context, CERT_NAME_DNS_TYPE, 0, NULL, NULL, + 0); + ok(len == strlen(localhost) + 1 || broken(len == 1) /* NT4 */, + "unexpected length %d\n", len); + if (len > 1) + { + str = HeapAlloc(GetProcessHeap(), 0, len); + if (str) + { + len = pCertGetNameStringA(context, CERT_NAME_DNS_TYPE, 0, NULL, + str, len); + ok(!strcmp(str, localhost), "unexpected value %s\n", str); + HeapFree(GetProcessHeap(), 0, str); + } + } + + CertFreeCertificateContext(context); + } +} + START_TEST(str) { dll = GetModuleHandleA("Crypt32.dll"); @@ -644,6 +1106,8 @@ START_TEST(str) "CryptDecodeObject"); pCertStrToNameA = (CertStrToNameAFunc)GetProcAddress(dll,"CertStrToNameA"); pCertStrToNameW = (CertStrToNameWFunc)GetProcAddress(dll,"CertStrToNameW"); + pCertGetNameStringA = (CertGetNameStringAFunc)GetProcAddress(dll, + "CertGetNameStringA"); test_CertRDNValueToStrA(); test_CertRDNValueToStrW(); @@ -651,4 +1115,5 @@ START_TEST(str) test_CertNameToStrW(); test_CertStrToNameA(); test_CertStrToNameW(); + test_CertGetNameStringA(); }