sync crypt32 winetest with wine 1.1.33

svn path=/trunk/; revision=44185
This commit is contained in:
Christoph von Wittich 2009-11-15 23:04:51 +00:00
parent 86d5f9981c
commit 9cd4c81c17
9 changed files with 3251 additions and 373 deletions

View file

@ -1015,6 +1015,10 @@ static void testFindCert(void)
CERT_INFO certInfo = { 0 }; CERT_INFO certInfo = { 0 };
CRYPT_HASH_BLOB blob; CRYPT_HASH_BLOB blob;
BYTE otherSerialNumber[] = { 2 }; BYTE otherSerialNumber[] = { 2 };
DWORD count;
static const WCHAR juan[] = { 'j','u','a','n',0 };
static const WCHAR lang[] = { 'L','A','N','G',0 };
static const WCHAR malcolm[] = { 'm','a','l','c','o','l','m',0 };
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL); CERT_STORE_CREATE_NEW_FLAG, NULL);
@ -1085,7 +1089,7 @@ static void testFindCert(void)
* the issuer, not the subject * the issuer, not the subject
*/ */
context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL); CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
ok(context == NULL, "Expected no certificate\n"); ok(context == NULL, "Expected no certificate\n");
certInfo.Subject.pbData = NULL; certInfo.Subject.pbData = NULL;
certInfo.Subject.cbData = 0; certInfo.Subject.cbData = 0;
@ -1098,7 +1102,7 @@ static void testFindCert(void)
if (context) if (context)
{ {
context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context); CERT_FIND_SUBJECT_CERT, &certInfo, context);
ok(context == NULL, "Expected one cert only\n"); ok(context == NULL, "Expected one cert only\n");
} }
/* A non-matching serial number will not match. */ /* A non-matching serial number will not match. */
@ -1135,6 +1139,41 @@ static void testFindCert(void)
ok(context == NULL, "Expected one cert only\n"); ok(context == NULL, "Expected one cert only\n");
} }
/* Searching for NULL string matches any context. */
count = 0;
context = NULL;
do {
context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
CERT_FIND_ISSUER_STR, NULL, context);
if (context)
count++;
} while (context);
ok(count == 3, "expected 3 contexts\n");
count = 0;
context = NULL;
do {
context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
CERT_FIND_ISSUER_STR, juan, context);
if (context)
count++;
} while (context);
ok(count == 2, "expected 2 contexts\n");
count = 0;
context = NULL;
do {
context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
CERT_FIND_ISSUER_STR, lang, context);
if (context)
count++;
} while (context);
ok(count == 3, "expected 3 contexts\n");
SetLastError(0xdeadbeef);
context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
CERT_FIND_ISSUER_STR, malcolm, NULL);
ok(!context, "expected no certs\n");
ok(GetLastError() == CRYPT_E_NOT_FOUND,
"expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
CertCloseStore(store, 0); CertCloseStore(store, 0);
/* Another subject cert search, using iTunes's certs */ /* Another subject cert search, using iTunes's certs */
@ -1624,12 +1663,14 @@ static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
algoID.pszObjId = (LPSTR)sigOID; algoID.pszObjId = (LPSTR)sigOID;
ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData, ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
&algoID, NULL, NULL, &size); &algoID, NULL, NULL, &size);
ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID), ok(!ret &&
(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_ALGID),
"Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
GetLastError()); GetLastError());
ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData, ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
toBeSigned->cbData, &algoID, NULL, NULL, &size); toBeSigned->cbData, &algoID, NULL, NULL, &size);
ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID), ok(!ret &&
(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_ALGID),
"Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
GetLastError()); GetLastError());
@ -1851,7 +1892,10 @@ static void testSignAndEncodeCert(void)
algID.pszObjId = oid_rsa_md5rsa; algID.pszObjId = oid_rsa_md5rsa;
ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size); X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID), ok(!ret &&
(GetLastError() == ERROR_INVALID_PARAMETER ||
GetLastError() == NTE_BAD_ALGID ||
GetLastError() == OSS_BAD_PTR), /* Win9x */
"Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
GetLastError()); GetLastError());
algID.pszObjId = oid_rsa_md5; algID.pszObjId = oid_rsa_md5;
@ -2021,6 +2065,54 @@ static void testCreateSelfSignCert(void)
CRYPT_DELETEKEYSET); CRYPT_DELETEKEYSET);
} }
static void testIntendedKeyUsage(void)
{
BOOL ret;
CERT_INFO info = { 0 };
static char oid_key_usage[] = szOID_KEY_USAGE;
/* A couple "key usages". Really they're just encoded bits which aren't
* necessarily restricted to the defined key usage values.
*/
static BYTE usage1[] = { 0x03,0x03,0x00,0xff,0xff };
static BYTE usage2[] = { 0x03,0x03,0x01,0xff,0xfe };
static const BYTE expected_usage1[] = { 0xff,0xff,0x00,0x00 };
static const BYTE expected_usage2[] = { 0xff,0xfe,0x00,0x00 };
CERT_EXTENSION ext = { oid_key_usage, TRUE, { sizeof(usage1), usage1 } };
BYTE usage_bytes[4];
if (0)
{
/* Crash */
ret = CertGetIntendedKeyUsage(0, NULL, NULL, 0);
}
ret = CertGetIntendedKeyUsage(0, &info, NULL, 0);
ok(!ret, "expected failure\n");
ret = CertGetIntendedKeyUsage(0, &info, usage_bytes, sizeof(usage_bytes));
ok(!ret, "expected failure\n");
ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0);
ok(!ret, "expected failure\n");
ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes,
sizeof(usage_bytes));
info.cExtension = 1;
info.rgExtension = &ext;
ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0);
ok(!ret, "expected failure\n");
/* The unused bytes are filled with 0. */
ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes,
sizeof(usage_bytes));
ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError());
ok(!memcmp(usage_bytes, expected_usage1, sizeof(expected_usage1)),
"unexpected value\n");
/* The usage bytes are copied in big-endian order. */
ext.Value.cbData = sizeof(usage2);
ext.Value.pbData = usage2;
ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes,
sizeof(usage_bytes));
ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError());
ok(!memcmp(usage_bytes, expected_usage2, sizeof(expected_usage2)),
"unexpected value\n");
}
static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING, static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA }; szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
@ -3138,7 +3230,8 @@ static void testGetPublicKeyLength(void)
ret, GetLastError()); ret, GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
ok(ret == 56, "Expected length 56, got %d\n", ret); ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */,
"Expected length 56, got %d\n", ret);
/* An RSA key with the DH OID */ /* An RSA key with the DH OID */
info.Algorithm.pszObjId = oid_rsa_dh; info.Algorithm.pszObjId = oid_rsa_dh;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
@ -3152,12 +3245,14 @@ static void testGetPublicKeyLength(void)
info.Algorithm.pszObjId = oid_rsa_rsa; info.Algorithm.pszObjId = oid_rsa_rsa;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
ok(ret == 56, "Expected length 56, got %d\n", ret); ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */,
"Expected length 56, got %d\n", ret);
/* With the RSA OID and a message encoding */ /* With the RSA OID and a message encoding */
info.Algorithm.pszObjId = oid_rsa_rsa; info.Algorithm.pszObjId = oid_rsa_rsa;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info); ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info);
ok(ret == 56, "Expected length 56, got %d\n", ret); ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */,
"Expected length 56, got %d\n", ret);
} }
START_TEST(cert) START_TEST(cert)
@ -3175,6 +3270,7 @@ START_TEST(cert)
testCertSigs(); testCertSigs();
testSignAndEncodeCert(); testSignAndEncodeCert();
testCreateSelfSignCert(); testCreateSelfSignCert();
testIntendedKeyUsage();
testKeyUsage(); testKeyUsage();
testGetValidUsages(); testGetValidUsages();
testCompareCertName(); testCompareCertName();

File diff suppressed because it is too large Load diff

View file

@ -118,6 +118,21 @@ static void testCreateCRL(void)
CertFreeCRLContext(context); CertFreeCRLContext(context);
} }
static void testDupCRL(void)
{
PCCRL_CONTEXT context, dupContext;
context = CertDuplicateCRLContext(NULL);
ok(context == NULL, "expected NULL\n");
context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
sizeof(signedCRL));
dupContext = CertDuplicateCRLContext(context);
ok(dupContext != NULL, "expected a context\n");
ok(dupContext == context, "expected identical context addresses\n");
CertFreeCRLContext(dupContext);
CertFreeCRLContext(context);
}
static void testAddCRL(void) static void testAddCRL(void)
{ {
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
@ -722,6 +737,7 @@ START_TEST(crl)
init_function_pointers(); init_function_pointers();
testCreateCRL(); testCreateCRL();
testDupCRL();
testAddCRL(); testAddCRL();
testFindCRL(); testFindCRL();
testGetCRLFromStore(); testGetCRLFromStore();

View file

@ -187,6 +187,21 @@ static void testCreateCTL(void)
CertFreeCTLContext(ctl); CertFreeCTLContext(ctl);
} }
static void testDupCTL(void)
{
PCCTL_CONTEXT context, dupContext;
context = CertDuplicateCTLContext(NULL);
ok(context == NULL, "expected NULL\n");
context = CertCreateCTLContext(X509_ASN_ENCODING,
signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent));
dupContext = CertDuplicateCTLContext(context);
ok(dupContext != NULL, "expected a context\n");
ok(dupContext == context, "expected identical context addresses\n");
CertFreeCTLContext(dupContext);
CertFreeCTLContext(context);
}
static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID, static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
PCCTL_CONTEXT context, DWORD propID) PCCTL_CONTEXT context, DWORD propID)
{ {
@ -444,6 +459,7 @@ static void testAddCTLToStore(void)
START_TEST(ctl) START_TEST(ctl)
{ {
testCreateCTL(); testCreateCTL();
testDupCTL();
testCTLProperties(); testCTLProperties();
testAddCTLToStore(); testAddCTLToStore();
} }

View file

@ -1264,6 +1264,9 @@ static BYTE bmpCommonNameValue[] = {
0x61,0x00,0x6e,0x00,0x67,0x00,0x00 }; 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
static BYTE utf8CommonNameValue[] = { static BYTE utf8CommonNameValue[] = {
0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
static char embedded_null[] = "foo\0com";
static BYTE ia5EmbeddedNull[] = {
0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
static struct EncodedNameValue nameValues[] = { static struct EncodedNameValue nameValues[] = {
{ { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } }, { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
@ -1299,6 +1302,12 @@ static struct EncodedNameValue nameValues[] = {
{ { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } }, { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
bin44, sizeof(bin44) }, bin44, sizeof(bin44) },
}; };
/* This is kept separate, because the decoding doesn't return to the original
* value.
*/
static struct EncodedNameValue embeddedNullNameValue = {
{ CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } },
ia5EmbeddedNull, sizeof(ia5EmbeddedNull) };
static void test_encodeNameValue(DWORD dwEncoding) static void test_encodeNameValue(DWORD dwEncoding)
{ {
@ -1337,6 +1346,19 @@ static void test_encodeNameValue(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
&embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
"Type %d: CryptEncodeObjectEx failed: %08x\n",
embeddedNullNameValue.value.dwValueType, GetLastError());
if (ret)
{
ok(size == embeddedNullNameValue.encodedSize,
"Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size);
ok(!memcmp(buf, embeddedNullNameValue.encoded, size),
"Got unexpected encoding\n");
LocalFree(buf);
}
} }
static void test_decodeNameValue(DWORD dwEncoding) static void test_decodeNameValue(DWORD dwEncoding)
@ -1361,6 +1383,45 @@ static void test_decodeNameValue(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
&buf, &bufSize);
ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
embeddedNullNameValue.value.dwValueType, GetLastError());
if (ret)
{
CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
{ sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
{ sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
*expected = NULL;
/* Some Windows versions decode name values with embedded NULLs,
* others leave them encoded, even with the same version of crypt32.
* Accept either.
*/
ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
got->dwValueType == CERT_RDN_IA5_STRING,
"Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
got->dwValueType);
if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
expected = &rdnEncodedValue;
else if (got->dwValueType == CERT_RDN_IA5_STRING)
expected = &embeddedNullValue;
if (expected)
{
ok(got->Value.cbData == expected->Value.cbData,
"String type %d: unexpected data size, got %d, expected %d\n",
got->dwValueType, got->Value.cbData, expected->Value.cbData);
if (got->Value.cbData && got->Value.pbData)
ok(!memcmp(got->Value.pbData, expected->Value.pbData,
min(got->Value.cbData, expected->Value.cbData)),
"String type %d: unexpected value\n", expected->dwValueType);
}
LocalFree(buf);
}
} }
static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 }; static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
@ -1504,6 +1565,12 @@ static void test_decodeAltName(DWORD dwEncoding)
0x00, 0x00, 0x01 }; 0x00, 0x00, 0x01 };
static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00, static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
0x01 }; 0x01 };
static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
BOOL ret; BOOL ret;
BYTE *buf = NULL; BYTE *buf = NULL;
DWORD bufSize = 0; DWORD bufSize = 0;
@ -1642,6 +1709,40 @@ static void test_decodeAltName(DWORD dwEncoding)
"Unexpected directory name value\n"); "Unexpected directory name value\n");
LocalFree(buf); LocalFree(buf);
} }
ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
NULL, &buf, &bufSize);
/* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
* particular failure, just that it doesn't decode.
* It succeeds on (broken) Windows versions that haven't addressed
* embedded NULLs in alternate names.
*/
ok(!ret || broken(ret), "expected failure\n");
/* An embedded bell character is allowed, however. */
ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
NULL, &buf, &bufSize);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
info = (CERT_ALT_NAME_INFO *)buf;
ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
info->cAltEntry);
ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
"Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
info->rgAltEntry[0].dwAltNameChoice);
LocalFree(buf);
}
ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
NULL, &buf, &bufSize);
/* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
* about the particular failure, just that it doesn't decode.
* It succeeds on (broken) Windows versions that haven't addressed
* embedded NULLs in alternate names.
*/
ok(!ret || broken(ret), "expected failure\n");
} }
struct UnicodeExpectedError struct UnicodeExpectedError
@ -2613,8 +2714,8 @@ static void test_decodeExtensions(DWORD dwEncoding)
/* MS encodes public key info with a NULL if the algorithm identifier's /* MS encodes public key info with a NULL if the algorithm identifier's
* parameters are empty. However, when encoding an algorithm in a CERT_INFO, * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
* it encodes them by omitting the algorithm parameters. This latter approach * it encodes them by omitting the algorithm parameters. It accepts either
* seems more correct, so accept either form. * form for decoding.
*/ */
struct encodedPublicKey struct encodedPublicKey
{ {
@ -2692,16 +2793,11 @@ static void test_encodePublicKeyInfo(DWORD dwEncoding)
"CryptEncodeObjectEx failed: %08x\n", GetLastError()); "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf) if (buf)
{ {
ok(bufSize == pubKeys[i].encoded[1] + 2 || ok(bufSize == pubKeys[i].encoded[1] + 2,
bufSize == pubKeys[i].encodedNoNull[1] + 2, "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
"Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
pubKeys[i].encodedNoNull[1] + 2, bufSize);
if (bufSize == pubKeys[i].encoded[1] + 2) if (bufSize == pubKeys[i].encoded[1] + 2)
ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2), ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
"Unexpected value\n"); "Unexpected value\n");
else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
ok(!memcmp(buf, pubKeys[i].encodedNoNull,
pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
LocalFree(buf); LocalFree(buf);
} }
} }
@ -2789,6 +2885,11 @@ static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 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, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
static const BYTE v4Cert[] = {
0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,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,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30, static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x02, 0x06, 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, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
@ -2846,6 +2947,35 @@ static const BYTE v1CertWithSubjectKeyId[] = {
0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30, 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20, 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
0x4c,0x61,0x6e,0x67,0x00 }; 0x4c,0x61,0x6e,0x67,0x00 };
static const BYTE v1CertWithIssuerUniqueId[] = {
0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,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,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
0x30,0x81,0x99,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,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,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 };
static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
0x30,0x81,0x97,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,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,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 };
static const BYTE serialNum[] = { 0x01 }; static const BYTE serialNum[] = { 0x01 };
@ -2903,6 +3033,16 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n"); ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
LocalFree(buf); LocalFree(buf);
} }
/* A v4 cert? */
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)
{
ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
LocalFree(buf);
}
/* see if a V1 cert can have basic constraints set (RFC3280 says no, but /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
* API doesn't prevent it) * API doesn't prevent it)
*/ */
@ -2930,7 +3070,27 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n"); ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
LocalFree(buf); LocalFree(buf);
} }
/* Test v1 cert with an issuer name, serial number, and issuer unique id */
info.dwVersion = CERT_V1;
info.cExtension = 0;
info.IssuerUniqueId.cbData = sizeof(serialNum);
info.IssuerUniqueId.pbData = (BYTE *)serialNum;
ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */),
"CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
"Got unexpected value\n");
LocalFree(buf);
}
/* Test v1 cert with an issuer name, a subject name, and a serial number */ /* Test v1 cert with an issuer name, a subject name, and a serial number */
info.IssuerUniqueId.cbData = 0;
info.IssuerUniqueId.pbData = NULL;
info.cExtension = 1;
info.rgExtension = &criticalExt;
info.Issuer.cbData = sizeof(encodedCommonName); info.Issuer.cbData = sizeof(encodedCommonName);
info.Issuer.pbData = (BYTE *)encodedCommonName; info.Issuer.pbData = (BYTE *)encodedCommonName;
info.Subject.cbData = sizeof(encodedCommonName); info.Subject.cbData = sizeof(encodedCommonName);
@ -2960,7 +3120,30 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
"Got unexpected value\n"); "Got unexpected value\n");
LocalFree(buf); LocalFree(buf);
} }
/* Again add an issuer unique id */
info.IssuerUniqueId.cbData = sizeof(serialNum);
info.IssuerUniqueId.pbData = (BYTE *)serialNum;
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)
{
ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
"Wrong size %d\n", size);
if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
size), "unexpected value\n");
else if (size ==
sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
ok(!memcmp(buf,
v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
"unexpected value\n");
LocalFree(buf);
}
/* Remove the public key, and add a subject key identifier extension */ /* Remove the public key, and add a subject key identifier extension */
info.IssuerUniqueId.cbData = 0;
info.IssuerUniqueId.pbData = NULL;
info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL; info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
info.SubjectPublicKeyInfo.PublicKey.cbData = 0; info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
info.SubjectPublicKeyInfo.PublicKey.pbData = NULL; info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
@ -2982,8 +3165,8 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
static void test_decodeCertToBeSigned(DWORD dwEncoding) static void test_decodeCertToBeSigned(DWORD dwEncoding)
{ {
static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
v1CertWithConstraints, v1CertWithSerial }; v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
BOOL ret; BOOL ret;
BYTE *buf = NULL; BYTE *buf = NULL;
DWORD size = 0, i; DWORD size = 0, i;
@ -3002,9 +3185,9 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding)
ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
"Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
} }
/* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
* minimum a cert must have a non-zero serial number, an issuer, and a * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
* subject. * serial number, an issuer, a subject, and a public key.
*/ */
for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++) for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
{ {
@ -3013,6 +3196,45 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding)
&buf, &size); &buf, &size);
ok(!ret, "Expected failure\n"); ok(!ret, "Expected failure\n");
} }
/* The following succeeds, even though v1 certs are not allowed to have
* extensions.
*/
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
CERT_INFO *info = (CERT_INFO *)buf;
ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
info->dwVersion);
ok(info->cExtension == 1, "expected 1 extension, got %d\n",
info->cExtension);
LocalFree(buf);
}
/* The following also succeeds, even though V1 certs are not allowed to
* have issuer unique ids.
*/
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
CERT_INFO *info = (CERT_INFO *)buf;
ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
info->dwVersion);
ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
"unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
"unexpected issuer unique id value\n");
LocalFree(buf);
}
/* Now check with serial number, subject and issuer specified */ /* Now check with serial number, subject and issuer specified */
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert, ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
@ -5520,7 +5742,10 @@ static void test_decodeCTL(DWORD dwEncoding)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry, ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT), ok(!ret &&
(GetLastError() == CRYPT_E_ASN1_EOD ||
GetLastError() == CRYPT_E_ASN1_CORRUPT ||
GetLastError() == OSS_MORE_INPUT), /* Win9x */
"expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n", "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
GetLastError()); GetLastError());
info.SubjectAlgorithm.Parameters.cbData = 0; info.SubjectAlgorithm.Parameters.cbData = 0;
@ -7302,6 +7527,305 @@ static void test_decodeCertPolicies(DWORD dwEncoding)
} }
} }
static const BYTE policyMappingWithOneMapping[] = {
0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
static const BYTE policyMappingWithTwoMappings[] = {
0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
static void test_encodeCertPolicyMappings(DWORD dwEncoding)
{
static char oid2[] = "2.3.4";
static char oid3[] = "1.3.4";
static char oid4[] = "2.5.6";
BOOL ret;
CERT_POLICY_MAPPINGS_INFO info = { 0 };
CERT_POLICY_MAPPING mapping[2];
LPBYTE buf;
DWORD size, i;
/* Each of the mapping OIDs is equivalent, so check with all of them */
for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
{
memset(&info, 0, sizeof(info));
ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
"CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
{
win_skip("no policy mappings support\n");
return;
}
if (ret)
{
ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
"unexpected value\n");
LocalFree(buf);
}
mapping[0].pszIssuerDomainPolicy = NULL;
mapping[0].pszSubjectDomainPolicy = NULL;
info.cPolicyMapping = 1;
info.rgPolicyMapping = mapping;
SetLastError(0xdeadbeef);
ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
mapping[0].pszIssuerDomainPolicy = oid1;
mapping[0].pszSubjectDomainPolicy = oid2;
ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(size == sizeof(policyMappingWithOneMapping),
"unexpected size %d\n", size);
ok(!memcmp(buf, policyMappingWithOneMapping, size),
"unexpected value\n");
LocalFree(buf);
}
mapping[1].pszIssuerDomainPolicy = oid3;
mapping[1].pszSubjectDomainPolicy = oid4;
info.cPolicyMapping = 2;
ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(size == sizeof(policyMappingWithTwoMappings),
"unexpected size %d\n", size);
ok(!memcmp(buf, policyMappingWithTwoMappings, size),
"unexpected value\n");
LocalFree(buf);
}
}
}
static void test_decodeCertPolicyMappings(DWORD dwEncoding)
{
DWORD size, i;
CERT_POLICY_MAPPINGS_INFO *info;
BOOL ret;
/* Each of the mapping OIDs is equivalent, so check with all of them */
for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
&info, &size);
ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
"CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
{
win_skip("no policy mappings support\n");
return;
}
if (ret)
{
ok(info->cPolicyMapping == 0,
"expected 0 policy mappings, got %d\n", info->cPolicyMapping);
LocalFree(info);
}
ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(info->cPolicyMapping == 1,
"expected 1 policy mappings, got %d\n", info->cPolicyMapping);
ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
"unexpected issuer policy %s\n",
info->rgPolicyMapping[0].pszIssuerDomainPolicy);
ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
"2.3.4"), "unexpected subject policy %s\n",
info->rgPolicyMapping[0].pszSubjectDomainPolicy);
LocalFree(info);
}
ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(info->cPolicyMapping == 2,
"expected 2 policy mappings, got %d\n", info->cPolicyMapping);
ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
"unexpected issuer policy %s\n",
info->rgPolicyMapping[0].pszIssuerDomainPolicy);
ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
"2.3.4"), "unexpected subject policy %s\n",
info->rgPolicyMapping[0].pszSubjectDomainPolicy);
ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
"unexpected issuer policy %s\n",
info->rgPolicyMapping[1].pszIssuerDomainPolicy);
ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
"2.5.6"), "unexpected subject policy %s\n",
info->rgPolicyMapping[1].pszSubjectDomainPolicy);
LocalFree(info);
}
}
}
static const BYTE policyConstraintsWithRequireExplicit[] = {
0x30,0x03,0x80,0x01,0x00 };
static const BYTE policyConstraintsWithInhibitMapping[] = {
0x30,0x03,0x81,0x01,0x01 };
static const BYTE policyConstraintsWithBoth[] = {
0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
{
CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
LPBYTE buf;
DWORD size;
BOOL ret;
/* Even though RFC 5280 explicitly states CAs must not issue empty
* policy constraints (section 4.2.1.11), the API doesn't prevent it.
*/
ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
"CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
{
win_skip("no policy constraints support\n");
return;
}
if (ret)
{
ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
"unexpected value\n");
LocalFree(buf);
}
/* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
* is not, then a skip of 0 is encoded.
*/
info.fRequireExplicitPolicy = TRUE;
ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(size == sizeof(policyConstraintsWithRequireExplicit),
"unexpected size %d\n", size);
ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
LocalFree(buf);
}
/* With inhibit policy mapping */
info.fRequireExplicitPolicy = FALSE;
info.dwRequireExplicitPolicySkipCerts = 0;
info.fInhibitPolicyMapping = TRUE;
info.dwInhibitPolicyMappingSkipCerts = 1;
ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(size == sizeof(policyConstraintsWithInhibitMapping),
"unexpected size %d\n", size);
ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
LocalFree(buf);
}
/* And with both */
info.fRequireExplicitPolicy = TRUE;
info.dwRequireExplicitPolicySkipCerts = 1;
ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
size);
ok(!memcmp(buf, policyConstraintsWithBoth,
sizeof(policyConstraintsWithBoth)), "unexpected value\n");
LocalFree(buf);
}
}
static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
{
CERT_POLICY_CONSTRAINTS_INFO *info;
DWORD size;
BOOL ret;
/* Again, even though CAs must not issue such constraints, they can be
* decoded.
*/
ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
&info, &size);
ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
"CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
{
win_skip("no policy mappings support\n");
return;
}
if (ret)
{
ok(!info->fRequireExplicitPolicy,
"expected require explicit = FALSE\n");
ok(!info->fInhibitPolicyMapping,
"expected implicit mapping = FALSE\n");
LocalFree(info);
}
ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
policyConstraintsWithRequireExplicit,
sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
NULL, &info, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(info->fRequireExplicitPolicy,
"expected require explicit = TRUE\n");
ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
info->dwRequireExplicitPolicySkipCerts);
ok(!info->fInhibitPolicyMapping,
"expected implicit mapping = FALSE\n");
LocalFree(info);
}
ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
policyConstraintsWithInhibitMapping,
sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
NULL, &info, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(!info->fRequireExplicitPolicy,
"expected require explicit = FALSE\n");
ok(info->fInhibitPolicyMapping,
"expected implicit mapping = TRUE\n");
ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
info->dwInhibitPolicyMappingSkipCerts);
LocalFree(info);
}
ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
ok(info->fRequireExplicitPolicy,
"expected require explicit = TRUE\n");
ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
info->dwRequireExplicitPolicySkipCerts);
ok(info->fInhibitPolicyMapping,
"expected implicit mapping = TRUE\n");
ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
info->dwInhibitPolicyMappingSkipCerts);
LocalFree(info);
}
}
/* Free *pInfo with HeapFree */ /* Free *pInfo with HeapFree */
static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo) static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
{ {
@ -7572,6 +8096,10 @@ START_TEST(encode)
test_decodePolicyQualifierUserNotice(encodings[i]); test_decodePolicyQualifierUserNotice(encodings[i]);
test_encodeCertPolicies(encodings[i]); test_encodeCertPolicies(encodings[i]);
test_decodeCertPolicies(encodings[i]); test_decodeCertPolicies(encodings[i]);
test_encodeCertPolicyMappings(encodings[i]);
test_decodeCertPolicyMappings(encodings[i]);
test_encodeCertPolicyConstraints(encodings[i]);
test_decodeCertPolicyConstraints(encodings[i]);
} }
testPortPublicKeyInfo(); testPortPublicKeyInfo();
} }

View file

@ -98,16 +98,8 @@ static void testOIDToAlgID(void)
DWORD alg; DWORD alg;
/* Test with a bogus one */ /* Test with a bogus one */
SetLastError(0xdeadbeef);
alg = CertOIDToAlgId("1.2.3"); alg = CertOIDToAlgId("1.2.3");
ok(!alg, "Expected failure, got %d\n", alg); ok(!alg, "Expected failure, got %d\n", alg);
ok(GetLastError() == 0xdeadbeef ||
GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND ||
GetLastError() == ERROR_INVALID_PARAMETER || /* Vista */
GetLastError() == ERROR_SUCCESS || /* win2k */
GetLastError() == ERROR_FILE_INVALID, /* another Vista */
"Expected ERROR_RESOURCE_NAME_NOT_FOUND, ERROR_INVALID_PARAMETER, "
"ERROR_SUCCESS or no error set, got %08x\n", GetLastError());
for (i = 0; i < sizeof(oidToAlgID) / sizeof(oidToAlgID[0]); i++) for (i = 0; i < sizeof(oidToAlgID) / sizeof(oidToAlgID[0]); i++)
{ {

View file

@ -213,6 +213,40 @@ static void test_cryptunprotectdata(void)
plain.cbData=0; plain.cbData=0;
} }
static void test_simpleroundtrip(const char *plaintext, int wine_fails)
{
DATA_BLOB input;
DATA_BLOB encrypted;
DATA_BLOB output;
int res;
WCHAR emptyW[1];
emptyW[0] = 0;
input.pbData = (unsigned char *)plaintext;
input.cbData = strlen(plaintext);
res = pCryptProtectData(&input, emptyW, NULL, NULL, NULL, 0, &encrypted);
ok(res != 0 || broken(!res), "can't protect\n");
if (!res)
{
/* Fails on Win9x, NT4 */
win_skip("CryptProtectData failed\n");
return;
}
res = pCryptUnprotectData(&encrypted, NULL, NULL, NULL, NULL, 0, &output);
if (wine_fails) {
todo_wine
ok(res != 0, "can't unprotect; last error %u\n", GetLastError());
} else {
ok(res != 0, "can't unprotect; last error %u\n", GetLastError());
}
if (res) {
ok(output.cbData == strlen(plaintext), "output wrong length %d for input '%s', wanted %d\n", output.cbData, plaintext, strlen(plaintext));
ok(!memcmp(plaintext, (char *)output.pbData, output.cbData), "output wrong contents for input '%s'\n", plaintext);
}
}
START_TEST(protectdata) START_TEST(protectdata)
{ {
HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll"); HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
@ -228,6 +262,8 @@ START_TEST(protectdata)
protected=FALSE; protected=FALSE;
test_cryptprotectdata(); test_cryptprotectdata();
test_cryptunprotectdata(); test_cryptunprotectdata();
test_simpleroundtrip("", 1);
test_simpleroundtrip("hello", 0);
/* deinit globals here */ /* deinit globals here */
if (cipher.pbData) LocalFree(cipher.pbData); if (cipher.pbData) LocalFree(cipher.pbData);

View file

@ -181,8 +181,10 @@ static void test_SIPRetrieveSubjectGUID(void)
memset(&subject, 1, sizeof(GUID)); memset(&subject, 1, sizeof(GUID));
ret = CryptSIPRetrieveSubjectGuid(deadbeef, NULL, &subject); ret = CryptSIPRetrieveSubjectGuid(deadbeef, NULL, &subject);
ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n");
ok (GetLastError() == ERROR_FILE_NOT_FOUND, ok (GetLastError() == ERROR_FILE_NOT_FOUND ||
"Expected ERROR_FILE_NOT_FOUND, got %d.\n", GetLastError()); GetLastError() == ERROR_PATH_NOT_FOUND,
"Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d.\n",
GetLastError());
ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
"Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject, guid1)); "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject, guid1));

