crypt32: Implement CMSG_CMS_SIGNER_INFO encoding.

This commit is contained in:
Juan Lang 2008-08-14 12:50:57 -07:00 committed by Alexandre Julliard
parent d71e6e96dd
commit 817adc5599
2 changed files with 93 additions and 16 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2007 Juan Lang
* Copyright 2005-2008 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -3419,6 +3419,95 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType,
return ret;
}
static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
if (!(dwCertEncodingType & PKCS_7_ASN_ENCODING))
{
SetLastError(E_INVALIDARG);
return FALSE;
}
__TRY
{
const CMSG_CMS_SIGNER_INFO *info = (const CMSG_CMS_SIGNER_INFO *)pvStructInfo;
if (info->SignerId.dwIdChoice != CERT_ID_ISSUER_SERIAL_NUMBER &&
info->SignerId.dwIdChoice != CERT_ID_KEY_IDENTIFIER)
SetLastError(E_INVALIDARG);
else if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER &&
!info->SignerId.u.IssuerSerialNumber.Issuer.cbData)
SetLastError(E_INVALIDARG);
else
{
struct AsnEncodeSequenceItem items[7] = {
{ &info->dwVersion, CRYPT_AsnEncodeInt, 0 },
};
struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } };
DWORD cItem = 1, cSwapped = 0;
if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
items[cItem].pvStructInfo =
&info->SignerId.u.IssuerSerialNumber.Issuer;
items[cItem].encodeFunc =
CRYPT_AsnEncodeIssuerSerialNumber;
cItem++;
}
else
{
swapped[cSwapped].tag = ASN_CONTEXT | 0;
swapped[cSwapped].pvStructInfo = &info->SignerId.u.KeyId;
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeOctets;
items[cItem].pvStructInfo = &swapped[cSwapped];
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
cSwapped++;
cItem++;
}
items[cItem].pvStructInfo = &info->HashAlgorithm;
items[cItem].encodeFunc = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
cItem++;
if (info->AuthAttrs.cAttr)
{
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)
{
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++;
}
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
return ret;
}
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
DWORD *pcbData)
{
@ -3607,6 +3696,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(PKCS7_SIGNER_INFO):
encodeFunc = CRYPT_AsnEncodePKCSSignerInfo;
break;
case LOWORD(CMS_SIGNER_INFO):
encodeFunc = CRYPT_AsnEncodeCMSSignerInfo;
break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))

View File

@ -5498,14 +5498,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
/* To be encoded, a signer must have a valid cert ID, where a valid ID may
@ -5519,7 +5517,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
@ -5533,13 +5530,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf);
}
}
}
info.SignerId.IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
info.SignerId.IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
@ -5554,14 +5549,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf);
}
}
}
info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
info.SignerId.KeyId.cbData = sizeof(serialNum);
info.SignerId.KeyId.pbData = (BYTE *)serialNum;
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
@ -5576,7 +5569,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf);
}
}
}
/* While a CERT_ID can have a hash type, that's not allowed in CMS, where
* only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
* (see RFC 3852, section 5.3.)
@ -5587,7 +5579,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
/* Now with a hash algo */
@ -5599,7 +5590,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
@ -5615,12 +5605,10 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf);
}
}
}
info.HashEncryptionAlgorithm.pszObjId = oid2;
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
@ -5636,13 +5624,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf);
}
}
}
info.EncryptedHash.cbData = sizeof(hash);
info.EncryptedHash.pbData = (BYTE *)hash;
SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
@ -5658,7 +5644,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
}
}
}
}
static void test_decodeCMSSignerInfo(DWORD dwEncoding)
{