Juan Lang : crypt32:
Test and fix encoding and decoding of attributes in PKCS signers.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jul 26 06:37:25 CDT 2007
Module: wine
Branch: master
Commit: c58cb379ebf5875ca241b609765554a9099e0e85
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c58cb379ebf5875ca241b609765554a9099e0e85
Author: Juan Lang <juan.lang at gmail.com>
Date: Wed Jul 25 18:13:45 2007 -0700
crypt32: Test and fix encoding and decoding of attributes in PKCS signers.
---
dlls/crypt32/decode.c | 27 ++++++++++++--------
dlls/crypt32/encode.c | 30 +++++++++++++++--------
dlls/crypt32/tests/encode.c | 55 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 21 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 29e1a2d..52e207e 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -1896,9 +1896,8 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttributesInternal(
DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
void *pvStructInfo, DWORD *pcbStructInfo)
{
- struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
- CRYPT_AsnDecodePKCSAttribute, sizeof(CRYPT_ATTRIBUTE), TRUE,
- offsetof(CRYPT_ATTRIBUTE, pszObjId) };
+ struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodePKCSAttribute,
+ sizeof(CRYPT_ATTRIBUTE), TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
BOOL ret;
@@ -1921,8 +1920,12 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
{
DWORD bytesNeeded;
- if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType,
- lpszStructType, pbEncoded, cbEncoded,
+ if (!cbEncoded)
+ SetLastError(CRYPT_E_ASN1_EOD);
+ else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
+ SetLastError(CRYPT_E_ASN1_CORRUPT);
+ else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(
+ dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded,
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded)))
{
if (!pvStructInfo)
@@ -3813,19 +3816,21 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
{ ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
+ { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
+ offsetof(CMSG_SIGNER_INFO, AuthAttrs),
+ CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
+ TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
{ ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
HashEncryptionAlgorithm.pszObjId), 0 },
- { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CMSG_SIGNER_INFO, AuthAttrs),
- CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
- TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
- { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
- CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
- TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
{ ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
+ { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
+ offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
+ CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
+ TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
};
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index e6695cf..b653a0d 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -3201,26 +3201,36 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType,
{ &info->Issuer, CRYPT_AsnEncodeIssuerSerialNumber, 0 },
{ &info->HashAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams,
0 },
- { &info->HashEncryptionAlgorithm,
- CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
};
- DWORD cItem = 4;
+ struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } };
+ DWORD cItem = 3, cSwapped = 0;
if (info->AuthAttrs.cAttr)
{
- items[cItem].pvStructInfo = &info->AuthAttrs;
- items[cItem].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+ swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0;
+ swapped[cSwapped].pvStructInfo = &info->AuthAttrs;
+ swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+ items[cItem].pvStructInfo = &swapped[cSwapped];
+ items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
+ cSwapped++;
cItem++;
}
+ items[cItem].pvStructInfo = &info->HashEncryptionAlgorithm;
+ items[cItem].encodeFunc = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
+ cItem++;
+ items[cItem].pvStructInfo = &info->EncryptedHash;
+ items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
+ cItem++;
if (info->UnauthAttrs.cAttr)
{
- items[cItem].pvStructInfo = &info->UnauthAttrs;
- items[cItem].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+ swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 1;
+ swapped[cSwapped].pvStructInfo = &info->UnauthAttrs;
+ swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+ items[cItem].pvStructInfo = &swapped[cSwapped];
+ items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
+ cSwapped++;
cItem++;
}
- items[cItem].pvStructInfo = &info->EncryptedHash;
- items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
- cItem++;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index 8173a12..467619a 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -4924,6 +4924,14 @@ static const BYTE PKCSSignerWithHash[] = {
0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
+static const BYTE PKCSSignerWithAuthAttr[] = {
+0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
+0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
+0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
+0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
+0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
+0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
static void test_encodePKCSSignerInfo(DWORD dwEncoding)
{
@@ -4932,6 +4940,10 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding)
LPBYTE buf = NULL;
DWORD size = 0;
CMSG_SIGNER_INFO info = { 0 };
+ char oid_common_name[] = szOID_COMMON_NAME;
+ CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
+ (LPBYTE)encodedCommonName };
+ CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
@@ -5053,6 +5065,29 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding)
LocalFree(buf);
}
}
+ info.AuthAttrs.cAttr = 1;
+ info.AuthAttrs.rgAttr = &attr;
+ SetLastError(0xdeadbeef);
+ ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
+ CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
+ if (!(dwEncoding & PKCS_7_ASN_ENCODING))
+ ok(!ret && GetLastError() == E_INVALIDARG,
+ "Expected E_INVALIDARG, got %08x\n", GetLastError());
+ else
+ {
+ ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
+ if (buf)
+ {
+ ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
+ size);
+ if (size == sizeof(PKCSSignerWithAuthAttr))
+ ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
+ "Unexpected value\n");
+ else
+ ok(0, "Unexpected value\n");
+ LocalFree(buf);
+ }
+ }
}
static void test_decodePKCSSignerInfo(DWORD dwEncoding)
@@ -5157,6 +5192,26 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding)
"Unexpected value\n");
LocalFree(buf);
}
+ ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
+ PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
+ CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
+ if (buf)
+ {
+ info = (CMSG_SIGNER_INFO *)buf;
+ ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
+ info->AuthAttrs.cAttr);
+ ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
+ "Expected %s, got %s\n", szOID_COMMON_NAME,
+ info->AuthAttrs.rgAttr[0].pszObjId);
+ ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
+ info->AuthAttrs.rgAttr[0].cValue);
+ ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
+ sizeof(encodedCommonName), "Unexpected size %d\n",
+ info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
+ ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
+ encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
+ LocalFree(buf);
+ }
}
/* Free *pInfo with HeapFree */
More information about the wine-cvs
mailing list