crypt32: Change finalized from a boolean to a state and use it to simplify message updating.

This commit is contained in:
Juan Lang 2007-07-12 15:05:02 -07:00 committed by Alexandre Julliard
parent 9bdb084eb6
commit 09c4faf159
2 changed files with 39 additions and 38 deletions

View File

@ -38,13 +38,18 @@ typedef BOOL (*CryptMsgGetParamFunc)(HCRYPTMSG hCryptMsg, DWORD dwParamType,
typedef BOOL (*CryptMsgUpdateFunc)(HCRYPTMSG hCryptMsg, const BYTE *pbData, typedef BOOL (*CryptMsgUpdateFunc)(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal); DWORD cbData, BOOL fFinal);
typedef enum _CryptMsgState {
MsgStateInit,
MsgStateFinalized
} CryptMsgState;
typedef struct _CryptMsgBase typedef struct _CryptMsgBase
{ {
LONG ref; LONG ref;
DWORD open_flags; DWORD open_flags;
BOOL streamed; BOOL streamed;
CMSG_STREAM_INFO stream_info; CMSG_STREAM_INFO stream_info;
BOOL finalized; CryptMsgState state;
CryptMsgCloseFunc close; CryptMsgCloseFunc close;
CryptMsgUpdateFunc update; CryptMsgUpdateFunc update;
CryptMsgGetParamFunc get_param; CryptMsgGetParamFunc get_param;
@ -69,7 +74,7 @@ static inline void CryptMsgBase_Init(CryptMsgBase *msg, DWORD dwFlags,
msg->close = close; msg->close = close;
msg->get_param = get_param; msg->get_param = get_param;
msg->update = update; msg->update = update;
msg->finalized = FALSE; msg->state = MsgStateInit;
} }
typedef struct _CDataEncodeMsg typedef struct _CDataEncodeMsg
@ -161,12 +166,8 @@ static BOOL CDataEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg; CDataEncodeMsg *msg = (CDataEncodeMsg *)hCryptMsg;
BOOL ret = FALSE; BOOL ret = FALSE;
if (msg->base.finalized) if (msg->base.streamed)
SetLastError(CRYPT_E_MSG_ERROR);
else if (msg->base.streamed)
{ {
if (fFinal)
msg->base.finalized = TRUE;
__TRY __TRY
{ {
if (!msg->begun) if (!msg->begun)
@ -223,7 +224,6 @@ static BOOL CDataEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
} }
else else
{ {
msg->base.finalized = TRUE;
if (!cbData) if (!cbData)
SetLastError(E_INVALIDARG); SetLastError(E_INVALIDARG);
else else
@ -380,7 +380,7 @@ static BOOL CRYPT_EncodePKCSDigestedData(CHashEncodeMsg *msg, void *pvData,
items[cItem].encodeFunc = items[cItem].encodeFunc =
CRYPT_AsnEncodePKCSContentInfoInternal; CRYPT_AsnEncodePKCSContentInfoInternal;
cItem++; cItem++;
if (msg->base.finalized) if (msg->base.state == MsgStateFinalized)
{ {
size = sizeof(DWORD); size = sizeof(DWORD);
ret = CryptGetHashParam(msg->hash, HP_HASHSIZE, ret = CryptGetHashParam(msg->hash, HP_HASHSIZE,
@ -454,7 +454,7 @@ static BOOL CHashEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
0); 0);
break; break;
case CMSG_VERSION_PARAM: case CMSG_VERSION_PARAM:
if (!msg->base.finalized) if (msg->base.state != MsgStateFinalized)
SetLastError(CRYPT_E_MSG_ERROR); SetLastError(CRYPT_E_MSG_ERROR);
else else
{ {
@ -479,39 +479,31 @@ static BOOL CHashEncodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData,
TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal); TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
if (msg->base.finalized) msg->begun = TRUE;
SetLastError(CRYPT_E_MSG_ERROR); if (msg->base.streamed || (msg->base.open_flags & CMSG_DETACHED_FLAG))
{
/* Doesn't do much, as stream output is never called, and you
* can't get the content.
*/
ret = CryptHashData(msg->hash, pbData, cbData, 0);
}
else else
{ {
msg->begun = TRUE; if (!fFinal)
if (fFinal) SetLastError(CRYPT_E_MSG_ERROR);
msg->base.finalized = TRUE;
if (msg->base.streamed || (msg->base.open_flags & CMSG_DETACHED_FLAG))
{
/* Doesn't do much, as stream output is never called, and you
* can't get the content.
*/
ret = CryptHashData(msg->hash, pbData, cbData, 0);
}
else else
{ {
if (!fFinal) ret = CryptHashData(msg->hash, pbData, cbData, 0);
SetLastError(CRYPT_E_MSG_ERROR); if (ret)
else
{ {
ret = CryptHashData(msg->hash, pbData, cbData, 0); msg->data.pbData = CryptMemAlloc(cbData);
if (ret) if (msg->data.pbData)
{ {
msg->data.pbData = CryptMemAlloc(cbData); memcpy(msg->data.pbData + msg->data.cbData, pbData, cbData);
if (msg->data.pbData) msg->data.cbData += cbData;
{
memcpy(msg->data.pbData + msg->data.cbData, pbData,
cbData);
msg->data.cbData += cbData;
}
else
ret = FALSE;
} }
else
ret = FALSE;
} }
} }
} }
@ -717,9 +709,19 @@ BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData,
DWORD cbData, BOOL fFinal) DWORD cbData, BOOL fFinal)
{ {
CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg; CryptMsgBase *msg = (CryptMsgBase *)hCryptMsg;
BOOL ret = FALSE;
TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal); TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal);
return msg->update(hCryptMsg, pbData, cbData, fFinal);
if (msg->state == MsgStateFinalized)
SetLastError(CRYPT_E_MSG_ERROR);
else
{
ret = msg->update(hCryptMsg, pbData, cbData, fFinal);
if (fFinal)
msg->state = MsgStateFinalized;
}
return ret;
} }
BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,

View File

@ -994,7 +994,6 @@ static void test_decode_msg_update(void)
/* Can't update after a final update */ /* Can't update after a final update */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
todo_wine
ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
"Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
CryptMsgClose(msg); CryptMsgClose(msg);