Commit 817adc55 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Implement CMSG_CMS_SIGNER_INFO encoding.

parent d71e6e96
/* /*
* Copyright 2005-2007 Juan Lang * Copyright 2005-2008 Juan Lang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -3419,6 +3419,95 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType, ...@@ -3419,6 +3419,95 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType,
return ret; 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, BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
DWORD *pcbData) DWORD *pcbData)
{ {
...@@ -3607,6 +3696,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, ...@@ -3607,6 +3696,9 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
case LOWORD(PKCS7_SIGNER_INFO): case LOWORD(PKCS7_SIGNER_INFO):
encodeFunc = CRYPT_AsnEncodePKCSSignerInfo; encodeFunc = CRYPT_AsnEncodePKCSSignerInfo;
break; break;
case LOWORD(CMS_SIGNER_INFO):
encodeFunc = CRYPT_AsnEncodeCMSSignerInfo;
break;
} }
} }
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS)) else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
......
...@@ -5498,14 +5498,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5498,14 +5498,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
/* To be encoded, a signer must have a valid cert ID, where a valid ID may /* 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) ...@@ -5519,7 +5517,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING)) if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
...@@ -5533,13 +5530,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5533,13 +5530,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
}
info.SignerId.IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum); info.SignerId.IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
info.SignerId.IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum; info.SignerId.IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING)) if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
...@@ -5554,14 +5549,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5554,14 +5549,12 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
}
info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER; info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
info.SignerId.KeyId.cbData = sizeof(serialNum); info.SignerId.KeyId.cbData = sizeof(serialNum);
info.SignerId.KeyId.pbData = (BYTE *)serialNum; info.SignerId.KeyId.pbData = (BYTE *)serialNum;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING)) if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
...@@ -5576,7 +5569,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5576,7 +5569,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
}
/* While a CERT_ID can have a hash type, that's not allowed in CMS, where /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
* only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
* (see RFC 3852, section 5.3.) * (see RFC 3852, section 5.3.)
...@@ -5587,7 +5579,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5587,7 +5579,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
/* Now with a hash algo */ /* Now with a hash algo */
...@@ -5599,7 +5590,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5599,7 +5590,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING)) if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
...@@ -5615,12 +5605,10 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5615,12 +5605,10 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
}
info.HashEncryptionAlgorithm.pszObjId = oid2; info.HashEncryptionAlgorithm.pszObjId = oid2;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING)) if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
...@@ -5636,13 +5624,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5636,13 +5624,11 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
}
info.EncryptedHash.cbData = sizeof(hash); info.EncryptedHash.cbData = sizeof(hash);
info.EncryptedHash.pbData = (BYTE *)hash; info.EncryptedHash.pbData = (BYTE *)hash;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info, ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size); CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
todo_wine {
if (!(dwEncoding & PKCS_7_ASN_ENCODING)) if (!(dwEncoding & PKCS_7_ASN_ENCODING))
ok(!ret && GetLastError() == E_INVALIDARG, ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError()); "Expected E_INVALIDARG, got %08x\n", GetLastError());
...@@ -5657,7 +5643,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding) ...@@ -5657,7 +5643,6 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
LocalFree(buf); LocalFree(buf);
} }
} }
}
} }
static void test_decodeCMSSignerInfo(DWORD dwEncoding) static void test_decodeCMSSignerInfo(DWORD dwEncoding)
......
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