crypt32: Add more tests of cert encoding/decoding.

This commit is contained in:
Juan Lang 2009-11-06 11:19:55 -08:00 committed by Alexandre Julliard
parent bcfa7c57d6
commit acfa433f15
1 changed files with 135 additions and 5 deletions

View File

@ -2784,6 +2784,11 @@ static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
static const BYTE v4Cert[] = {
0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
@ -2841,6 +2846,35 @@ static const BYTE v1CertWithSubjectKeyId[] = {
0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
0x4c,0x61,0x6e,0x67,0x00 };
static const BYTE v1CertWithIssuerUniqueId[] = {
0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
0x01,0x01,0xff,0x02,0x01,0x01 };
static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
0xff,0x02,0x01,0x01 };
static const BYTE serialNum[] = { 0x01 };
@ -2898,6 +2932,16 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
LocalFree(buf);
}
/* A v4 cert? */
info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
if (buf)
{
ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
LocalFree(buf);
}
/* see if a V1 cert can have basic constraints set (RFC3280 says no, but
* API doesn't prevent it)
*/
@ -2925,7 +2969,28 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
LocalFree(buf);
}
/* Test v1 cert with an issuer name, serial number, and issuer unique id */
info.dwVersion = CERT_V1;
info.cExtension = 0;
info.IssuerUniqueId.cbData = sizeof(serialNum);
info.IssuerUniqueId.pbData = (BYTE *)serialNum;
ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
todo_wine {
ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
"Got unexpected value\n");
}
LocalFree(buf);
}
/* Test v1 cert with an issuer name, a subject name, and a serial number */
info.IssuerUniqueId.cbData = 0;
info.IssuerUniqueId.pbData = NULL;
info.cExtension = 1;
info.rgExtension = &criticalExt;
info.Issuer.cbData = sizeof(encodedCommonName);
info.Issuer.pbData = (BYTE *)encodedCommonName;
info.Subject.cbData = sizeof(encodedCommonName);
@ -2955,7 +3020,32 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
"Got unexpected value\n");
LocalFree(buf);
}
/* Again add an issuer unique id */
info.IssuerUniqueId.cbData = sizeof(serialNum);
info.IssuerUniqueId.pbData = (BYTE *)serialNum;
ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (buf)
{
ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
"Wrong size %d\n", size);
todo_wine {
if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
size), "unexpected value\n");
else if (size ==
sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
ok(!memcmp(buf,
v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
"unexpected value\n");
}
LocalFree(buf);
}
/* Remove the public key, and add a subject key identifier extension */
info.IssuerUniqueId.cbData = 0;
info.IssuerUniqueId.pbData = NULL;
info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
@ -2977,8 +3067,8 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding)
static void test_decodeCertToBeSigned(DWORD dwEncoding)
{
static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
v1CertWithConstraints, v1CertWithSerial };
static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
BOOL ret;
BYTE *buf = NULL;
DWORD size = 0, i;
@ -2997,9 +3087,9 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding)
ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
"Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
}
/* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
* minimum a cert must have a non-zero serial number, an issuer, and a
* subject.
/* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
* CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
* serial number, an issuer, a subject, and a public key.
*/
for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
{
@ -3008,6 +3098,46 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding)
&buf, &size);
ok(!ret, "Expected failure\n");
}
/* The following succeeds, even though v1 certs are not allowed to have
* extensions.
*/
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
CERT_INFO *info = (CERT_INFO *)buf;
ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
info->dwVersion);
ok(info->cExtension == 1, "expected 1 extension, got %d\n",
info->cExtension);
LocalFree(buf);
}
/* The following also succeeds, even though V1 certs are not allowed to
* have issuer unique ids.
*/
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
todo_wine
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
CERT_INFO *info = (CERT_INFO *)buf;
ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
info->dwVersion);
ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
"unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
"unexpected issuer unique id value\n");
LocalFree(buf);
}
/* Now check with serial number, subject and issuer specified */
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);