#include "wine/port.h"
#include <stdarg.h>
+#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
typedef BOOL (*CryptMsgControlFunc)(HCRYPTMSG hCryptMsg, DWORD dwFlags,
DWORD dwCtrlType, const void *pvCtrlPara);
-BOOL CRYPT_DefaultMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
+static BOOL CRYPT_DefaultMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
DWORD dwCtrlType, const void *pvCtrlPara)
{
TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara);
static void CDataEncodeMsg_Close(HCRYPTMSG hCryptMsg)
{
- CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg;
+ CDataEncodeMsg *msg = hCryptMsg;
if (msg->bare_content != empty_data_content)
LocalFree(msg->bare_content);
static BOOL CDataEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal)
{
- CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg;
+ CDataEncodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
if (msg->base.state == MsgStateFinalized)
static BOOL CDataEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
DWORD dwIndex, void *pvData, DWORD *pcbData)
{
- CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg;
+ CDataEncodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
switch (dwParamType)
msg->bare_content_len = sizeof(empty_data_content);
msg->bare_content = (LPBYTE)empty_data_content;
}
- return (HCRYPTMSG)msg;
+ return msg;
}
typedef struct _CHashEncodeMsg
static void CHashEncodeMsg_Close(HCRYPTMSG hCryptMsg)
{
- CHashEncodeMsg *msg = (CHashEncodeMsg *)hCryptMsg;
+ CHashEncodeMsg *msg = hCryptMsg;
CryptMemFree(msg->data.pbData);
CryptDestroyHash(msg->hash);
static BOOL CHashEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
DWORD dwIndex, void *pvData, DWORD *pcbData)
{
- CHashEncodeMsg *msg = (CHashEncodeMsg *)hCryptMsg;
+ CHashEncodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
break;
}
case CMSG_COMPUTED_HASH_PARAM:
- ret = CryptGetHashParam(msg->hash, HP_HASHVAL, (BYTE *)pvData, pcbData,
- 0);
+ ret = CryptGetHashParam(msg->hash, HP_HASHVAL, pvData, pcbData, 0);
break;
case CMSG_VERSION_PARAM:
if (msg->base.state != MsgStateFinalized)
static BOOL CHashEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal)
{
- CHashEncodeMsg *msg = (CHashEncodeMsg *)hCryptMsg;
+ CHashEncodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
{
CHashEncodeMsg *msg;
- const CMSG_HASHED_ENCODE_INFO *info =
- (const CMSG_HASHED_ENCODE_INFO *)pvMsgEncodeInfo;
+ const CMSG_HASHED_ENCODE_INFO *info = pvMsgEncodeInfo;
HCRYPTPROV prov;
ALG_ID algID;
msg = NULL;
}
}
- return (HCRYPTMSG)msg;
+ return msg;
}
typedef struct _CMSG_SIGNER_ENCODE_INFO_WITH_CMS
}
break;
case CERT_ID_ISSUER_SERIAL_NUMBER:
- if (!signer->SignerId.IssuerSerialNumber.SerialNumber.cbData)
+ if (!signer->SignerId.u.IssuerSerialNumber.SerialNumber.cbData)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
- if (!signer->SignerId.IssuerSerialNumber.Issuer.cbData)
+ if (!signer->SignerId.u.IssuerSerialNumber.Issuer.cbData)
{
SetLastError(E_INVALIDARG);
return FALSE;
}
break;
case CERT_ID_KEY_IDENTIFIER:
- if (!signer->SignerId.KeyId.cbData)
+ if (!signer->SignerId.u.KeyId.cbData)
{
SetLastError(E_INVALIDARG);
return FALSE;
if (in->cbSize == sizeof(CMSG_SIGNER_ENCODE_INFO))
{
info->dwVersion = CMSG_SIGNER_INFO_V1;
- ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer,
+ ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer,
&in->pCertInfo->Issuer);
if (ret)
ret = CRYPT_ConstructBlob(
- &info->SignerId.IssuerSerialNumber.SerialNumber,
+ &info->SignerId.u.IssuerSerialNumber.SerialNumber,
&in->pCertInfo->SerialNumber);
info->SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
}
if (!in->SignerId.dwIdChoice)
{
info->dwVersion = CMSG_SIGNER_INFO_V1;
- ret = CRYPT_ConstructBlob(&info->SignerId.IssuerSerialNumber.Issuer,
+ ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer,
&in->pCertInfo->Issuer);
if (ret)
ret = CRYPT_ConstructBlob(
- &info->SignerId.IssuerSerialNumber.SerialNumber,
+ &info->SignerId.u.IssuerSerialNumber.SerialNumber,
&in->pCertInfo->SerialNumber);
info->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);
+ ret = CRYPT_ConstructBlob(&info->SignerId.u.IssuerSerialNumber.Issuer,
+ &in->SignerId.u.IssuerSerialNumber.Issuer);
if (ret)
ret = CRYPT_ConstructBlob(
- &info->SignerId.IssuerSerialNumber.SerialNumber,
- &in->SignerId.IssuerSerialNumber.SerialNumber);
+ &info->SignerId.u.IssuerSerialNumber.SerialNumber,
+ &in->SignerId.u.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);
+ ret = CRYPT_ConstructBlob(&info->SignerId.u.KeyId,
+ &in->SignerId.u.KeyId);
}
}
/* Assumption: algorithm IDs will point to static strings, not
if (info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
- CryptMemFree(info->SignerId.IssuerSerialNumber.Issuer.pbData);
- CryptMemFree(info->SignerId.IssuerSerialNumber.SerialNumber.pbData);
+ CryptMemFree(info->SignerId.u.IssuerSerialNumber.Issuer.pbData);
+ CryptMemFree(info->SignerId.u.IssuerSerialNumber.SerialNumber.pbData);
}
else
- CryptMemFree(info->SignerId.KeyId.pbData);
+ CryptMemFree(info->SignerId.u.KeyId.pbData);
CryptMemFree(info->HashAlgorithm.Parameters.pbData);
CryptMemFree(info->EncryptedHash.pbData);
for (i = 0; i < info->AuthAttrs.cAttr; i++)
ret = CryptEncodeObjectEx(X509_ASN_ENCODING, PKCS_ATTRIBUTES,
&msg_data->info->rgSignerInfo[i].AuthAttrs,
- CRYPT_ENCODE_ALLOC_FLAG, NULL, (LPBYTE)&encodedAttrs, &size);
+ CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedAttrs, &size);
if (ret)
{
ret = CryptHashData(
typedef struct _CSignedEncodeMsg
{
CryptMsgBase base;
+ LPSTR innerOID;
CRYPT_DATA_BLOB data;
CSignedMsgData msg_data;
} CSignedEncodeMsg;
static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
{
- CSignedEncodeMsg *msg = (CSignedEncodeMsg *)hCryptMsg;
+ CSignedEncodeMsg *msg = hCryptMsg;
DWORD i;
+ CryptMemFree(msg->innerOID);
CryptMemFree(msg->data.pbData);
CRYPT_FreeBlobArray((BlobArray *)&msg->msg_data.info->cCertEncoded);
CRYPT_FreeBlobArray((BlobArray *)&msg->msg_data.info->cCrlEncoded);
static BOOL CSignedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
DWORD dwIndex, void *pvData, DWORD *pcbData)
{
- CSignedEncodeMsg *msg = (CSignedEncodeMsg *)hCryptMsg;
+ CSignedEncodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
switch (dwParamType)
case CMSG_BARE_CONTENT_PARAM:
{
CRYPT_SIGNED_INFO info;
- char oid_rsa_data[] = szOID_RSA_data;
+ BOOL freeContent = FALSE;
info = *msg->msg_data.info;
- /* Quirk: OID is only encoded messages if an update has happened */
- if (msg->base.state != MsgStateInit)
- info.content.pszObjId = oid_rsa_data;
- else
- info.content.pszObjId = NULL;
- if (msg->data.cbData)
+ if (!msg->innerOID || !strcmp(msg->innerOID, szOID_RSA_data))
{
- CRYPT_DATA_BLOB blob = { msg->data.cbData, msg->data.pbData };
+ char oid_rsa_data[] = szOID_RSA_data;
- ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_OCTET_STRING,
- &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL,
- &info.content.Content.pbData, &info.content.Content.cbData);
+ /* Quirk: OID is only encoded messages if an update has happened */
+ if (msg->base.state != MsgStateInit)
+ info.content.pszObjId = oid_rsa_data;
+ else
+ info.content.pszObjId = NULL;
+ if (msg->data.cbData)
+ {
+ CRYPT_DATA_BLOB blob = { msg->data.cbData, msg->data.pbData };
+
+ ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_OCTET_STRING,
+ &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL,
+ &info.content.Content.pbData, &info.content.Content.cbData);
+ freeContent = TRUE;
+ }
+ else
+ {
+ info.content.Content.cbData = 0;
+ info.content.Content.pbData = NULL;
+ ret = TRUE;
+ }
}
else
{
- info.content.Content.cbData = 0;
- info.content.Content.pbData = NULL;
+ info.content.pszObjId = msg->innerOID;
+ info.content.Content.cbData = msg->data.cbData;
+ info.content.Content.pbData = msg->data.pbData;
ret = TRUE;
}
if (ret)
{
ret = CRYPT_AsnEncodeCMSSignedInfo(&info, pvData, pcbData);
- LocalFree(info.content.Content.pbData);
+ if (freeContent)
+ LocalFree(info.content.Content.pbData);
}
break;
}
static BOOL CSignedEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal)
{
- CSignedEncodeMsg *msg = (CSignedEncodeMsg *)hCryptMsg;
+ CSignedEncodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
if (msg->base.state == MsgStateFinalized)
const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
PCMSG_STREAM_INFO pStreamInfo)
{
- const CMSG_SIGNED_ENCODE_INFO_WITH_CMS *info =
- (const CMSG_SIGNED_ENCODE_INFO_WITH_CMS *)pvMsgEncodeInfo;
+ const CMSG_SIGNED_ENCODE_INFO_WITH_CMS *info = pvMsgEncodeInfo;
DWORD i;
CSignedEncodeMsg *msg;
return NULL;
}
if (info->cbSize == sizeof(CMSG_SIGNED_ENCODE_INFO_WITH_CMS) &&
- info->rgAttrCertEncoded)
+ info->cAttrCertEncoded)
{
FIXME("CMSG_SIGNED_ENCODE_INFO with CMS fields unsupported\n");
return NULL;
CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo,
CSignedEncodeMsg_Close, CSignedEncodeMsg_GetParam,
CSignedEncodeMsg_Update, CRYPT_DefaultMsgControl);
+ if (pszInnerContentObjID)
+ {
+ msg->innerOID = CryptMemAlloc(strlen(pszInnerContentObjID) + 1);
+ if (msg->innerOID)
+ strcpy(msg->innerOID, pszInnerContentObjID);
+ else
+ ret = FALSE;
+ }
+ else
+ msg->innerOID = NULL;
msg->data.cbData = 0;
msg->data.pbData = NULL;
- msg->msg_data.info = CryptMemAlloc(sizeof(CRYPT_SIGNED_INFO));
+ if (ret)
+ msg->msg_data.info = CryptMemAlloc(sizeof(CRYPT_SIGNED_INFO));
+ else
+ msg->msg_data.info = NULL;
if (msg->msg_data.info)
{
memset(msg->msg_data.info, 0, sizeof(CRYPT_SIGNED_INFO));
return msg;
}
-static inline const char *MSG_TYPE_STR(DWORD type)
-{
- switch (type)
- {
-#define _x(x) case (x): return #x
- _x(CMSG_DATA);
- _x(CMSG_SIGNED);
- _x(CMSG_ENVELOPED);
- _x(CMSG_SIGNED_AND_ENVELOPED);
- _x(CMSG_HASHED);
- _x(CMSG_ENCRYPTED);
-#undef _x
- default:
- return wine_dbg_sprintf("unknown (%d)", type);
- }
-}
-
HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags,
DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
PCMSG_STREAM_INFO pStreamInfo)
pszInnerContentObjID, pStreamInfo);
break;
case CMSG_ENVELOPED:
- FIXME("unimplemented for type %s\n", MSG_TYPE_STR(dwMsgType));
+ FIXME("unimplemented for type CMSG_ENVELOPED\n");
break;
case CMSG_SIGNED_AND_ENVELOPED:
case CMSG_ENCRYPTED:
CSignedMsgData signed_data;
} u;
CRYPT_DATA_BLOB msg_data;
+ CRYPT_DATA_BLOB detached_data;
PCONTEXT_PROPERTY_LIST properties;
} CDecodeMsg;
static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg)
{
- CDecodeMsg *msg = (CDecodeMsg *)hCryptMsg;
+ CDecodeMsg *msg = hCryptMsg;
if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG)
CryptReleaseContext(msg->crypt_prov, 0);
break;
}
CryptMemFree(msg->msg_data.pbData);
+ CryptMemFree(msg->detached_data.pbData);
ContextPropertyList_Free(msg->properties);
}
DWORD size;
ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_OCTET_STRING,
- blob->pbData, blob->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, (LPBYTE)&data,
- &size);
+ blob->pbData, blob->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &data, &size);
if (ret)
{
ret = ContextPropertyList_SetProperty(msg->properties,
(const BYTE *)digestedData->ContentInfo.pszObjId,
digestedData->ContentInfo.pszObjId ?
strlen(digestedData->ContentInfo.pszObjId) + 1 : 0);
- if (digestedData->ContentInfo.Content.cbData)
- CDecodeMsg_DecodeDataContent(msg,
- &digestedData->ContentInfo.Content);
- else
- ContextPropertyList_SetProperty(msg->properties,
- CMSG_CONTENT_PARAM, NULL, 0);
+ if (!(msg->base.open_flags & CMSG_DETACHED_FLAG))
+ {
+ if (digestedData->ContentInfo.Content.cbData)
+ CDecodeMsg_DecodeDataContent(msg,
+ &digestedData->ContentInfo.Content);
+ else
+ ContextPropertyList_SetProperty(msg->properties,
+ CMSG_CONTENT_PARAM, NULL, 0);
+ }
ContextPropertyList_SetProperty(msg->properties, CMSG_HASH_DATA_PARAM,
digestedData->hash.pbData, digestedData->hash.cbData);
LocalFree(digestedData);
CRYPT_DECODE_ALLOC_FLAG, NULL, (CRYPT_SIGNED_INFO *)&signedInfo,
&size);
if (ret)
- {
- DWORD i;
-
msg->u.signed_data.info = signedInfo;
- ret = CSignedMsgData_AllocateHandles(&msg->u.signed_data);
- for (i = 0; ret && i < msg->u.signed_data.info->cSignerInfo; i++)
- ret = CSignedMsgData_ConstructSignerHandles(&msg->u.signed_data, i,
- msg->crypt_prov);
- if (ret)
- {
- /* Now that we have all the content, update the hash handles with
- * it. Have to decode it if the type is szOID_RSA_data.
- */
- if (msg->u.signed_data.info->content.Content.cbData)
- {
- if (!strcmp(msg->u.signed_data.info->content.pszObjId,
- szOID_RSA_data))
- {
- CRYPT_DATA_BLOB *blob;
-
- ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
- X509_OCTET_STRING,
- msg->u.signed_data.info->content.Content.pbData,
- msg->u.signed_data.info->content.Content.cbData,
- CRYPT_DECODE_ALLOC_FLAG, NULL, (LPBYTE)&blob, &size);
- if (ret)
- {
- ret = CSignedMsgData_Update(&msg->u.signed_data,
- blob->pbData, blob->cbData, TRUE, Verify);
- LocalFree(blob);
- }
- }
- else
- ret = CSignedMsgData_Update(&msg->u.signed_data,
- msg->u.signed_data.info->content.Content.pbData,
- msg->u.signed_data.info->content.Content.cbData, TRUE,
- Verify);
- }
- }
- }
return ret;
}
+
/* Decodes the content in blob as the type given, and updates the value
* (type, parameters, etc.) of msg based on what blob contains.
* It doesn't just use msg's type, to allow a recursive call from an implicitly
msg->type = CMSG_HASHED;
break;
case CMSG_ENVELOPED:
- FIXME("unimplemented for type %s\n", MSG_TYPE_STR(type));
+ FIXME("unimplemented for type CMSG_ENVELOPED\n");
ret = TRUE;
break;
case CMSG_SIGNED:
ret = CryptDecodeObjectEx(X509_ASN_ENCODING, PKCS_CONTENT_INFO,
msg->msg_data.pbData, msg->msg_data.cbData, CRYPT_DECODE_ALLOC_FLAG,
- NULL, (LPBYTE)&info, &size);
+ NULL, &info, &size);
if (ret)
{
if (!strcmp(info->pszObjId, szOID_RSA_data))
return ret;
}
+static BOOL CDecodeMsg_FinalizeHashedContent(CDecodeMsg *msg,
+ CRYPT_DER_BLOB *blob)
+{
+ CRYPT_ALGORITHM_IDENTIFIER *hashAlgoID = NULL;
+ DWORD size = 0;
+ ALG_ID algID = 0;
+ BOOL ret;
+
+ CryptMsgGetParam(msg, CMSG_HASH_ALGORITHM_PARAM, 0, NULL, &size);
+ hashAlgoID = CryptMemAlloc(size);
+ ret = CryptMsgGetParam(msg, CMSG_HASH_ALGORITHM_PARAM, 0, hashAlgoID,
+ &size);
+ if (ret)
+ algID = CertOIDToAlgId(hashAlgoID->pszObjId);
+ ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash);
+ if (ret)
+ {
+ CRYPT_DATA_BLOB content;
+
+ if (msg->base.open_flags & CMSG_DETACHED_FLAG)
+ {
+ /* Unlike for non-detached messages, the data were never stored as
+ * the content param, but were saved in msg->detached_data instead.
+ */
+ content.pbData = msg->detached_data.pbData;
+ content.cbData = msg->detached_data.cbData;
+ }
+ else
+ ret = ContextPropertyList_FindProperty(msg->properties,
+ CMSG_CONTENT_PARAM, &content);
+ if (ret)
+ ret = CryptHashData(msg->u.hash, content.pbData, content.cbData, 0);
+ }
+ CryptMemFree(hashAlgoID);
+ return ret;
+}
+
+static BOOL CDecodeMsg_FinalizeSignedContent(CDecodeMsg *msg,
+ CRYPT_DER_BLOB *blob)
+{
+ BOOL ret;
+ DWORD i, size;
+
+ ret = CSignedMsgData_AllocateHandles(&msg->u.signed_data);
+ for (i = 0; ret && i < msg->u.signed_data.info->cSignerInfo; i++)
+ ret = CSignedMsgData_ConstructSignerHandles(&msg->u.signed_data, i,
+ msg->crypt_prov);
+ if (ret)
+ {
+ CRYPT_DATA_BLOB *content;
+
+ /* Now that we have all the content, update the hash handles with
+ * it. If the message is a detached message, the content is stored
+ * in msg->detached_data rather than in the signed message's
+ * content.
+ */
+ if (msg->base.open_flags & CMSG_DETACHED_FLAG)
+ content = &msg->detached_data;
+ else
+ content = &msg->u.signed_data.info->content.Content;
+ if (content->cbData)
+ {
+ /* If the message is not detached, have to decode the message's
+ * content if the type is szOID_RSA_data.
+ */
+ if (!(msg->base.open_flags & CMSG_DETACHED_FLAG) &&
+ !strcmp(msg->u.signed_data.info->content.pszObjId,
+ szOID_RSA_data))
+ {
+ CRYPT_DATA_BLOB *blob;
+
+ ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
+ X509_OCTET_STRING, content->pbData, content->cbData,
+ CRYPT_DECODE_ALLOC_FLAG, NULL, &blob, &size);
+ if (ret)
+ {
+ ret = CSignedMsgData_Update(&msg->u.signed_data,
+ blob->pbData, blob->cbData, TRUE, Verify);
+ LocalFree(blob);
+ }
+ }
+ else
+ ret = CSignedMsgData_Update(&msg->u.signed_data,
+ content->pbData, content->cbData, TRUE, Verify);
+ }
+ }
+ return ret;
+}
+
+static BOOL CDecodeMsg_FinalizeContent(CDecodeMsg *msg, CRYPT_DER_BLOB *blob)
+{
+ BOOL ret = FALSE;
+
+ switch (msg->type)
+ {
+ case CMSG_HASHED:
+ ret = CDecodeMsg_FinalizeHashedContent(msg, blob);
+ break;
+ case CMSG_SIGNED:
+ ret = CDecodeMsg_FinalizeSignedContent(msg, blob);
+ break;
+ default:
+ ret = TRUE;
+ }
+ return ret;
+}
+
static BOOL CDecodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal)
{
- CDecodeMsg *msg = (CDecodeMsg *)hCryptMsg;
+ CDecodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
{
FIXME("(%p, %p, %d, %d): streamed update stub\n", hCryptMsg, pbData,
cbData, fFinal);
- if (fFinal)
+ switch (msg->base.state)
{
- if (msg->base.open_flags & CMSG_DETACHED_FLAG &&
- msg->base.state != MsgStateDataFinalized)
+ case MsgStateInit:
+ ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
+ if (fFinal)
{
- ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
- msg->base.state = MsgStateDataFinalized;
- if (ret)
- ret = CDecodeMsg_DecodeContent(msg, &msg->msg_data,
- msg->type);
+ if (msg->base.open_flags & CMSG_DETACHED_FLAG)
+ msg->base.state = MsgStateDataFinalized;
+ else
+ msg->base.state = MsgStateFinalized;
}
else
+ msg->base.state = MsgStateUpdated;
+ break;
+ case MsgStateUpdated:
+ ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
+ if (fFinal)
{
- FIXME("(%p, %p, %d, %d): detached update stub\n", hCryptMsg,
- pbData, cbData, fFinal);
- ret = TRUE;
- msg->base.state = MsgStateFinalized;
+ if (msg->base.open_flags & CMSG_DETACHED_FLAG)
+ msg->base.state = MsgStateDataFinalized;
+ else
+ msg->base.state = MsgStateFinalized;
}
- }
- else
- {
- ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
- if (msg->base.state == MsgStateInit)
- msg->base.state = MsgStateUpdated;
+ break;
+ case MsgStateDataFinalized:
+ ret = CDecodeMsg_CopyData(&msg->detached_data, pbData, cbData);
+ if (fFinal)
+ msg->base.state = MsgStateFinalized;
+ break;
+ default:
+ SetLastError(CRYPT_E_MSG_ERROR);
+ break;
}
}
else
SetLastError(CRYPT_E_MSG_ERROR);
else
{
- if (msg->base.state == MsgStateInit)
+ switch (msg->base.state)
{
+ case MsgStateInit:
ret = CDecodeMsg_CopyData(&msg->msg_data, pbData, cbData);
- if (ret)
- ret = CDecodeMsg_DecodeContent(msg, &msg->msg_data,
- msg->type);
if (msg->base.open_flags & CMSG_DETACHED_FLAG)
msg->base.state = MsgStateDataFinalized;
else
msg->base.state = MsgStateFinalized;
- }
- else if (msg->base.state == MsgStateDataFinalized)
- {
- FIXME("(%p, %p, %d, %d): detached update stub\n", hCryptMsg,
- pbData, cbData, fFinal);
- ret = TRUE;
+ break;
+ case MsgStateDataFinalized:
+ ret = CDecodeMsg_CopyData(&msg->detached_data, pbData, cbData);
msg->base.state = MsgStateFinalized;
+ break;
+ default:
+ SetLastError(CRYPT_E_MSG_ERROR);
}
}
}
+ if (ret && fFinal &&
+ ((msg->base.open_flags & CMSG_DETACHED_FLAG && msg->base.state ==
+ MsgStateDataFinalized) ||
+ (!(msg->base.open_flags & CMSG_DETACHED_FLAG) && msg->base.state ==
+ MsgStateFinalized)))
+ ret = CDecodeMsg_DecodeContent(msg, &msg->msg_data, msg->type);
+ if (ret && msg->base.state == MsgStateFinalized)
+ ret = CDecodeMsg_FinalizeContent(msg, &msg->msg_data);
return ret;
}
{
ret = CRYPT_CopyParam(pvData, pcbData, blob.pbData, blob.cbData);
if (ret && pvData)
- CRYPT_FixUpAlgorithmID((CRYPT_ALGORITHM_IDENTIFIER *)pvData);
+ CRYPT_FixUpAlgorithmID(pvData);
}
else
SetLastError(CRYPT_E_INVALID_MSG_TYPE);
break;
}
case CMSG_COMPUTED_HASH_PARAM:
- if (!msg->u.hash)
- {
- CRYPT_ALGORITHM_IDENTIFIER *hashAlgoID = NULL;
- DWORD size = 0;
- ALG_ID algID = 0;
-
- CryptMsgGetParam(msg, CMSG_HASH_ALGORITHM_PARAM, 0, NULL, &size);
- hashAlgoID = CryptMemAlloc(size);
- ret = CryptMsgGetParam(msg, CMSG_HASH_ALGORITHM_PARAM, 0,
- hashAlgoID, &size);
- if (ret)
- algID = CertOIDToAlgId(hashAlgoID->pszObjId);
- ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash);
- if (ret)
- {
- CRYPT_DATA_BLOB content;
-
- ret = ContextPropertyList_FindProperty(msg->properties,
- CMSG_CONTENT_PARAM, &content);
- if (ret)
- ret = CryptHashData(msg->u.hash, content.pbData,
- content.cbData, 0);
- }
- CryptMemFree(hashAlgoID);
- }
- else
- ret = TRUE;
- if (ret)
- ret = CryptGetHashParam(msg->u.hash, HP_HASHVAL, pvData, pcbData,
- 0);
+ ret = CryptGetHashParam(msg->u.hash, HP_HASHVAL, pvData, pcbData, 0);
break;
default:
{
{
DWORD i;
- if ((*nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
- *nextData += (*nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+ *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
out->rgAttr = (CRYPT_ATTRIBUTE *)*nextData;
*nextData += in->cAttr * sizeof(CRYPT_ATTRIBUTE);
for (i = 0; i < in->cAttr; i++)
DWORD j;
out->rgAttr[i].cValue = in->rgAttr[i].cValue;
- if ((*nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
- *nextData += (*nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+ *nextData = POINTER_ALIGN_DWORD_PTR(*nextData);
out->rgAttr[i].rgValue = (PCRYPT_DATA_BLOB)*nextData;
*nextData += in->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
for (j = 0; j < in->rgAttr[i].cValue; j++)
if (attr->rgAttr[i].pszObjId)
size += strlen(attr->rgAttr[i].pszObjId) + 1;
/* align pointer */
- if (size % sizeof(DWORD_PTR))
- size += size % sizeof(DWORD_PTR);
+ size = ALIGN_DWORD_PTR(size);
size += attr->rgAttr[i].cValue * sizeof(CRYPT_DATA_BLOB);
for (j = 0; j < attr->rgAttr[i].cValue; j++)
size += attr->rgAttr[i].rgValue[j].cbData;
}
/* align pointer again to be conservative */
- if (size % sizeof(DWORD_PTR))
- size += size % sizeof(DWORD_PTR);
+ size = ALIGN_DWORD_PTR(size);
return size;
}
static BOOL CRYPT_CopySignerInfo(void *pvData, DWORD *pcbData,
const CMSG_CMS_SIGNER_INFO *in)
{
- DWORD size = sizeof(CMSG_SIGNER_INFO), rdnSize;
+ DWORD size = sizeof(CMSG_SIGNER_INFO), rdnSize = 0;
BOOL ret;
TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
- size += in->SignerId.IssuerSerialNumber.Issuer.cbData;
- size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData;
+ size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
+ size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
}
else
{
- rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.KeyId);
+ rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId);
size += rdnSize;
}
if (in->HashAlgorithm.pszObjId)
size += in->HashEncryptionAlgorithm.Parameters.cbData;
size += in->EncryptedHash.cbData;
/* align pointer */
- if (size % sizeof(DWORD_PTR))
- size += size % sizeof(DWORD_PTR);
+ size = ALIGN_DWORD_PTR(size);
size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
if (!pvData)
else
{
LPBYTE nextData = (BYTE *)pvData + sizeof(CMSG_SIGNER_INFO);
- CMSG_SIGNER_INFO *out = (CMSG_SIGNER_INFO *)pvData;
+ CMSG_SIGNER_INFO *out = pvData;
ret = TRUE;
out->dwVersion = in->dwVersion;
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
CRYPT_CopyBlob(&out->Issuer,
- &in->SignerId.IssuerSerialNumber.Issuer, &nextData);
+ &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
CRYPT_CopyBlob(&out->SerialNumber,
- &in->SignerId.IssuerSerialNumber.SerialNumber, &nextData);
+ &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
}
else
ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber,
- &in->SignerId.KeyId, rdnSize, &nextData);
+ &in->SignerId.u.KeyId, rdnSize, &nextData);
if (ret)
{
CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
&in->HashEncryptionAlgorithm, &nextData);
CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
- /* align pointer */
- if ((nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
- nextData += (nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+ nextData = POINTER_ALIGN_DWORD_PTR(nextData);
CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
}
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
- size += in->SignerId.IssuerSerialNumber.Issuer.cbData;
- size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData;
+ size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
+ size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
}
else
- size += in->SignerId.KeyId.cbData;
+ size += in->SignerId.u.KeyId.cbData;
if (in->HashAlgorithm.pszObjId)
size += strlen(in->HashAlgorithm.pszObjId) + 1;
size += in->HashAlgorithm.Parameters.cbData;
size += in->HashEncryptionAlgorithm.Parameters.cbData;
size += in->EncryptedHash.cbData;
/* align pointer */
- if (size % sizeof(DWORD_PTR))
- size += size % sizeof(DWORD_PTR);
+ size = ALIGN_DWORD_PTR(size);
size += CRYPT_SizeOfAttributes(&in->AuthAttrs);
size += CRYPT_SizeOfAttributes(&in->UnauthAttrs);
if (!pvData)
else
{
LPBYTE nextData = (BYTE *)pvData + sizeof(CMSG_CMS_SIGNER_INFO);
- CMSG_CMS_SIGNER_INFO *out = (CMSG_CMS_SIGNER_INFO *)pvData;
+ CMSG_CMS_SIGNER_INFO *out = pvData;
out->dwVersion = in->dwVersion;
out->SignerId.dwIdChoice = in->SignerId.dwIdChoice;
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
- CRYPT_CopyBlob(&out->SignerId.IssuerSerialNumber.Issuer,
- &in->SignerId.IssuerSerialNumber.Issuer, &nextData);
- CRYPT_CopyBlob(&out->SignerId.IssuerSerialNumber.SerialNumber,
- &in->SignerId.IssuerSerialNumber.SerialNumber, &nextData);
+ CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.Issuer,
+ &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
+ CRYPT_CopyBlob(&out->SignerId.u.IssuerSerialNumber.SerialNumber,
+ &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
}
else
- CRYPT_CopyBlob(&out->SignerId.KeyId, &in->SignerId.KeyId, &nextData);
+ CRYPT_CopyBlob(&out->SignerId.u.KeyId, &in->SignerId.u.KeyId, &nextData);
CRYPT_CopyAlgorithmId(&out->HashAlgorithm, &in->HashAlgorithm,
&nextData);
CRYPT_CopyAlgorithmId(&out->HashEncryptionAlgorithm,
&in->HashEncryptionAlgorithm, &nextData);
CRYPT_CopyBlob(&out->EncryptedHash, &in->EncryptedHash, &nextData);
- /* align pointer */
- if ((nextData - (LPBYTE)0) % sizeof(DWORD_PTR))
- nextData += (nextData - (LPBYTE)0) % sizeof(DWORD_PTR);
+ nextData = POINTER_ALIGN_DWORD_PTR(nextData);
CRYPT_CopyAttributes(&out->AuthAttrs, &in->AuthAttrs, &nextData);
CRYPT_CopyAttributes(&out->UnauthAttrs, &in->UnauthAttrs, &nextData);
ret = TRUE;
static BOOL CRYPT_CopySignerCertInfo(void *pvData, DWORD *pcbData,
const CMSG_CMS_SIGNER_INFO *in)
{
- DWORD size = sizeof(CERT_INFO), rdnSize;
+ DWORD size = sizeof(CERT_INFO), rdnSize = 0;
BOOL ret;
TRACE("(%p, %d, %p)\n", pvData, pvData ? *pcbData : 0, in);
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
- size += in->SignerId.IssuerSerialNumber.Issuer.cbData;
- size += in->SignerId.IssuerSerialNumber.SerialNumber.cbData;
+ size += in->SignerId.u.IssuerSerialNumber.Issuer.cbData;
+ size += in->SignerId.u.IssuerSerialNumber.SerialNumber.cbData;
}
else
{
- rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.KeyId);
+ rdnSize = CRYPT_SizeOfKeyIdAsIssuerAndSerial(&in->SignerId.u.KeyId);
size += rdnSize;
}
if (!pvData)
else
{
LPBYTE nextData = (BYTE *)pvData + sizeof(CERT_INFO);
- CERT_INFO *out = (CERT_INFO *)pvData;
+ CERT_INFO *out = pvData;
memset(out, 0, sizeof(CERT_INFO));
if (in->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
CRYPT_CopyBlob(&out->Issuer,
- &in->SignerId.IssuerSerialNumber.Issuer, &nextData);
+ &in->SignerId.u.IssuerSerialNumber.Issuer, &nextData);
CRYPT_CopyBlob(&out->SerialNumber,
- &in->SignerId.IssuerSerialNumber.SerialNumber, &nextData);
+ &in->SignerId.u.IssuerSerialNumber.SerialNumber, &nextData);
ret = TRUE;
}
else
ret = CRYPT_CopyKeyIdAsIssuerAndSerial(&out->Issuer, &out->SerialNumber,
- &in->SignerId.KeyId, rdnSize, &nextData);
+ &in->SignerId.u.KeyId, rdnSize, &nextData);
}
TRACE("returning %d\n", ret);
return ret;
ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_OCTET_STRING,
msg->u.signed_data.info->content.Content.pbData,
msg->u.signed_data.info->content.Content.cbData,
- CRYPT_DECODE_ALLOC_FLAG, NULL, (LPBYTE)&blob, &size);
+ CRYPT_DECODE_ALLOC_FLAG, NULL, &blob, &size);
if (ret)
{
ret = CRYPT_CopyParam(pvData, pcbData, blob->pbData,
static BOOL CDecodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
DWORD dwIndex, void *pvData, DWORD *pcbData)
{
- CDecodeMsg *msg = (CDecodeMsg *)hCryptMsg;
+ CDecodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
switch (msg->type)
ret = CDecodeHashMsg_GetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
computedHash, &computedHashSize);
if (ret)
- ret = !memcmp(hashBlob.pbData, computedHash,
- hashBlob.cbData);
+ {
+ if (memcmp(hashBlob.pbData, computedHash, hashBlob.cbData))
+ {
+ SetLastError(CRYPT_E_HASH_VALUE);
+ ret = FALSE;
+ }
+ }
CryptMemFree(computedHash);
}
else
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
ret = FALSE;
+ }
+ }
+ else
+ {
+ SetLastError(CRYPT_E_HASH_VALUE);
+ ret = FALSE;
}
}
return ret;
BOOL ret = FALSE;
DWORD i;
+ if (!msg->u.signed_data.signerHandles)
+ {
+ SetLastError(NTE_BAD_SIGNATURE);
+ return FALSE;
+ }
for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++)
{
PCMSG_CMS_SIGNER_INFO signerInfo =
if (signerInfo->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
{
ret = CertCompareCertificateName(X509_ASN_ENCODING,
- &signerInfo->SignerId.IssuerSerialNumber.Issuer,
+ &signerInfo->SignerId.u.IssuerSerialNumber.Issuer,
&info->Issuer);
if (ret)
{
ret = CertCompareIntegerBlob(
- &signerInfo->SignerId.IssuerSerialNumber.SerialNumber,
+ &signerInfo->SignerId.u.IssuerSerialNumber.SerialNumber,
&info->SerialNumber);
if (ret)
break;
SetLastError(ERROR_INVALID_PARAMETER);
else if (para->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo)
SetLastError(CRYPT_E_SIGNER_NOT_FOUND);
+ else if (!msg->u.signed_data.signerHandles)
+ SetLastError(NTE_BAD_SIGNATURE);
else
{
switch (para->dwSignerType)
{
case CMSG_VERIFY_SIGNER_PUBKEY:
ret = CDecodeSignedMsg_VerifySignatureWithKey(msg,
- para->hCryptProv, para->dwSignerIndex,
- (PCERT_PUBLIC_KEY_INFO)para->pvSigner);
+ para->hCryptProv, para->dwSignerIndex, para->pvSigner);
break;
case CMSG_VERIFY_SIGNER_CERT:
{
- PCCERT_CONTEXT cert = (PCCERT_CONTEXT)para->pvSigner;
+ PCCERT_CONTEXT cert = para->pvSigner;
ret = CDecodeSignedMsg_VerifySignatureWithKey(msg, para->hCryptProv,
para->dwSignerIndex, &cert->pCertInfo->SubjectPublicKeyInfo);
static BOOL CDecodeMsg_Control(HCRYPTMSG hCryptMsg, DWORD dwFlags,
DWORD dwCtrlType, const void *pvCtrlPara)
{
- CDecodeMsg *msg = (CDecodeMsg *)hCryptMsg;
+ CDecodeMsg *msg = hCryptMsg;
BOOL ret = FALSE;
switch (dwCtrlType)
memset(&msg->u, 0, sizeof(msg->u));
msg->msg_data.cbData = 0;
msg->msg_data.pbData = NULL;
+ msg->detached_data.cbData = 0;
+ msg->detached_data.pbData = NULL;
msg->properties = ContextPropertyList_Create();
}
return msg;
if (hCryptMsg)
{
- CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
+ CryptMsgBase *msg = hCryptMsg;
InterlockedIncrement(&msg->ref);
}
if (hCryptMsg)
{
- CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
+ CryptMsgBase *msg = hCryptMsg;
if (InterlockedDecrement(&msg->ref) == 0)
{
BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal)
{
- CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
+ CryptMsgBase *msg = hCryptMsg;
TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
DWORD dwIndex, void *pvData, DWORD *pcbData)
{
- CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
+ CryptMsgBase *msg = hCryptMsg;
TRACE("(%p, %d, %d, %p, %p)\n", hCryptMsg, dwParamType, dwIndex,
pvData, pcbData);
BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
DWORD dwCtrlType, const void *pvCtrlPara)
{
- CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
+ CryptMsgBase *msg = hCryptMsg;
TRACE("(%p, %08x, %d, %p)\n", hCryptMsg, dwFlags, dwCtrlType,
pvCtrlPara);
DWORD *pdwSignerIndex)
{
HCERTSTORE store;
- DWORD i, signerIndex;
+ DWORD i, signerIndex = 0;
PCCERT_CONTEXT signerCert = NULL;
BOOL ret = FALSE;
cbSignerInfoCountersignature, dwSignerType, pvSigner, dwFlags, pvReserved);
return FALSE;
}
+
+BOOL WINAPI CryptMsgEncodeAndSignCTL(DWORD dwMsgEncodingType,
+ PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
+ BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+ BOOL ret;
+ BYTE *pbCtlContent;
+ DWORD cbCtlContent;
+
+ TRACE("(%08x, %p, %p, %08x, %p, %p)\n", dwMsgEncodingType, pCtlInfo,
+ pSignInfo, dwFlags, pbEncoded, pcbEncoded);
+
+ if (dwFlags)
+ {
+ FIXME("unimplemented for flags %08x\n", dwFlags);
+ return FALSE;
+ }
+ if ((ret = CryptEncodeObjectEx(dwMsgEncodingType, PKCS_CTL, pCtlInfo,
+ CRYPT_ENCODE_ALLOC_FLAG, NULL, &pbCtlContent, &cbCtlContent)))
+ {
+ ret = CryptMsgSignCTL(dwMsgEncodingType, pbCtlContent, cbCtlContent,
+ pSignInfo, dwFlags, pbEncoded, pcbEncoded);
+ LocalFree(pbCtlContent);
+ }
+ return ret;
+}
+
+BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent,
+ DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
+ BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+ static char oid_ctl[] = szOID_CTL;
+ BOOL ret;
+ HCRYPTMSG msg;
+
+ TRACE("(%08x, %p, %d, %p, %08x, %p, %p)\n", dwMsgEncodingType,
+ pbCtlContent, cbCtlContent, pSignInfo, dwFlags, pbEncoded, pcbEncoded);
+
+ if (dwFlags)
+ {
+ FIXME("unimplemented for flags %08x\n", dwFlags);
+ return FALSE;
+ }
+ msg = CryptMsgOpenToEncode(dwMsgEncodingType, 0, CMSG_SIGNED, pSignInfo,
+ oid_ctl, NULL);
+ if (msg)
+ {
+ ret = CryptMsgUpdate(msg, pbCtlContent, cbCtlContent, TRUE);
+ if (ret)
+ ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbEncoded,
+ pcbEncoded);
+ CryptMsgClose(msg);
+ }
+ else
+ ret = FALSE;
+ return ret;
+}