crypt32: Implement CertCreateCTLContext and CertFreeCTLContext.
This commit is contained in:
parent
e6bcb4581f
commit
429b1e1b41
|
@ -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 \
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue