crypt32: Implement CMSG_CMS_SIGNER_INFO encoding.
This commit is contained in:
parent
d71e6e96dd
commit
817adc5599
|
@ -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))
|
||||
|
|
|
@ -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());
|
||||
|
@ -5657,7 +5643,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
|
|||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_decodeCMSSignerInfo(DWORD dwEncoding)
|
||||
|
|
Loading…
Reference in New Issue