From 282eb73bc3eafe63f3f33117370b7e891011353b Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Wed, 20 Aug 2008 11:57:21 -0700 Subject: [PATCH] crypt32: Use CMS messages rather than PKCS messages internally. --- dlls/crypt32/crypt32_private.h | 20 ++--- dlls/crypt32/decode.c | 6 +- dlls/crypt32/encode.c | 10 +-- dlls/crypt32/msg.c | 149 +++++++++++++++++++++++++-------- dlls/crypt32/serialize.c | 4 +- 5 files changed, 135 insertions(+), 54 deletions(-) diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index 18384dcc9f1..c0805408dd2 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -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); diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 1f5348c924f..8df801aba84 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -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) { diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 16b4bb86871..5658ba2f374 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -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++; diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 12ee8a38b1f..3fd188809de 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -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) diff --git a/dlls/crypt32/serialize.c b/dlls/crypt32/serialize.c index 5f9911f774c..f55302d5129 100644 --- a/dlls/crypt32/serialize.c +++ b/dlls/crypt32/serialize.c @@ -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); } }