📄 serialize.c
字号:
if (hdr)
type = CERT_STORE_CTL_CONTEXT;
}
}
}
else if (dwContextTypeFlags & CERT_STORE_CERTIFICATE_CONTEXT_FLAG)
{
hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CERT_PROP_ID);
type = CERT_STORE_CERTIFICATE_CONTEXT;
}
else if (dwContextTypeFlags & CERT_STORE_CRL_CONTEXT_FLAG)
{
hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CRL_PROP_ID);
type = CERT_STORE_CRL_CONTEXT;
}
else if (dwContextTypeFlags & CERT_STORE_CTL_CONTEXT_FLAG)
{
hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CTL_PROP_ID);
type = CERT_STORE_CTL_CONTEXT;
}
switch (type)
{
case CERT_STORE_CERTIFICATE_CONTEXT:
contextInterface = pCertInterface;
break;
case CERT_STORE_CRL_CONTEXT:
contextInterface = pCRLInterface;
break;
case CERT_STORE_CTL_CONTEXT:
contextInterface = pCTLInterface;
break;
default:
SetLastError(E_INVALIDARG);
ret = FALSE;
}
if (!hdr)
ret = FALSE;
if (ret)
context = contextInterface->create(X509_ASN_ENCODING,
(BYTE *)hdr + sizeof(WINE_CERT_PROP_HEADER), hdr->cb);
if (ret && context)
{
BOOL noMoreProps = FALSE;
while (!noMoreProps && ret)
{
if (cbElement < sizeof(WINE_CERT_PROP_HEADER))
ret = FALSE;
else
{
const WINE_CERT_PROP_HEADER *hdr =
(const WINE_CERT_PROP_HEADER *)pbElement;
TRACE("prop is %d\n", hdr->propID);
cbElement -= sizeof(WINE_CERT_PROP_HEADER);
pbElement += sizeof(WINE_CERT_PROP_HEADER);
if (!hdr->propID)
{
/* Like in CRYPT_findPropID, stop if the propID is zero
*/
noMoreProps = TRUE;
}
else
ret = CRYPT_ReadContextProp(contextInterface, context,
hdr, pbElement, cbElement);
pbElement += hdr->cb;
cbElement -= hdr->cb;
if (!cbElement)
noMoreProps = TRUE;
}
}
if (ret)
{
if (pdwContentType)
*pdwContentType = type;
}
else
{
contextInterface->free(context);
context = NULL;
}
}
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
context = NULL;
}
__ENDTRY
return context;
}
static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' };
BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
{
BYTE fileHeaderBuf[sizeof(fileHeader)];
DWORD read;
BOOL ret;
/* Failure reading is non-critical, we'll leave the store empty */
ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL);
if (ret)
{
if (!memcmp(fileHeaderBuf, fileHeader, read))
{
WINE_CERT_PROP_HEADER propHdr;
const void *context = NULL;
const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
LPBYTE buf = NULL;
DWORD bufSize = 0;
do {
ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL);
if (ret && read == sizeof(propHdr))
{
if (contextInterface && context &&
(propHdr.propID == CERT_CERT_PROP_ID ||
propHdr.propID == CERT_CRL_PROP_ID ||
propHdr.propID == CERT_CTL_PROP_ID))
{
/* We have a new context, so free the existing one */
contextInterface->free(context);
}
if (propHdr.cb > bufSize)
{
/* Not reusing realloc, because the old data aren't
* needed any longer.
*/
CryptMemFree(buf);
buf = CryptMemAlloc(propHdr.cb);
bufSize = propHdr.cb;
}
if (buf)
{
ret = ReadFile(file, buf, propHdr.cb, &read, NULL);
if (ret && read == propHdr.cb)
{
if (propHdr.propID == CERT_CERT_PROP_ID)
{
contextInterface = pCertInterface;
ret = contextInterface->addEncodedToStore(store,
X509_ASN_ENCODING, buf, read,
CERT_STORE_ADD_NEW, &context);
}
else if (propHdr.propID == CERT_CRL_PROP_ID)
{
contextInterface = pCRLInterface;
ret = contextInterface->addEncodedToStore(store,
X509_ASN_ENCODING, buf, read,
CERT_STORE_ADD_NEW, &context);
}
else if (propHdr.propID == CERT_CTL_PROP_ID)
{
contextInterface = pCTLInterface;
ret = contextInterface->addEncodedToStore(store,
X509_ASN_ENCODING, buf, read,
CERT_STORE_ADD_NEW, &context);
}
else
ret = CRYPT_ReadContextProp(contextInterface,
context, &propHdr, buf, read);
}
}
else
ret = FALSE;
}
} while (ret && read > 0);
if (contextInterface && context)
{
/* Free the last context added */
contextInterface->free(context);
}
CryptMemFree(buf);
ret = TRUE;
}
}
else
ret = TRUE;
return ret;
}
static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
return CRYPT_SerializeStoreElement(pCertContext,
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded,
CERT_CERT_PROP_ID, pCertInterface, dwFlags, TRUE, pbElement, pcbElement);
}
static BOOL WINAPI CRYPT_SerializeCRLNoHash(PCCRL_CONTEXT pCrlContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
return CRYPT_SerializeStoreElement(pCrlContext,
pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded,
CERT_CRL_PROP_ID, pCRLInterface, dwFlags, TRUE, pbElement, pcbElement);
}
static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext,
DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
return CRYPT_SerializeStoreElement(pCtlContext,
pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded,
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
}
static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
{
const void *context = NULL;
BOOL ret;
do {
context = contextInterface->enumContextsInStore(store, context);
if (context)
{
DWORD size = 0;
LPBYTE buf = NULL;
ret = contextInterface->serialize(context, 0, NULL, &size);
if (size)
buf = CryptMemAlloc(size);
if (buf)
{
ret = contextInterface->serialize(context, 0, buf, &size);
if (ret)
ret = WriteFile(file, buf, size, &size, NULL);
}
CryptMemFree(buf);
}
else
ret = TRUE;
} while (ret && context != NULL);
if (context)
contextInterface->free(context);
return ret;
}
BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store)
{
static const BYTE fileTrailer[12] = { 0 };
WINE_CONTEXT_INTERFACE interface;
BOOL ret;
DWORD size;
SetFilePointer(file, 0, NULL, FILE_BEGIN);
ret = WriteFile(file, fileHeader, sizeof(fileHeader), &size, NULL);
if (ret)
{
memcpy(&interface, pCertInterface, sizeof(interface));
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCertNoHash;
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
}
if (ret)
{
memcpy(&interface, pCRLInterface, sizeof(interface));
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCRLNoHash;
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
}
if (ret)
{
memcpy(&interface, pCTLInterface, sizeof(interface));
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCTLNoHash;
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
}
if (ret)
ret = WriteFile(file, fileTrailer, sizeof(fileTrailer), &size, NULL);
return ret;
}
BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
{
const void *context;
DWORD type;
BOOL ret;
TRACE("(%p, %p, %d, %08x, %08x, %08x, %p, %p)\n", hCertStore,
pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags,
pdwContentType, ppvContext);
/* Call the internal function, then delete the hashes. Tests show this
* function uses real hash values, not whatever's stored in the hash
* property.
*/
context = CRYPT_ReadSerializedElement(pbElement, cbElement,
dwContextTypeFlags, &type);
if (context)
{
const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
switch (type)
{
case CERT_STORE_CERTIFICATE_CONTEXT:
contextInterface = pCertInterface;
break;
case CERT_STORE_CRL_CONTEXT:
contextInterface = pCRLInterface;
break;
case CERT_STORE_CTL_CONTEXT:
contextInterface = pCTLInterface;
break;
default:
SetLastError(E_INVALIDARG);
}
if (contextInterface)
{
contextInterface->setProp(context, CERT_HASH_PROP_ID, 0, NULL);
contextInterface->setProp(context, CERT_MD5_HASH_PROP_ID, 0, NULL);
contextInterface->setProp(context, CERT_SIGNATURE_HASH_PROP_ID, 0,
NULL);
if (pdwContentType)
*pdwContentType = type;
ret = contextInterface->addContextToStore(hCertStore, context,
dwAddDisposition, ppvContext);
contextInterface->free(context);
}
else
ret = FALSE;
}
else
ret = FALSE;
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -