Juan Lang : crypt32: Implement CertCreateCTLContext and CertFreeCTLContext.

Alexandre Julliard julliard at winehq.org
Tue Sep 2 08:32:47 CDT 2008


Module: wine
Branch: master
Commit: 429b1e1b41f0d5b849c7ddc2c20712d53e47c8dc
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=429b1e1b41f0d5b849c7ddc2c20712d53e47c8dc

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Aug 29 07:29:00 2008 -0700

crypt32: Implement CertCreateCTLContext and CertFreeCTLContext.

---

 dlls/crypt32/Makefile.in |    1 +
 dlls/crypt32/ctl.c       |  177 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/crypt32/store.c     |   14 ----
 dlls/crypt32/tests/ctl.c |    8 --
 4 files changed, 178 insertions(+), 22 deletions(-)

diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index 16fbd5e..10ffda9 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -14,6 +14,7 @@ C_SRCS = \
 	collectionstore.c \
 	context.c \
 	crl.c \
+	ctl.c \
 	decode.c \
 	encode.c \
 	filestore.c \
diff --git a/dlls/crypt32/ctl.c b/dlls/crypt32/ctl.c
new file mode 100644
index 0000000..728d008
--- /dev/null
+++ b/dlls/crypt32/ctl.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2008 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+#include "wine/debug.h"
+#include "crypt32_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+
+PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
+ const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
+{
+    PCTL_CONTEXT ctl = NULL;
+    HCRYPTMSG msg;
+    BOOL ret;
+    BYTE *content = NULL;
+    DWORD contentSize = 0, size;
+    PCTL_INFO ctlInfo = NULL;
+
+    TRACE("(%08x, %p, %d)\n", dwMsgAndCertEncodingType, pbCtlEncoded,
+     cbCtlEncoded);
+
+    if (GET_CERT_ENCODING_TYPE(dwMsgAndCertEncodingType) != X509_ASN_ENCODING)
+    {
+        SetLastError(E_INVALIDARG);
+        return NULL;
+    }
+    if (!pbCtlEncoded || !cbCtlEncoded)
+    {
+        SetLastError(ERROR_INVALID_DATA);
+        return NULL;
+    }
+    msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0,
+     0, NULL, NULL);
+    if (!msg)
+        return NULL;
+    ret = CryptMsgUpdate(msg, pbCtlEncoded, cbCtlEncoded, TRUE);
+    if (!ret)
+    {
+        SetLastError(ERROR_INVALID_DATA);
+        goto end;
+    }
+    /* Check that it's really a CTL */
+    ret = CryptMsgGetParam(msg, CMSG_INNER_CONTENT_TYPE_PARAM, 0, NULL, &size);
+    if (ret)
+    {
+        char *innerContent = CryptMemAlloc(size);
+
+        if (innerContent)
+        {
+            ret = CryptMsgGetParam(msg, CMSG_INNER_CONTENT_TYPE_PARAM, 0,
+             innerContent, &size);
+            if (ret)
+            {
+                if (strcmp(innerContent, szOID_CTL))
+                {
+                    SetLastError(ERROR_INVALID_DATA);
+                    ret = FALSE;
+                }
+            }
+            CryptMemFree(innerContent);
+        }
+        else
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            ret = FALSE;
+        }
+    }
+    if (!ret)
+        goto end;
+    ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &contentSize);
+    if (!ret)
+        goto end;
+    content = CryptMemAlloc(contentSize);
+    if (content)
+    {
+        ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, content,
+         &contentSize);
+        if (ret)
+        {
+            ret = CryptDecodeObjectEx(dwMsgAndCertEncodingType, PKCS_CTL,
+             content, contentSize, CRYPT_DECODE_ALLOC_FLAG, NULL,
+             (BYTE *)&ctlInfo, &size);
+            if (ret)
+            {
+                ctl = (PCTL_CONTEXT)Context_CreateDataContext(
+                 sizeof(CTL_CONTEXT));
+                if (ctl)
+                {
+                    BYTE *data = CryptMemAlloc(cbCtlEncoded);
+
+                    if (data)
+                    {
+                        memcpy(data, pbCtlEncoded, cbCtlEncoded);
+                        ctl->dwMsgAndCertEncodingType =
+                         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+                        ctl->pbCtlEncoded             = data;
+                        ctl->cbCtlEncoded             = cbCtlEncoded;
+                        ctl->pCtlInfo                 = ctlInfo;
+                        ctl->hCertStore               = NULL;
+                        ctl->hCryptMsg                = msg;
+                        ctl->pbCtlContext             = content;
+                        ctl->cbCtlContext             = contentSize;
+                    }
+                    else
+                    {
+                        SetLastError(ERROR_OUTOFMEMORY);
+                        ret = FALSE;
+                    }
+                }
+                else
+                {
+                    SetLastError(ERROR_OUTOFMEMORY);
+                    ret = FALSE;
+                }
+            }
+        }
+    }
+    else
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        ret = FALSE;
+    }
+
+end:
+    if (!ret)
+    {
+        CryptMemFree(ctl);
+        ctl = NULL;
+        LocalFree(ctlInfo);
+        CryptMemFree(content);
+        CryptMsgClose(msg);
+    }
+    return (PCCTL_CONTEXT)ctl;
+}
+
+static void CTLDataContext_Free(void *context)
+{
+    PCTL_CONTEXT ctlContext = (PCTL_CONTEXT)context;
+
+    CryptMsgClose(ctlContext->hCryptMsg);
+    CryptMemFree(ctlContext->pbCtlEncoded);
+    CryptMemFree(ctlContext->pbCtlContext);
+    LocalFree(ctlContext->pCtlInfo);
+}
+
+BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
+{
+    TRACE("(%p)\n", pCTLContext);
+
+    if (pCTLContext)
+        Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
+         CTLDataContext_Free);
+    return TRUE;
+}
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index 9534e5c..9ce6be4 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -1043,14 +1043,6 @@ PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
     return ret;
 }
 
-PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
-  const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
-{
-    FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
-     cbCtlEncoded);
-    return NULL;
-}
-
 BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
  DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
  DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
@@ -1076,12 +1068,6 @@ PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
     return pCtlContext;
 }
 
-BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
-{
-    FIXME("(%p): stub\n", pCtlContext );
-    return TRUE;
-}
-
 BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
 {
     FIXME("(%p): stub\n", pCtlContext);
diff --git a/dlls/crypt32/tests/ctl.c b/dlls/crypt32/tests/ctl.c
index 215c057..9d4eee4 100644
--- a/dlls/crypt32/tests/ctl.c
+++ b/dlls/crypt32/tests/ctl.c
@@ -113,19 +113,16 @@ static void testCreateCTL(void)
 
     SetLastError(0xdeadbeef);
     ctl = CertCreateCTLContext(0, NULL, 0);
-    todo_wine
     ok(!ctl && GetLastError() == E_INVALIDARG,
      "expected E_INVALIDARG, got %08x\n", GetLastError());
     SetLastError(0xdeadbeef);
     ctl = CertCreateCTLContext(X509_ASN_ENCODING, NULL, 0);
-    todo_wine
     ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
      "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
      GetLastError());
     /* An empty CTL can't be created.. */
     SetLastError(0xdeadbeef);
     ctl = CertCreateCTLContext(X509_ASN_ENCODING, emptyCTL, sizeof(emptyCTL));
-    todo_wine
     ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
      "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
      GetLastError());
@@ -134,21 +131,18 @@ static void testCreateCTL(void)
      */
     SetLastError(0xdeadbeef);
     ctl = CertCreateCTLContext(X509_ASN_ENCODING, signedCTL, sizeof(signedCTL));
-    todo_wine
     ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
      "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
      GetLastError());
     SetLastError(0xdeadbeef);
     ctl = CertCreateCTLContext(X509_ASN_ENCODING, ctlWithOneEntry,
      sizeof(ctlWithOneEntry));
-    todo_wine
     ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
      "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
      GetLastError());
     SetLastError(0xdeadbeef);
     ctl = CertCreateCTLContext(X509_ASN_ENCODING,
      signedCTLWithSubjectAlgorithm, sizeof(signedCTLWithSubjectAlgorithm));
-    todo_wine
     ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
      "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
      GetLastError());
@@ -156,7 +150,6 @@ static void testCreateCTL(void)
      */
     ctl = CertCreateCTLContext(X509_ASN_ENCODING,
      signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent));
-    todo_wine
     ok(ctl != NULL, "CertCreateCTLContext failed: %08x\n", GetLastError());
     if (ctl)
     {
@@ -175,7 +168,6 @@ static void testCreateCTL(void)
     ctl = CertCreateCTLContext(X509_ASN_ENCODING,
      signedCTLWithCTLInnerContentAndBadSig,
      sizeof(signedCTLWithCTLInnerContentAndBadSig));
-    todo_wine
     ok(ctl != NULL, "CertCreateCTLContext failed: %08x\n", GetLastError());
     if (ctl)
         CertFreeCTLContext(ctl);




More information about the wine-cvs mailing list