Module: wine Branch: master Commit: 2cca297ba657c9ee03a1a7d271a4a0a4b6f599e3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2cca297ba657c9ee03a1a7d271...
Author: Juan Lang juan.lang@gmail.com Date: Fri Jul 13 11:45:03 2007 -0700
crypt32: Partially implement updating decode messages.
---
dlls/crypt32/msg.c | 111 +++++++++++++++++++++++++++++++++++++++++++-- dlls/crypt32/tests/msg.c | 11 ----- 2 files changed, 106 insertions(+), 16 deletions(-)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 78130d2..470bf58 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -607,9 +607,10 @@ HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags,
typedef struct _CDecodeMsg { - CryptMsgBase base; - DWORD type; - HCRYPTPROV crypt_prov; + CryptMsgBase base; + DWORD type; + HCRYPTPROV crypt_prov; + CRYPT_DATA_BLOB msg_data; } CDecodeMsg;
static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg) @@ -618,13 +619,111 @@ static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg)
if (msg->base.open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG) CryptReleaseContext(msg->crypt_prov, 0); + CryptMemFree(msg->msg_data.pbData); +} + +static BOOL CDecodeMsg_CopyData(CDecodeMsg *msg, const BYTE *pbData, + DWORD cbData) +{ + BOOL ret = TRUE; + + if (cbData) + { + if (msg->msg_data.cbData) + msg->msg_data.pbData = CryptMemRealloc(msg->msg_data.pbData, + msg->msg_data.cbData + cbData); + else + msg->msg_data.pbData = CryptMemAlloc(cbData); + if (msg->msg_data.pbData) + { + memcpy(msg->msg_data.pbData + msg->msg_data.cbData, pbData, cbData); + msg->msg_data.cbData += cbData; + } + else + ret = FALSE; + } + 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 + * typed message once the outer content info has been decoded. + */ +static BOOL CDecodeMsg_DecodeContent(CDecodeMsg *msg, CRYPT_DER_BLOB *blob, + DWORD type) +{ + BOOL ret; + + switch (type) + { + case CMSG_DATA: + case CMSG_HASHED: + case CMSG_ENVELOPED: + case CMSG_SIGNED: + FIXME("unimplemented for type %s\n", MSG_TYPE_STR(type)); + ret = TRUE; + break; + default: + { + CRYPT_CONTENT_INFO *info; + DWORD size; + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING, PKCS_CONTENT_INFO, + msg->msg_data.pbData, msg->msg_data.cbData, CRYPT_DECODE_ALLOC_FLAG, + NULL, (LPBYTE)&info, &size); + if (ret) + { + if (!strcmp(info->pszObjId, szOID_RSA_data)) + ret = CDecodeMsg_DecodeContent(msg, &info->Content, CMSG_DATA); + else if (!strcmp(info->pszObjId, szOID_RSA_digestedData)) + ret = CDecodeMsg_DecodeContent(msg, &info->Content, + CMSG_HASHED); + else if (!strcmp(info->pszObjId, szOID_RSA_envelopedData)) + ret = CDecodeMsg_DecodeContent(msg, &info->Content, + CMSG_ENVELOPED); + else if (!strcmp(info->pszObjId, szOID_RSA_signedData)) + ret = CDecodeMsg_DecodeContent(msg, &info->Content, + CMSG_SIGNED); + else + { + SetLastError(CRYPT_E_INVALID_MSG_TYPE); + ret = FALSE; + } + LocalFree(info); + } + } + } + return ret; }
static BOOL CDecodeMsg_Update(HCRYPTMSG hCryptMsg, const BYTE *pbData, DWORD cbData, BOOL fFinal) { - FIXME("(%p, %p, %d, %d): stub\n", hCryptMsg, pbData, cbData, fFinal); - return FALSE; + CDecodeMsg *msg = (CDecodeMsg *)hCryptMsg; + BOOL ret = FALSE; + + TRACE("(%p, %p, %d, %d)\n", hCryptMsg, pbData, cbData, fFinal); + + if (msg->base.streamed) + { + ret = CDecodeMsg_CopyData(msg, pbData, cbData); + FIXME("(%p, %p, %d, %d): streamed update stub\n", hCryptMsg, pbData, + cbData, fFinal); + } + else + { + if (!fFinal) + SetLastError(CRYPT_E_MSG_ERROR); + else + { + ret = CDecodeMsg_CopyData(msg, pbData, cbData); + if (ret) + ret = CDecodeMsg_DecodeContent(msg, &msg->msg_data, msg->type); + + } + } + return ret; }
static BOOL CDecodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, @@ -673,6 +772,8 @@ HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, msg->crypt_prov = CRYPT_GetDefaultProvider(); msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; } + msg->msg_data.cbData = 0; + msg->msg_data.pbData = NULL; } return msg; } diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c index a41a310..17beca1 100644 --- a/dlls/crypt32/tests/msg.c +++ b/dlls/crypt32/tests/msg.c @@ -989,7 +989,6 @@ static void test_decode_msg_update(void) msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); /* Update with a full message in a final update */ ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); - todo_wine ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); /* Can't update after a final update */ SetLastError(0xdeadbeef); @@ -1003,12 +1002,10 @@ static void test_decode_msg_update(void) SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), FALSE); - todo_wine ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR, "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError()); /* A subsequent final update succeeds */ ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); - todo_wine ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); CryptMsgClose(msg);
@@ -1035,7 +1032,6 @@ static void test_decode_msg_update(void) /* Empty non-final updates are allowed when streaming.. */ msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); ret = CryptMsgUpdate(msg, NULL, 0, FALSE); - todo_wine ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); /* but final updates aren't when not enough data has been received. */ SetLastError(0xdeadbeef); @@ -1051,11 +1047,9 @@ static void test_decode_msg_update(void) msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo); for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++) ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE); - todo_wine { ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError()); ret = CryptMsgUpdate(msg, NULL, 0, TRUE); ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError()); - } CryptMsgClose(msg); todo_wine check_updates("byte-by-byte empty content", &a4, &accum); @@ -1065,7 +1059,6 @@ static void test_decode_msg_update(void) msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); - todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG, "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError()); CryptMsgClose(msg); @@ -1092,7 +1085,6 @@ static void test_decode_msg_update(void) msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE); - todo_wine ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); /* but decoding it as an explicitly typed message fails. */ msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, @@ -1111,7 +1103,6 @@ static void test_decode_msg_update(void) SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, dataEmptyBareContent, sizeof(dataEmptyBareContent), TRUE); - todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG, "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError()); CryptMsgClose(msg); @@ -1120,7 +1111,6 @@ static void test_decode_msg_update(void) NULL); ret = CryptMsgUpdate(msg, dataEmptyBareContent, sizeof(dataEmptyBareContent), TRUE); - todo_wine ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError()); CryptMsgClose(msg);
@@ -1128,7 +1118,6 @@ static void test_decode_msg_update(void) msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL); SetLastError(0xdeadbeef); ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE); - todo_wine ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE, "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError()); CryptMsgClose(msg);