crypt32: Use CMS messages rather than PKCS messages internally.

This commit is contained in:
Juan Lang 2008-08-20 11:57:21 -07:00 committed by Alexandre Julliard
parent a360e93430
commit 282eb73bc3
5 changed files with 135 additions and 54 deletions

View file

@ -84,20 +84,20 @@ BOOL CRYPT_AsnEncodePKCSDigestedData(CRYPT_DIGESTED_DATA *digestedData,
typedef struct _CRYPT_SIGNED_INFO
{
DWORD version;
DWORD cCertEncoded;
PCERT_BLOB rgCertEncoded;
DWORD cCrlEncoded;
PCRL_BLOB rgCrlEncoded;
CRYPT_CONTENT_INFO content;
DWORD cSignerInfo;
PCMSG_SIGNER_INFO rgSignerInfo;
DWORD version;
DWORD cCertEncoded;
PCERT_BLOB rgCertEncoded;
DWORD cCrlEncoded;
PCRL_BLOB rgCrlEncoded;
CRYPT_CONTENT_INFO content;
DWORD cSignerInfo;
PCMSG_CMS_SIGNER_INFO rgSignerInfo;
} CRYPT_SIGNED_INFO;
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
DWORD *pcbData);
BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo);

View file

@ -4452,8 +4452,8 @@ static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
{
BOOL ret;
struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
struct GenericArray *array = (struct GenericArray *)pvStructInfo;
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
@ -4465,7 +4465,7 @@ static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
{

View file

@ -3508,7 +3508,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType,
return ret;
}
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
DWORD *pcbData)
{
struct AsnEncodeSequenceItem items[7] = {
@ -3524,9 +3524,9 @@ BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
{
digestAlgorithmsSet.cItems = signedInfo->cSignerInfo;
digestAlgorithmsSet.items = signedInfo->rgSignerInfo;
digestAlgorithmsSet.itemSize = sizeof(CMSG_SIGNER_INFO);
digestAlgorithmsSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO);
digestAlgorithmsSet.itemOffset =
offsetof(CMSG_SIGNER_INFO, HashAlgorithm);
offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm);
digestAlgorithmsSet.encode = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
items[cItem].pvStructInfo = &digestAlgorithmsSet;
items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
@ -3569,9 +3569,9 @@ BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
{
signerSet.cItems = signedInfo->cSignerInfo;
signerSet.items = signedInfo->rgSignerInfo;
signerSet.itemSize = sizeof(CMSG_SIGNER_INFO);
signerSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO);
signerSet.itemOffset = 0;
signerSet.encode = CRYPT_AsnEncodePKCSSignerInfo;
signerSet.encode = CRYPT_AsnEncodeCMSSignerInfo;
items[cItem].pvStructInfo = &signerSet;
items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
cItem++;

View file

@ -799,18 +799,59 @@ static BOOL CRYPT_ConstructAttributes(CRYPT_ATTRIBUTES *out,
return ret;
}
/* Constructs a CMSG_SIGNER_INFO from a CMSG_SIGNER_ENCODE_INFO_WITH_CMS. */
static BOOL CSignerInfo_Construct(CMSG_SIGNER_INFO *info,
CMSG_SIGNER_ENCODE_INFO_WITH_CMS *in)
/* Constructs a CMSG_CMS_SIGNER_INFO from a CMSG_SIGNER_ENCODE_INFO_WITH_CMS. */
static BOOL CSignerInfo_Construct(CMSG_CMS_SIGNER_INFO *info,
const CMSG_SIGNER_ENCODE_INFO_WITH_CMS *in)
{
BOOL ret;
/* Note: needs to change if CMS fields are supported */
info->dwVersion = CMSG_SIGNER_INFO_V1;
ret = CRYPT_ConstructBlob(&info->Issuer, &in->pCertInfo->Issuer);
if (ret)
ret = CRYPT_ConstructBlob(&info->SerialNumber,
&in->pCertInfo->SerialNumber);
if (in->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO))
{
info->dwVersion = CMSG_SIGNER_INFO_V1;
ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer,
&in->pCertInfo->Issuer);
if (ret)
ret = CRYPT_ConstructBlob(
&info->SignerId.IssuerSerialNumber.SerialNumber,
&in->pCertInfo->SerialNumber);
info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
}
else
{
/* Implicitly in->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO_WITH_CMS).
* See CRYPT_IsValidSigner.
*/
if (!in->SignerId.dwIdChoice)
{
info->dwVersion = CMSG_SIGNER_INFO_V1;
ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer,
&in->pCertInfo->Issuer);
if (ret)
ret = CRYPT_ConstructBlob(
&info->SignerId.IssuerSerialNumber.SerialNumber,
&in->pCertInfo->SerialNumber);
info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
}
else if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
info->dwVersion = CMSG_SIGNER_INFO_V1;
info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer,
&in->SignerId.IssuerSerialNumber.Issuer);
if (ret)
ret = CRYPT_ConstructBlob(
&info->SignerId.IssuerSerialNumber.SerialNumber,
&in->SignerId.IssuerSerialNumber.SerialNumber);
}
else
{
/* Implicitly dwIdChoice == CERT_ID_KEY_IDENTIFIER */
info->dwVersion = CMSG_SIGNER_INFO_V3;
info->SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
ret = CRYPT_ConstructBlob(&info->SignerId.KeyId,
&in->SignerId.KeyId);
}
}
/* Assumption: algorithm IDs will point to static strings, not
* stack-based ones, so copying the pointer values is safe.
*/
@ -829,12 +870,17 @@ static BOOL CSignerInfo_Construct(CMSG_SIGNER_INFO *info,
return ret;
}
static void CSignerInfo_Free(CMSG_SIGNER_INFO *info)
static void CSignerInfo_Free(CMSG_CMS_SIGNER_INFO *info)
{
DWORD i, j;
CryptMemFree(info->Issuer.pbData);
CryptMemFree(info->SerialNumber.pbData);
if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
CryptMemFree(info->SignerId.IssuerSerialNumber.Issuer.pbData);
CryptMemFree(info->SignerId.IssuerSerialNumber.SerialNumber.pbData);
}
else
CryptMemFree(info->SignerId.KeyId.pbData);
CryptMemFree(info->HashAlgorithm.Parameters.pbData);
CryptMemFree(info->EncryptedHash.pbData);
for (i = 0; i < info->AuthAttrs.cAttr; i++)
@ -1204,7 +1250,7 @@ static BOOL CSignedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
}
if (ret)
{
ret = CRYPT_AsnEncodePKCSSignedInfo(&info, pvData, pcbData);
ret = CRYPT_AsnEncodeCMSSignedInfo(&info, pvData, pcbData);
LocalFree(info.content.Content.pbData);
}
break;
@ -1222,7 +1268,7 @@ static BOOL CSignedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
SetLastError(CRYPT_E_INVALID_INDEX);
else
ret = CryptEncodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
PKCS7_SIGNER_INFO, &msg->msg_data.info->rgSignerInfo[dwIndex], 0,
CMS_SIGNER_INFO, &msg->msg_data.info->rgSignerInfo[dwIndex], 0,
NULL, pvData, pcbData);
break;
case CMSG_VERSION_PARAM:
@ -1325,12 +1371,13 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags,
if (info->cSigners)
{
msg->msg_data.info->rgSignerInfo =
CryptMemAlloc(info->cSigners * sizeof(CMSG_SIGNER_INFO));
CryptMemAlloc(info->cSigners * sizeof(CMSG_CMS_SIGNER_INFO));
if (msg->msg_data.info->rgSignerInfo)
{
msg->msg_data.info->cSignerInfo = info->cSigners;
memset(msg->msg_data.info->rgSignerInfo, 0,
msg->msg_data.info->cSignerInfo * sizeof(CMSG_SIGNER_INFO));
msg->msg_data.info->cSignerInfo *
sizeof(CMSG_CMS_SIGNER_INFO));
ret = CSignedMsgData_AllocateHandles(&msg->msg_data);
for (i = 0; ret && i < msg->msg_data.info->cSignerInfo; i++)
{
@ -1592,7 +1639,7 @@ static BOOL CDecodeMsg_DecodeSignedContent(CDecodeMsg *msg,
CRYPT_SIGNED_INFO *signedInfo;
DWORD size;
ret = CRYPT_AsnDecodePKCSSignedInfo(blob->pbData, blob->cbData,
ret = CRYPT_AsnDecodeCMSSignedInfo(blob->pbData, blob->cbData,
CRYPT_DECODE_ALLOC_FLAG, NULL, (CRYPT_SIGNED_INFO *)&signedInfo,
&size);
if (ret)
@ -1928,15 +1975,23 @@ static DWORD CRYPT_SizeOfAttributes(const CRYPT_ATTRIBUTES *attr)
}
static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData,
const CMSG_SIGNER_INFO *in)
const CMSG_CMS_SIGNER_INFO *in)
{
DWORD size = sizeof(CMSG_SIGNER_INFO);
BOOL ret;
TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
size += in->Issuer.cbData;
size += in->SerialNumber.cbData;
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
size += in->SignerId.IssuerSerialNumber.Issuer.cbData;
size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData;
}
else
{
FIXME("unsupported for key id\n");
return FALSE;
}
if (in->HashAlgorithm.pszObjId)
size += strlen(in->HashAlgorithm.pszObjId) + 1;
size += in->HashAlgorithm.Parameters.cbData;
@ -1966,8 +2021,13 @@ static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData,
CMSG_SIGNER_INFO *out = (CMSG_SIGNER_INFO *)pvData;
out->dwVersion = in->dwVersion;
CRYPT_CopyBlob(&out->Issuer, &in->Issuer, &nextData);
CRYPT_CopyBlob(&out->SerialNumber, &in->SerialNumber, &nextData);
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
CRYPT_CopyBlob(&out->Issuer,
&in->SignerId.IssuerSerialNumber.Issuer, &nextData);
CRYPT_CopyBlob(&out->SerialNumber,
&in->SignerId.IssuerSerialNumber.SerialNumber, &nextData);
}
CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
&nextData);
CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
@ -1985,15 +2045,23 @@ static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData,
}
static BOOL CRYPT_CopySignerCertInfo(void *pvData, DWORD *pcbData,
const CMSG_SIGNER_INFO *in)
const CMSG_CMS_SIGNER_INFO *in)
{
DWORD size = sizeof(CERT_INFO);
BOOL ret;
TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
size += in->Issuer.cbData;
size += in->SerialNumber.cbData;
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
size += in->SignerId.IssuerSerialNumber.Issuer.cbData;
size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData;
}
else
{
FIXME("unimplemented for key id\n");
return FALSE;
}
if (!pvData)
{
*pcbData = size;
@ -2011,8 +2079,10 @@ static BOOL CRYPT_CopySignerCertInfo(void *pvData, DWORD *pcbData,
CERT_INFO *out = (CERT_INFO *)pvData;
memset(out, 0, sizeof(CERT_INFO));
CRYPT_CopyBlob(&out->Issuer, &in->Issuer, &nextData);
CRYPT_CopyBlob(&out->SerialNumber, &in->SerialNumber, &nextData);
CRYPT_CopyBlob(&out->Issuer,
&in->SignerId.IssuerSerialNumber.Issuer, &nextData);
CRYPT_CopyBlob(&out->SerialNumber,
&in->SignerId.IssuerSerialNumber.SerialNumber, &nextData);
ret = TRUE;
}
TRACE("returning %d\n", ret);
@ -2285,15 +2355,26 @@ static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info)
for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++)
{
ret = CertCompareCertificateName(X509_ASN_ENCODING,
&msg->u.signed_data.info->rgSignerInfo[i].Issuer, &info->Issuer);
if (ret)
PCMSG_CMS_SIGNER_INFO signerInfo =
&msg->u.signed_data.info->rgSignerInfo[i];
if (signerInfo->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
ret = CertCompareIntegerBlob(
&msg->u.signed_data.info->rgSignerInfo[i].SerialNumber,
&info->SerialNumber);
ret = CertCompareCertificateName(X509_ASN_ENCODING,
&signerInfo->SignerId.IssuerSerialNumber.Issuer,
&info->Issuer);
if (ret)
break;
{
ret = CertCompareIntegerBlob(
&signerInfo->SignerId.IssuerSerialNumber.SerialNumber,
&info->SerialNumber);
if (ret)
break;
}
}
else
{
FIXME("signer %d: unimplemented for key id\n", i);
}
}
if (ret)

View file

@ -697,7 +697,7 @@ static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
}
if (ret)
{
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, NULL, &size);
ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, NULL, &size);
if (ret)
{
if (!blob->pbData)
@ -711,7 +711,7 @@ static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
else
{
blob->cbData = size;
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, blob->pbData,
ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, blob->pbData,
&blob->cbData);
}
}