crypt32: Implement CertSaveStore.
This commit is contained in:
parent
0fdb2bc89f
commit
6471621f5e
|
@ -781,12 +781,262 @@ 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)
|
||||
{
|
||||
FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore,
|
||||
BOOL (*saveFunc)(HCERTSTORE, DWORD, void *);
|
||||
void *handle;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %d, %p, %08x)\n", hCertStore,
|
||||
dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
|
||||
return TRUE;
|
||||
|
||||
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) \
|
||||
|
|
Loading…
Reference in New Issue