View file

@ -277,11 +277,53 @@ static void testMemStore(void)
CertCloseStore(store1, 0); CertCloseStore(store1, 0);
} }
static void compareFile(LPCWSTR filename, const BYTE *pb, DWORD cb)
{
HANDLE h;
BYTE buf[200];
BOOL ret;
DWORD cbRead = 0, totalRead = 0;
h = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return;
do {
ret = ReadFile(h, buf, sizeof(buf), &cbRead, NULL);
if (ret && cbRead)
{
ok(totalRead + cbRead <= cb, "Expected total count %d, see %d\n",
cb, totalRead + cbRead);
ok(!memcmp(pb + totalRead, buf, cbRead),
"Unexpected data in file\n");
totalRead += cbRead;
}
} while (ret && cbRead);
CloseHandle(h);
}
static const BYTE serializedStoreWithCert[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,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,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,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00 };
static void testCollectionStore(void) static void testCollectionStore(void)
{ {
HCERTSTORE store1, store2, collection, collection2; HCERTSTORE store1, store2, collection, collection2;
PCCERT_CONTEXT context; PCCERT_CONTEXT context;
BOOL ret; BOOL ret;
static const WCHAR szPrefix[] = { 'c','e','r',0 };
static const WCHAR szDot[] = { '.',0 };
WCHAR filename[MAX_PATH];
HANDLE file;
if (!pCertAddStoreToCollection) if (!pCertAddStoreToCollection)
{ {
@ -573,6 +615,86 @@ static void testCollectionStore(void)
CertCloseStore(collection, 0); CertCloseStore(collection, 0);
CertCloseStore(store2, 0); CertCloseStore(store2, 0);
CertCloseStore(store1, 0); CertCloseStore(store1, 0);
/* Test adding certificates to and deleting certificates from collections.
*/
store1 = CertOpenSystemStoreA(0, "My");
collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
CertDeleteCertificateFromStore(context);
CertAddStoreToCollection(collection, store1,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
CertDeleteCertificateFromStore(context);
CertCloseStore(collection, 0);
CertCloseStore(store1, 0);
/* Test whether a collection store can be committed */
if (!pCertControlStore)
{
win_skip("CertControlStore() is not available\n");
return;
}
collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
SetLastError(0xdeadbeef);
ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(ret, "CertControlStore failed: %08x\n", GetLastError());
/* Adding a mem store that can't be committed prevents a successful commit.
*/
store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
pCertAddStoreToCollection(collection, store1, 0, 0);
SetLastError(0xdeadbeef);
ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
"expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError());
pCertRemoveStoreFromCollection(collection, store1);
CertCloseStore(store1, 0);
/* Test adding a cert to a collection with a file store, committing the
* change to the collection, and comparing the resulting file.
*/
if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
return;
DeleteFileW(filename);
file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
pCertAddStoreToCollection(collection, store1,
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
CertCloseStore(store1, 0);
ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
GetLastError());
ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(ret, "CertControlStore failed: %d\n", ret);
CertCloseStore(collection, 0);
compareFile(filename, serializedStoreWithCert,
sizeof(serializedStoreWithCert));
DeleteFileW(filename);
} }
/* Looks for the property with ID propID in the buffer buf. Returns a pointer /* Looks for the property with ID propID in the buffer buf. Returns a pointer
@ -1046,18 +1168,6 @@ static void testSystemStore(void)
RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
} }
static const BYTE serializedStoreWithCert[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,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,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,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00 };
static const BYTE serializedStoreWithCertAndCRL[] = { static const BYTE serializedStoreWithCertAndCRL[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
@ -1076,31 +1186,6 @@ static const BYTE serializedStoreWithCertAndCRL[] = {
0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02, 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static void compareFile(LPCWSTR filename, const BYTE *pb, DWORD cb)
{
HANDLE h;
BYTE buf[200];
BOOL ret;
DWORD cbRead = 0, totalRead = 0;
h = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return;
do {
ret = ReadFile(h, buf, sizeof(buf), &cbRead, NULL);
if (ret && cbRead)
{
ok(totalRead + cbRead <= cb, "Expected total count %d, see %d\n",
cb, totalRead + cbRead);
ok(!memcmp(pb + totalRead, buf, cbRead),
"Unexpected data in file\n");
totalRead += cbRead;
}
} while (ret && cbRead);
CloseHandle(h);
}
static void testFileStore(void) static void testFileStore(void)
{ {
static const WCHAR szPrefix[] = { 'c','e','r',0 }; static const WCHAR szPrefix[] = { 'c','e','r',0 };
@ -2074,7 +2159,6 @@ static void test_I_UpdateStore(void)
certs = countCertsInStore(store1); certs = countCertsInStore(store1);
ok(certs == 0, "Expected 0 certs, got %d\n", certs); ok(certs == 0, "Expected 0 certs, got %d\n", certs);
CertFreeCertificateContext(cert);
CertCloseStore(store1, 0); CertCloseStore(store1, 0);
CertCloseStore(store2, 0); CertCloseStore(store2, 0);
} }