Commit f6ebeba5 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Move CertSaveStore to serialize.c.

parent 9c55a71f
......@@ -268,18 +268,6 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
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
* if the file is not of the expected format.
*/
......
/*
* Copyright 2004-2006 Juan Lang
* Copyright 2004-2007 Juan Lang
*
* This library is free software; you can redistribute it and/or
* 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);
}
typedef BOOL (*SerializedOutputFunc)(void *handle, const void *buffer,
DWORD size);
static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
void *handle, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
{
......@@ -565,7 +568,7 @@ static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
return ret;
}
BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
static BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
SerializedOutputFunc output, void *handle)
{
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);
}
BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store)
static BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store)
{
SetFilePointer(file, 0, NULL, FILE_BEGIN);
return CRYPT_WriteSerializedStoreToStream(store, CRYPT_FileOutputFunc,
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,
const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
......
......@@ -781,264 +781,6 @@ HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
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) \
Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment