crypt32: Implement CertCreateCTLContext and CertFreeCTLContext.

This commit is contained in:
Juan Lang 2008-08-29 07:29:00 -07:00 committed by Alexandre Julliard
parent e6bcb4581f
commit 429b1e1b41
4 changed files with 178 additions and 22 deletions

View File

@ -14,6 +14,7 @@ C_SRCS = \
collectionstore.c \ collectionstore.c \
context.c \ context.c \
crl.c \ crl.c \
ctl.c \
decode.c \ decode.c \
encode.c \ encode.c \
filestore.c \ filestore.c \

177
dlls/crypt32/ctl.c Normal file
View File

@ -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;
}

View File

@ -1043,14 +1043,6 @@ PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
return ret; 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, BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext) DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
@ -1076,12 +1068,6 @@ PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
return pCtlContext; return pCtlContext;
} }
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
{
FIXME("(%p): stub\n", pCtlContext );
return TRUE;
}
BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext) BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
{ {
FIXME("(%p): stub\n", pCtlContext); FIXME("(%p): stub\n", pCtlContext);

View File

@ -113,19 +113,16 @@ static void testCreateCTL(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ctl = CertCreateCTLContext(0, NULL, 0); ctl = CertCreateCTLContext(0, NULL, 0);
todo_wine
ok(!ctl && GetLastError() == E_INVALIDARG, ok(!ctl && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError()); "expected E_INVALIDARG, got %08x\n", GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ctl = CertCreateCTLContext(X509_ASN_ENCODING, NULL, 0); ctl = CertCreateCTLContext(X509_ASN_ENCODING, NULL, 0);
todo_wine
ok(!ctl && GetLastError() == ERROR_INVALID_DATA, ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
"expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(), "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
GetLastError()); GetLastError());
/* An empty CTL can't be created.. */ /* An empty CTL can't be created.. */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ctl = CertCreateCTLContext(X509_ASN_ENCODING, emptyCTL, sizeof(emptyCTL)); ctl = CertCreateCTLContext(X509_ASN_ENCODING, emptyCTL, sizeof(emptyCTL));
todo_wine
ok(!ctl && GetLastError() == ERROR_INVALID_DATA, ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
"expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(), "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
GetLastError()); GetLastError());
@ -134,21 +131,18 @@ static void testCreateCTL(void)
*/ */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ctl = CertCreateCTLContext(X509_ASN_ENCODING, signedCTL, sizeof(signedCTL)); ctl = CertCreateCTLContext(X509_ASN_ENCODING, signedCTL, sizeof(signedCTL));
todo_wine
ok(!ctl && GetLastError() == ERROR_INVALID_DATA, ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
"expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(), "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
GetLastError()); GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ctl = CertCreateCTLContext(X509_ASN_ENCODING, ctlWithOneEntry, ctl = CertCreateCTLContext(X509_ASN_ENCODING, ctlWithOneEntry,
sizeof(ctlWithOneEntry)); sizeof(ctlWithOneEntry));
todo_wine
ok(!ctl && GetLastError() == ERROR_INVALID_DATA, ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
"expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(), "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
GetLastError()); GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ctl = CertCreateCTLContext(X509_ASN_ENCODING, ctl = CertCreateCTLContext(X509_ASN_ENCODING,
signedCTLWithSubjectAlgorithm, sizeof(signedCTLWithSubjectAlgorithm)); signedCTLWithSubjectAlgorithm, sizeof(signedCTLWithSubjectAlgorithm));
todo_wine
ok(!ctl && GetLastError() == ERROR_INVALID_DATA, ok(!ctl && GetLastError() == ERROR_INVALID_DATA,
"expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(), "expected ERROR_INVALID_DATA, got %d (0x%08x)\n", GetLastError(),
GetLastError()); GetLastError());
@ -156,7 +150,6 @@ static void testCreateCTL(void)
*/ */
ctl = CertCreateCTLContext(X509_ASN_ENCODING, ctl = CertCreateCTLContext(X509_ASN_ENCODING,
signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent)); signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent));
todo_wine
ok(ctl != NULL, "CertCreateCTLContext failed: %08x\n", GetLastError()); ok(ctl != NULL, "CertCreateCTLContext failed: %08x\n", GetLastError());
if (ctl) if (ctl)
{ {
@ -175,7 +168,6 @@ static void testCreateCTL(void)
ctl = CertCreateCTLContext(X509_ASN_ENCODING, ctl = CertCreateCTLContext(X509_ASN_ENCODING,
signedCTLWithCTLInnerContentAndBadSig, signedCTLWithCTLInnerContentAndBadSig,
sizeof(signedCTLWithCTLInnerContentAndBadSig)); sizeof(signedCTLWithCTLInnerContentAndBadSig));
todo_wine
ok(ctl != NULL, "CertCreateCTLContext failed: %08x\n", GetLastError()); ok(ctl != NULL, "CertCreateCTLContext failed: %08x\n", GetLastError());
if (ctl) if (ctl)
CertFreeCTLContext(ctl); CertFreeCTLContext(ctl);