[CRYPT32_WINETEST]

* Sync to Wine 1.3.37.

svn path=/trunk/; revision=55109
This commit is contained in:
Amine Khaldi 2012-01-23 15:45:22 +00:00
parent 7f7460e8c4
commit 2b23e89568
13 changed files with 2735 additions and 722 deletions

View file

@ -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();

View file

@ -18,9 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
@ -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();

File diff suppressed because it is too large Load diff

View file

@ -18,9 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
@ -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);

View file

@ -18,9 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winerror.h>
@ -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)

File diff suppressed because it is too large Load diff

View file

@ -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.

View file

@ -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(&para, 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(&para, 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(&para, 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(&para, 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(&para, 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(&para, 0, signedWithCertWithPubKeyContent,
sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
ok(!ret, "Expected failure\n");
/* Apparently, an output pcbDecoded parameter is expected. */
ret = CryptVerifyMessageSignature(&para, 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(&para, 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(&para, 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(&para, 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(&para, 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(&para, FALSE, 2, NULL, NULL, NULL,
CryptHashMessage(&para, 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(&para, 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(&para, 0, sizeof(para));
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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(&para, 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(&para, 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(&para, TRUE, 0, NULL, NULL, NULL, &signedBlobSize);
ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
signedBlob = CryptMemAlloc(signedBlobSize);
if (signedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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(&para, FALSE, 0, NULL, NULL, NULL, &signedBlobSize);
ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
signedBlob = CryptMemAlloc(signedBlobSize);
if (signedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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(&para, TRUE, 2, toSign, signSize, NULL,
&signedBlobSize);
ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
signedBlob = CryptMemAlloc(signedBlobSize);
if (signedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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 = &para.pSigningCert;
SetLastError(0xdeadbeef);
signedBlobSize = 0;
ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, NULL,
&signedBlobSize);
ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
signedBlob = CryptMemAlloc(signedBlobSize);
if (signedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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(&para, TRUE, 2, toSign, signSize, NULL,
&signedBlobSize);
ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
signedBlob = CryptMemAlloc(signedBlobSize);
if (signedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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(&para, FALSE, 1, toSign, signSize, NULL,
&signedBlobSize);
ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
signedBlob = CryptMemAlloc(signedBlobSize);
if (signedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptSignMessage(&para, 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(&para, 0, sizeof(para));
SetLastError(0xdeadbeef);
encryptedBlobSize = 255;
ret = CryptEncryptMessage(&para, 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(&para, 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(&para, 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(&para, 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(&para, 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(&para, 2, certs, NULL, 0, NULL,
&encryptedBlobSize);
ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError());
if (ret)
{
encryptedBlob = CryptMemAlloc(encryptedBlobSize);
if (encryptedBlob)
{
SetLastError(0xdeadbeef);
ret = CryptEncryptMessage(&para, 2, certs, NULL, 0, encryptedBlob,
&encryptedBlobSize);
ok(ret, "CryptEncryptMessage failed: %08x\n", GetLastError());
CryptMemFree(encryptedBlob);
}
}
SetLastError(0xdeadbeef);
encryptedBlobSize = 0;
ret = CryptEncryptMessage(&para, 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(&para, 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(&para, 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(&para, 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();
}

View file

@ -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();

View file

@ -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");

View file

@ -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)

View file

@ -18,9 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
@ -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();

View file

@ -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();
}