crypt32(13/17): Implement CryptMsgUpdate for data messages opened to encode

Juan Lang juan.lang at gmail.com
Thu Jun 28 19:32:24 CDT 2007


--Juan
-------------- next part --------------
From 4919b1b2e231ea41ba9f6e0f26fd6e1124ae3ea7 Mon Sep 17 00:00:00 2001
From: Juan Lang <juanlang at juan.corp.google.com>
Date: Thu, 28 Jun 2007 17:14:02 -0700
Subject: [PATCH] Implement CryptMsgUpdate for data messages opened to encode
---
 dlls/crypt32/msg.c       |   53 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/crypt32/tests/msg.c |    8 -------
 2 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index 1dbca4f..016a108 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -59,8 +59,57 @@ static inline void CryptMsgBase_Init(Cry
 typedef struct _CDataEncodeMsg
 {
     CryptMsgBase base;
+    DWORD        bare_content_len;
+    LPBYTE       bare_content;
 } CDataEncodeMsg;
 
+static const BYTE empty_data_content[] = { 0x04,0x00 };
+
+static void CDataEncodeMsg_Close(HCRYPTMSG hCryptMsg)
+{
+    CDataEncodeMsg *msg = (CDataEncodeMsg *)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;
+    BOOL ret = FALSE;
+
+    if (msg->base.finalized)
+        SetLastError(CRYPT_E_MSG_ERROR);
+    else if (!fFinal)
+    {
+        if (msg->base.open_flags & CMSG_DETACHED_FLAG)
+            SetLastError(E_INVALIDARG);
+        else
+            SetLastError(CRYPT_E_MSG_ERROR);
+    }
+    else
+    {
+        msg->base.finalized = TRUE;
+        if (!cbData)
+            SetLastError(E_INVALIDARG);
+        else
+        {
+            CRYPT_DATA_BLOB blob = { cbData, (LPBYTE)pbData };
+
+            /* data messages don't allow non-final updates, don't bother
+             * checking whether data already exist, they can't.
+             */
+            ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_OCTET_STRING,
+             &blob, CRYPT_ENCODE_ALLOC_FLAG, NULL, &msg->bare_content,
+             &msg->bare_content_len);
+            if (ret && msg->base.stream_info)
+                FIXME("stream info unimplemented\n");
+        }
+    }
+    return ret;
+}
+
 static HCRYPTMSG CDataEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo,
  LPSTR pszInnerContentObjID, PCMSG_STREAM_INFO pStreamInfo)
 {
@@ -76,6 +125,10 @@ static HCRYPTMSG CDataEncodeMsg_Open(DWO
     if (msg)
     {
         CryptMsgBase_Init((CryptMsgBase *)msg, dwFlags, pStreamInfo);
+        msg->base.close = CDataEncodeMsg_Close;
+        msg->base.update = CDataEncodeMsg_Update;
+        msg->bare_content_len = sizeof(empty_data_content);
+        msg->bare_content = (LPBYTE)empty_data_content;
     }
     return (HCRYPTMSG)msg;
 }
diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c
index df5e83f..03d0abf 100644
--- a/dlls/crypt32/tests/msg.c
+++ b/dlls/crypt32/tests/msg.c
@@ -309,17 +309,14 @@ static void test_data_msg_update(void)
     /* Can't update a message that wasn't opened detached with final = FALSE */
     SetLastError(0xdeadbeef);
     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
-    todo_wine
     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
     /* Updating it with final = TRUE succeeds */
     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
-    todo_wine
     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
     /* Any subsequent update will fail, as the last was final */
     SetLastError(0xdeadbeef);
     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
-    todo_wine
     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
     CryptMsgClose(msg);
@@ -329,7 +326,6 @@ static void test_data_msg_update(void)
     /* Can't update a message with no data */
     SetLastError(0xdeadbeef);
     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
-    todo_wine {
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %x\n", GetLastError());
     /* Curiously, a valid update will now fail as well, presumably because of
@@ -338,7 +334,6 @@ static void test_data_msg_update(void)
     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
-    }
     CryptMsgClose(msg);
 
     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
@@ -346,16 +341,13 @@ static void test_data_msg_update(void)
     /* Dont appear to be able to update CMSG-DATA with non-final updates */
     SetLastError(0xdeadbeef);
     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %x\n", GetLastError());
     SetLastError(0xdeadbeef);
     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %x\n", GetLastError());
     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
-    todo_wine
     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
     CryptMsgClose(msg);
 }
-- 
1.4.1


More information about the wine-patches mailing list