crypt32: Move CertSaveStore to serialize.c.
This commit is contained in:
parent
9c55a71f8f
commit
f6ebeba5a2
@ -268,18 +268,6 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
|
|||||||
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
|
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
|
||||||
DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
|
DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
|
||||||
|
|
||||||
typedef BOOL (*SerializedOutputFunc)(void *handle, const void *buffer,
|
|
||||||
DWORD size);
|
|
||||||
|
|
||||||
/* Writes contexts from the memory store to the output function, passing handle
|
|
||||||
* as the handle parameter to the output function.
|
|
||||||
*/
|
|
||||||
BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
|
|
||||||
SerializedOutputFunc output, void *handle);
|
|
||||||
|
|
||||||
/* Writes contexts from the memory store to the file. */
|
|
||||||
BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store);
|
|
||||||
|
|
||||||
/* Reads contexts serialized in the file into the memory store. Returns FALSE
|
/* Reads contexts serialized in the file into the memory store. Returns FALSE
|
||||||
* if the file is not of the expected format.
|
* if the file is not of the expected format.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2006 Juan Lang
|
* Copyright 2004-2007 Juan Lang
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -533,6 +533,9 @@ static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext,
|
|||||||
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
|
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef BOOL (*SerializedOutputFunc)(void *handle, const void *buffer,
|
||||||
|
DWORD size);
|
||||||
|
|
||||||
static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
|
static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
|
||||||
void *handle, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
|
void *handle, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
|
||||||
{
|
{
|
||||||
@ -565,7 +568,7 @@ static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
|
static BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
|
||||||
SerializedOutputFunc output, void *handle)
|
SerializedOutputFunc output, void *handle)
|
||||||
{
|
{
|
||||||
static const BYTE fileTrailer[12] = { 0 };
|
static const BYTE fileTrailer[12] = { 0 };
|
||||||
@ -604,13 +607,271 @@ static BOOL CRYPT_FileOutputFunc(void *handle, const void *buffer, DWORD size)
|
|||||||
return WriteFile(handle, buffer, size, &size, NULL);
|
return WriteFile(handle, buffer, size, &size, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store)
|
static BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store)
|
||||||
{
|
{
|
||||||
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||||
return CRYPT_WriteSerializedStoreToStream(store, CRYPT_FileOutputFunc,
|
return CRYPT_WriteSerializedStoreToStream(store, CRYPT_FileOutputFunc,
|
||||||
file);
|
file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
|
||||||
|
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||||
|
{
|
||||||
|
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
||||||
|
CRYPT_SIGNED_INFO signedInfo = { 0 };
|
||||||
|
PCCERT_CONTEXT cert = NULL;
|
||||||
|
PCCRL_CONTEXT crl = NULL;
|
||||||
|
DWORD size;
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
|
TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData);
|
||||||
|
|
||||||
|
do {
|
||||||
|
cert = CertEnumCertificatesInStore(store, cert);
|
||||||
|
if (cert)
|
||||||
|
signedInfo.cCertEncoded++;
|
||||||
|
} while (cert);
|
||||||
|
if (signedInfo.cCertEncoded)
|
||||||
|
{
|
||||||
|
signedInfo.rgCertEncoded = CryptMemAlloc(
|
||||||
|
signedInfo.cCertEncoded * sizeof(CERT_BLOB));
|
||||||
|
if (!signedInfo.rgCertEncoded)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD i = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
cert = CertEnumCertificatesInStore(store, cert);
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
signedInfo.rgCertEncoded[i].cbData = cert->cbCertEncoded;
|
||||||
|
signedInfo.rgCertEncoded[i].pbData = cert->pbCertEncoded;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} while (cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
crl = CertEnumCRLsInStore(store, crl);
|
||||||
|
if (crl)
|
||||||
|
signedInfo.cCrlEncoded++;
|
||||||
|
} while (crl);
|
||||||
|
if (signedInfo.cCrlEncoded)
|
||||||
|
{
|
||||||
|
signedInfo.rgCrlEncoded = CryptMemAlloc(
|
||||||
|
signedInfo.cCrlEncoded * sizeof(CERT_BLOB));
|
||||||
|
if (!signedInfo.rgCrlEncoded)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD i = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
crl = CertEnumCRLsInStore(store, crl);
|
||||||
|
if (crl)
|
||||||
|
{
|
||||||
|
signedInfo.rgCrlEncoded[i].cbData = crl->cbCrlEncoded;
|
||||||
|
signedInfo.rgCrlEncoded[i].pbData = crl->pbCrlEncoded;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} while (crl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, NULL, &size);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (!blob->pbData)
|
||||||
|
blob->cbData = size;
|
||||||
|
else if (blob->cbData < size)
|
||||||
|
{
|
||||||
|
blob->cbData = size;
|
||||||
|
SetLastError(ERROR_MORE_DATA);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blob->cbData = size;
|
||||||
|
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, blob->pbData,
|
||||||
|
&blob->cbData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CryptMemFree(signedInfo.rgCertEncoded);
|
||||||
|
CryptMemFree(signedInfo.rgCrlEncoded);
|
||||||
|
TRACE("returning %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_SavePKCSToFile(HCERTSTORE store,
|
||||||
|
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||||
|
{
|
||||||
|
CERT_BLOB blob = { 0, NULL };
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", handle);
|
||||||
|
|
||||||
|
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
blob.pbData = CryptMemAlloc(blob.cbData);
|
||||||
|
if (blob.pbData)
|
||||||
|
{
|
||||||
|
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
||||||
|
if (ret)
|
||||||
|
ret = WriteFile((HANDLE)handle, blob.pbData, blob.cbData,
|
||||||
|
&blob.cbData, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("returning %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_SaveSerializedToFile(HCERTSTORE store,
|
||||||
|
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||||
|
{
|
||||||
|
return CRYPT_WriteSerializedStoreToFile((HANDLE)handle, store);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MemWrittenTracker
|
||||||
|
{
|
||||||
|
DWORD cbData;
|
||||||
|
BYTE *pbData;
|
||||||
|
DWORD written;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* handle is a pointer to a MemWrittenTracker. Assumes its pointer is valid. */
|
||||||
|
static BOOL CRYPT_MemOutputFunc(void *handle, const void *buffer, DWORD size)
|
||||||
|
{
|
||||||
|
struct MemWrittenTracker *tracker = (struct MemWrittenTracker *)handle;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
if (tracker->written + size > tracker->cbData)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_MORE_DATA);
|
||||||
|
/* Update written so caller can notify its caller of the required size
|
||||||
|
*/
|
||||||
|
tracker->written += size;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(tracker->pbData + tracker->written, buffer, size);
|
||||||
|
tracker->written += size;
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_CountSerializedBytes(void *handle, const void *buffer,
|
||||||
|
DWORD size)
|
||||||
|
{
|
||||||
|
*(DWORD *)handle += size;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CRYPT_SaveSerializedToMem(HCERTSTORE store,
|
||||||
|
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||||
|
{
|
||||||
|
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
||||||
|
DWORD size;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_CountSerializedBytes,
|
||||||
|
&size);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (!blob->pbData)
|
||||||
|
blob->cbData = size;
|
||||||
|
else if (blob->cbData < size)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_MORE_DATA);
|
||||||
|
blob->cbData = size;
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct MemWrittenTracker tracker = { blob->cbData, blob->pbData,
|
||||||
|
0 };
|
||||||
|
|
||||||
|
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_MemOutputFunc,
|
||||||
|
&tracker);
|
||||||
|
if (!ret && GetLastError() == ERROR_MORE_DATA)
|
||||||
|
blob->cbData = tracker.written;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("returning %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
|
||||||
|
DWORD dwSaveAs, DWORD dwSaveTo, void *pvSaveToPara, DWORD dwFlags)
|
||||||
|
{
|
||||||
|
BOOL (*saveFunc)(HCERTSTORE, DWORD, void *);
|
||||||
|
void *handle;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
TRACE("(%p, %08x, %d, %d, %p, %08x)\n", hCertStore,
|
||||||
|
dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
|
||||||
|
|
||||||
|
switch (dwSaveAs)
|
||||||
|
{
|
||||||
|
case CERT_STORE_SAVE_AS_STORE:
|
||||||
|
case CERT_STORE_SAVE_AS_PKCS7:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN("unimplemented for %d\n", dwSaveAs);
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
switch (dwSaveTo)
|
||||||
|
{
|
||||||
|
case CERT_STORE_SAVE_TO_FILE:
|
||||||
|
handle = (HANDLE)pvSaveToPara;
|
||||||
|
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||||
|
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||||
|
break;
|
||||||
|
case CERT_STORE_SAVE_TO_FILENAME_A:
|
||||||
|
handle = CreateFileA((LPCSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
||||||
|
CREATE_ALWAYS, 0, NULL);
|
||||||
|
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||||
|
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||||
|
break;
|
||||||
|
case CERT_STORE_SAVE_TO_FILENAME_W:
|
||||||
|
handle = CreateFileW((LPCWSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
||||||
|
CREATE_ALWAYS, 0, NULL);
|
||||||
|
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||||
|
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||||
|
break;
|
||||||
|
case CERT_STORE_SAVE_TO_MEMORY:
|
||||||
|
handle = pvSaveToPara;
|
||||||
|
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||||
|
CRYPT_SaveSerializedToMem : CRYPT_SavePKCSToMem;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN("unimplemented for %d\n", dwSaveTo);
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ret = saveFunc(hCertStore, dwMsgAndCertEncodingType, handle);
|
||||||
|
TRACE("returning %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
|
BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
|
||||||
const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
|
const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
|
||||||
DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
|
DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
|
||||||
|
@ -781,264 +781,6 @@ HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
|
|||||||
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
|
|
||||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
|
||||||
{
|
|
||||||
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
|
||||||
CRYPT_SIGNED_INFO signedInfo = { 0 };
|
|
||||||
PCCERT_CONTEXT cert = NULL;
|
|
||||||
PCCRL_CONTEXT crl = NULL;
|
|
||||||
DWORD size;
|
|
||||||
BOOL ret = TRUE;
|
|
||||||
|
|
||||||
TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData);
|
|
||||||
|
|
||||||
do {
|
|
||||||
cert = CertEnumCertificatesInStore(store, cert);
|
|
||||||
if (cert)
|
|
||||||
signedInfo.cCertEncoded++;
|
|
||||||
} while (cert);
|
|
||||||
if (signedInfo.cCertEncoded)
|
|
||||||
{
|
|
||||||
signedInfo.rgCertEncoded = CryptMemAlloc(
|
|
||||||
signedInfo.cCertEncoded * sizeof(CERT_BLOB));
|
|
||||||
if (!signedInfo.rgCertEncoded)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DWORD i = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
cert = CertEnumCertificatesInStore(store, cert);
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
signedInfo.rgCertEncoded[i].cbData = cert->cbCertEncoded;
|
|
||||||
signedInfo.rgCertEncoded[i].pbData = cert->pbCertEncoded;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
} while (cert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
crl = CertEnumCRLsInStore(store, crl);
|
|
||||||
if (crl)
|
|
||||||
signedInfo.cCrlEncoded++;
|
|
||||||
} while (crl);
|
|
||||||
if (signedInfo.cCrlEncoded)
|
|
||||||
{
|
|
||||||
signedInfo.rgCrlEncoded = CryptMemAlloc(
|
|
||||||
signedInfo.cCrlEncoded * sizeof(CERT_BLOB));
|
|
||||||
if (!signedInfo.rgCrlEncoded)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DWORD i = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
crl = CertEnumCRLsInStore(store, crl);
|
|
||||||
if (crl)
|
|
||||||
{
|
|
||||||
signedInfo.rgCrlEncoded[i].cbData = crl->cbCrlEncoded;
|
|
||||||
signedInfo.rgCrlEncoded[i].pbData = crl->pbCrlEncoded;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
} while (crl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, NULL, &size);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
if (!blob->pbData)
|
|
||||||
blob->cbData = size;
|
|
||||||
else if (blob->cbData < size)
|
|
||||||
{
|
|
||||||
blob->cbData = size;
|
|
||||||
SetLastError(ERROR_MORE_DATA);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
blob->cbData = size;
|
|
||||||
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, blob->pbData,
|
|
||||||
&blob->cbData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CryptMemFree(signedInfo.rgCertEncoded);
|
|
||||||
CryptMemFree(signedInfo.rgCrlEncoded);
|
|
||||||
TRACE("returning %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL CRYPT_SavePKCSToFile(HCERTSTORE store,
|
|
||||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
|
||||||
{
|
|
||||||
CERT_BLOB blob = { 0, NULL };
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
TRACE("(%p)\n", handle);
|
|
||||||
|
|
||||||
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
blob.pbData = CryptMemAlloc(blob.cbData);
|
|
||||||
if (blob.pbData)
|
|
||||||
{
|
|
||||||
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
|
||||||
if (ret)
|
|
||||||
ret = WriteFile((HANDLE)handle, blob.pbData, blob.cbData,
|
|
||||||
&blob.cbData, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("returning %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL CRYPT_SaveSerializedToFile(HCERTSTORE store,
|
|
||||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
|
||||||
{
|
|
||||||
return CRYPT_WriteSerializedStoreToFile((HANDLE)handle, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MemWrittenTracker
|
|
||||||
{
|
|
||||||
DWORD cbData;
|
|
||||||
BYTE *pbData;
|
|
||||||
DWORD written;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* handle is a pointer to a MemWrittenTracker. Assumes its pointer is valid. */
|
|
||||||
static BOOL CRYPT_MemOutputFunc(void *handle, const void *buffer, DWORD size)
|
|
||||||
{
|
|
||||||
struct MemWrittenTracker *tracker = (struct MemWrittenTracker *)handle;
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
if (tracker->written + size > tracker->cbData)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_MORE_DATA);
|
|
||||||
/* Update written so caller can notify its caller of the required size
|
|
||||||
*/
|
|
||||||
tracker->written += size;
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(tracker->pbData + tracker->written, buffer, size);
|
|
||||||
tracker->written += size;
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL CRYPT_CountSerializedBytes(void *handle, const void *buffer,
|
|
||||||
DWORD size)
|
|
||||||
{
|
|
||||||
*(DWORD *)handle += size;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL CRYPT_SaveSerializedToMem(HCERTSTORE store,
|
|
||||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
|
||||||
{
|
|
||||||
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
|
||||||
DWORD size;
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_CountSerializedBytes,
|
|
||||||
&size);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
if (!blob->pbData)
|
|
||||||
blob->cbData = size;
|
|
||||||
else if (blob->cbData < size)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_MORE_DATA);
|
|
||||||
blob->cbData = size;
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct MemWrittenTracker tracker = { blob->cbData, blob->pbData,
|
|
||||||
0 };
|
|
||||||
|
|
||||||
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_MemOutputFunc,
|
|
||||||
&tracker);
|
|
||||||
if (!ret && GetLastError() == ERROR_MORE_DATA)
|
|
||||||
blob->cbData = tracker.written;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("returning %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
|
|
||||||
DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags)
|
|
||||||
{
|
|
||||||
BOOL (*saveFunc)(HCERTSTORE, DWORD, void *);
|
|
||||||
void *handle;
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
TRACE("(%p, %08x, %d, %d, %p, %08x)\n", hCertStore,
|
|
||||||
dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
|
|
||||||
|
|
||||||
switch (dwSaveAs)
|
|
||||||
{
|
|
||||||
case CERT_STORE_SAVE_AS_STORE:
|
|
||||||
case CERT_STORE_SAVE_AS_PKCS7:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN("unimplemented for %d\n", dwSaveAs);
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
switch (dwSaveTo)
|
|
||||||
{
|
|
||||||
case CERT_STORE_SAVE_TO_FILE:
|
|
||||||
handle = (HANDLE)pvSaveToPara;
|
|
||||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
|
||||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
|
||||||
break;
|
|
||||||
case CERT_STORE_SAVE_TO_FILENAME_A:
|
|
||||||
handle = CreateFileA((LPCSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
|
||||||
CREATE_ALWAYS, 0, NULL);
|
|
||||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
|
||||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
|
||||||
break;
|
|
||||||
case CERT_STORE_SAVE_TO_FILENAME_W:
|
|
||||||
handle = CreateFileW((LPCWSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
|
||||||
CREATE_ALWAYS, 0, NULL);
|
|
||||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
|
||||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
|
||||||
break;
|
|
||||||
case CERT_STORE_SAVE_TO_MEMORY:
|
|
||||||
handle = pvSaveToPara;
|
|
||||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
|
||||||
CRYPT_SaveSerializedToMem : CRYPT_SavePKCSToMem;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN("unimplemented for %d\n", dwSaveTo);
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
ret = saveFunc(hCertStore, dwMsgAndCertEncodingType, handle);
|
|
||||||
TRACE("returning %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CertContext_CopyProperties(to, from) \
|
#define CertContext_CopyProperties(to, from) \
|
||||||
Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
|
Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user