Commit 13766712 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

Encode/decode certs, with tests.

parent 11ad6a0a
...@@ -100,6 +100,9 @@ static BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType, ...@@ -100,6 +100,9 @@ static BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType,
static BOOL WINAPI CRYPT_AsnEncodeBits(DWORD dwCertEncodingType, static BOOL WINAPI CRYPT_AsnEncodeBits(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodeBitsSwapBytes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
static BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType, static BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
...@@ -732,6 +735,37 @@ static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType, ...@@ -732,6 +735,37 @@ static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType,
return ret; return ret;
} }
static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CERT_SIGNED_CONTENT_INFO *info =
(const CERT_SIGNED_CONTENT_INFO *)pvStructInfo;
struct AsnEncodeSequenceItem items[] = {
{ &info->ToBeSigned, CRYPT_CopyEncodedBlob, 0 },
{ &info->SignatureAlgorithm, CRYPT_AsnEncodeAlgorithmId, 0 },
{ &info->Signature, CRYPT_AsnEncodeBitsSwapBytes, 0 },
};
if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].encodeFunc = CRYPT_AsnEncodeBits;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT(page_fault)
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
/* Like in Windows, this blithely ignores the validity of the passed-in /* Like in Windows, this blithely ignores the validity of the passed-in
* CERT_INFO, and just encodes it as-is. The resulting encoded data may not * CERT_INFO, and just encodes it as-is. The resulting encoded data may not
* decode properly, see CRYPT_AsnDecodeCertInfo. * decode properly, see CRYPT_AsnDecodeCertInfo.
...@@ -1447,6 +1481,45 @@ static BOOL WINAPI CRYPT_AsnEncodeBits(DWORD dwCertEncodingType, ...@@ -1447,6 +1481,45 @@ static BOOL WINAPI CRYPT_AsnEncodeBits(DWORD dwCertEncodingType,
return ret; return ret;
} }
static BOOL WINAPI CRYPT_AsnEncodeBitsSwapBytes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret;
__TRY
{
const CRYPT_BIT_BLOB *blob = (const CRYPT_BIT_BLOB *)pvStructInfo;
CRYPT_BIT_BLOB newBlob = { blob->cbData, NULL, blob->cUnusedBits };
ret = TRUE;
if (newBlob.cbData)
{
newBlob.pbData = HeapAlloc(GetProcessHeap(), 0, newBlob.cbData);
if (newBlob.pbData)
{
DWORD i;
for (i = 0; i < newBlob.cbData; i++)
newBlob.pbData[newBlob.cbData - i - 1] = blob->pbData[i];
}
else
ret = FALSE;
}
if (ret)
ret = CRYPT_AsnEncodeBits(dwCertEncodingType, lpszStructType,
&newBlob, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
HeapFree(GetProcessHeap(), 0, newBlob.pbData);
}
__EXCEPT(page_fault)
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType, static BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
...@@ -1856,6 +1929,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, ...@@ -1856,6 +1929,9 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
{ {
switch (LOWORD(lpszStructType)) switch (LOWORD(lpszStructType))
{ {
case (WORD)X509_CERT:
encodeFunc = CRYPT_AsnEncodeCert;
break;
case (WORD)X509_CERT_TO_BE_SIGNED: case (WORD)X509_CERT_TO_BE_SIGNED:
encodeFunc = CRYPT_AsnEncodeCertInfo; encodeFunc = CRYPT_AsnEncodeCertInfo;
break; break;
...@@ -2129,10 +2205,11 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType, ...@@ -2129,10 +2205,11 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType,
&items[i].size); &items[i].size);
if (ret) if (ret)
{ {
/* FIXME: need to ensure alignment for sizes greater /* Account for alignment padding */
* than the minimum size
*/
bytesNeeded += items[i].size; bytesNeeded += items[i].size;
if (items[i].size % sizeof(DWORD))
bytesNeeded += sizeof(DWORD) -
items[i].size % sizeof(DWORD);
ptr += 1 + nextItemLenBytes + nextItemLen; ptr += 1 + nextItemLenBytes + nextItemLen;
} }
else if (items[i].optional && else if (items[i].optional &&
...@@ -2187,8 +2264,14 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType, ...@@ -2187,8 +2264,14 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType,
{ {
if (items[i].hasPointer && if (items[i].hasPointer &&
items[i].size > items[i].minSize) items[i].size > items[i].minSize)
{
nextData += items[i].size - nextData += items[i].size -
items[i].minSize; items[i].minSize;
/* align nextData to DWORD boundaries */
if (items[i].size % sizeof(DWORD))
nextData += sizeof(DWORD) -
items[i].size % sizeof(DWORD);
}
ptr += 1 + nextItemLenBytes + nextItemLen; ptr += 1 + nextItemLenBytes + nextItemLen;
} }
else if (items[i].optional && else if (items[i].optional &&
...@@ -2216,33 +2299,6 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType, ...@@ -2216,33 +2299,6 @@ static BOOL CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType,
return ret; return ret;
} }
static BOOL WINAPI CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR))
{
DWORD dataLen;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
ret = CRYPT_AsnDecodeInt(dwCertEncodingType, X509_INTEGER,
pbEncoded + 1 + lenBytes, dataLen, dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo);
}
}
else
{
SetLastError(CRYPT_E_ASN1_BADTAG);
ret = FALSE;
}
return ret;
}
/* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
* pvStructInfo. The BLOB must be non-empty, otherwise the last error is set * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
* to CRYPT_E_ASN1_CORRUPT. * to CRYPT_E_ASN1_CORRUPT.
...@@ -2292,6 +2348,94 @@ static BOOL WINAPI CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType, ...@@ -2292,6 +2348,94 @@ static BOOL WINAPI CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType,
return ret; return ret;
} }
/* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
static BOOL WINAPI CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
ret = CRYPT_AsnDecodeBitsInternal(dwCertEncodingType, lpszStructType,
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
if (ret && pvStructInfo)
{
CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
DWORD i;
BYTE temp;
for (i = 0; i < blob->cbData / 2; i++)
{
temp = blob->pbData[i];
blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
blob->pbData[blob->cbData - i - 1] = temp;
}
}
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = TRUE;
__TRY
{
struct AsnDecodeSequenceItem items[] = {
{ offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
{ offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CERT_SIGNED_CONTENT_INFO,
SignatureAlgorithm.Parameters.pbData), 0 },
{ offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
};
if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, pcbStructInfo);
}
__EXCEPT(page_fault)
{
SetLastError(STATUS_ACCESS_VIOLATION);
ret = FALSE;
}
__ENDTRY
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret;
if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR))
{
DWORD dataLen;
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
{
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
ret = CRYPT_AsnDecodeInt(dwCertEncodingType, X509_INTEGER,
pbEncoded + 1 + lenBytes, dataLen, dwFlags, pDecodePara,
pvStructInfo, pcbStructInfo);
}
}
else
{
SetLastError(CRYPT_E_ASN1_BADTAG);
ret = FALSE;
}
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType, static BOOL WINAPI CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
...@@ -2338,16 +2482,16 @@ static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, ...@@ -2338,16 +2482,16 @@ static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
Subject.pbData) }, Subject.pbData) },
{ offsetof(CERT_INFO, SubjectPublicKeyInfo), CRYPT_AsnDecodePubKeyInfo, { offsetof(CERT_INFO, SubjectPublicKeyInfo), CRYPT_AsnDecodePubKeyInfo,
sizeof(CERT_PUBLIC_KEY_INFO), FALSE, TRUE, offsetof(CERT_INFO, sizeof(CERT_PUBLIC_KEY_INFO), FALSE, TRUE, offsetof(CERT_INFO,
SubjectPublicKeyInfo.Algorithm.Parameters.pbData) }, SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
{ offsetof(CERT_INFO, IssuerUniqueId), CRYPT_AsnDecodeBitsInternal, { offsetof(CERT_INFO, IssuerUniqueId), CRYPT_AsnDecodeBitsInternal,
sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO,
IssuerUniqueId.pbData) }, IssuerUniqueId.pbData), 0 },
{ offsetof(CERT_INFO, SubjectUniqueId), CRYPT_AsnDecodeBitsInternal, { offsetof(CERT_INFO, SubjectUniqueId), CRYPT_AsnDecodeBitsInternal,
sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO,
SubjectUniqueId.pbData) }, SubjectUniqueId.pbData), 0 },
{ offsetof(CERT_INFO, cExtension), CRYPT_AsnDecodeExtensions, { offsetof(CERT_INFO, cExtension), CRYPT_AsnDecodeExtensions,
sizeof(CERT_EXTENSIONS), TRUE, TRUE, offsetof(CERT_INFO, sizeof(CERT_EXTENSIONS), TRUE, TRUE, offsetof(CERT_INFO,
rgExtension) }, rgExtension), 0 },
}; };
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items, ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
...@@ -3322,57 +3466,6 @@ static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType, ...@@ -3322,57 +3466,6 @@ static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType,
return ret; return ret;
} }
static BOOL WINAPI CRYPT_AsnDecodePathConstraint(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
BOOL ret = TRUE;
DWORD bytesNeeded = sizeof(BOOL) + sizeof(DWORD);
if (!pvStructInfo)
*pcbStructInfo = bytesNeeded;
else if (*pcbStructInfo < bytesNeeded)
{
*pcbStructInfo = bytesNeeded;
SetLastError(ERROR_MORE_DATA);
ret = FALSE;
}
else
{
if (cbEncoded)
{
if (pbEncoded[0] == ASN_INTEGER)
{
DWORD size = sizeof(DWORD);
ret = CRYPT_AsnDecodeInt(dwCertEncodingType, X509_INTEGER,
pbEncoded, cbEncoded, 0, NULL,
(BYTE *)pvStructInfo + sizeof(BOOL), &size);
if (ret)
{
cbEncoded -= 2 + pbEncoded[1];
pbEncoded += 2 + pbEncoded[1];
if (cbEncoded)
{
SetLastError(CRYPT_E_ASN1_CORRUPT);
ret = FALSE;
}
else
*(BOOL *)pvStructInfo = TRUE;
}
}
else
{
SetLastError(CRYPT_E_ASN1_BADTAG);
ret = FALSE;
}
}
else
*(BOOL *)pvStructInfo = FALSE;
}
return ret;
}
static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType, static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
...@@ -3571,8 +3664,10 @@ static BOOL WINAPI CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType, ...@@ -3571,8 +3664,10 @@ static BOOL WINAPI CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType,
blob->cUnusedBits = *(pbEncoded + 1 + blob->cUnusedBits = *(pbEncoded + 1 +
GET_LEN_BYTES(pbEncoded[1])); GET_LEN_BYTES(pbEncoded[1]));
if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
{
blob->pbData = (BYTE *)pbEncoded + 2 + blob->pbData = (BYTE *)pbEncoded + 2 +
GET_LEN_BYTES(pbEncoded[1]); GET_LEN_BYTES(pbEncoded[1]);
}
else else
{ {
assert(blob->pbData); assert(blob->pbData);
...@@ -4368,6 +4463,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, ...@@ -4368,6 +4463,9 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
{ {
switch (LOWORD(lpszStructType)) switch (LOWORD(lpszStructType))
{ {
case (WORD)X509_CERT:
decodeFunc = CRYPT_AsnDecodeCert;
break;
case (WORD)X509_CERT_TO_BE_SIGNED: case (WORD)X509_CERT_TO_BE_SIGNED:
decodeFunc = CRYPT_AsnDecodeCertInfo; decodeFunc = CRYPT_AsnDecodeCertInfo;
break; break;
......
...@@ -1628,6 +1628,74 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding) ...@@ -1628,6 +1628,74 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding)
} }
} }
static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
0xe, 0xf };
static const BYTE signedBigCert[] = {
0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
static void test_encodeCert(DWORD dwEncoding)
{
/* Note the SignatureAlgorithm must match that in the encoded cert. Note
* also that bigCert is a NULL-terminated string, so don't count its
* last byte (otherwise the signed cert won't decode.)
*/
CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert) - 1, (BYTE *)bigCert },
{ NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
BOOL ret;
BYTE *buf = NULL;
DWORD bufSize = 0;
ret = CryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
if (buf)
{
ok(bufSize == sizeof(signedBigCert), "Expected size %d, got %ld\n",
sizeof(signedBigCert), bufSize);
ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
LocalFree(buf);
}
}
static void test_decodeCert(DWORD dwEncoding)
{
BOOL ret;
BYTE *buf = NULL;
DWORD size = 0;
ret = CryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
ok(ret, "CryptDecodeObjectEx failed: %08lx\n", GetLastError());
if (buf)
{
CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
ok(info->ToBeSigned.cbData == sizeof(bigCert) - 1,
"Expected cert to be %d bytes, got %ld\n", sizeof(bigCert) - 1,
info->ToBeSigned.cbData);
ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
"Unexpected cert\n");
ok(info->Signature.cbData == sizeof(hash),
"Expected signature size %d, got %ld\n", sizeof(hash),
info->Signature.cbData);
ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
"Unexpected signature\n");
LocalFree(buf);
}
}
static void test_registerOIDFunction(void) static void test_registerOIDFunction(void)
{ {
static const WCHAR bogusDll[] = { 'b','o','g','u','s','.','d','l','l',0 }; static const WCHAR bogusDll[] = { 'b','o','g','u','s','.','d','l','l',0 };
...@@ -1712,6 +1780,8 @@ START_TEST(encode) ...@@ -1712,6 +1780,8 @@ START_TEST(encode)
test_decodePublicKeyInfo(encodings[i]); test_decodePublicKeyInfo(encodings[i]);
test_encodeCertToBeSigned(encodings[i]); test_encodeCertToBeSigned(encodings[i]);
test_decodeCertToBeSigned(encodings[i]); test_decodeCertToBeSigned(encodings[i]);
test_encodeCert(encodings[i]);
test_decodeCert(encodings[i]);
} }
test_registerOIDFunction(); test_registerOIDFunction();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment