crypt32: Copy the CRL_INFO structure instead of recalculating it.
Steam calls CertGetCertificateChain() on a certificate with a 20 MB CRL, which can take over 400 ms to parse each time. Avoid parsing it more often than we need to. Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1c501c6587
commit
bdcddf024f
|
@ -38,6 +38,108 @@ static void CRL_free(context_t *context)
|
|||
|
||||
static const context_vtbl_t crl_vtbl;
|
||||
|
||||
static char *copy_string(char *p, char **dst, const char *src)
|
||||
{
|
||||
size_t size = strlen(src) + 1;
|
||||
|
||||
*dst = memcpy(p, src, size);
|
||||
return p + size;
|
||||
}
|
||||
|
||||
static char *copy_blob(char *p, DATA_BLOB *dst, const DATA_BLOB *src)
|
||||
{
|
||||
size_t size = src->cbData;
|
||||
|
||||
dst->cbData = size;
|
||||
dst->pbData = memcpy(p, src->pbData, size);
|
||||
return p + size;
|
||||
}
|
||||
|
||||
static char *copy_extension(char *p, CERT_EXTENSION *dst, const CERT_EXTENSION *src)
|
||||
{
|
||||
p = copy_string(p, &dst->pszObjId, src->pszObjId);
|
||||
dst->fCritical = src->fCritical;
|
||||
return copy_blob(p, &dst->Value, &src->Value);
|
||||
}
|
||||
|
||||
static CRL_INFO *clone_crl_info(const CRL_INFO *src)
|
||||
{
|
||||
size_t size = sizeof(CRL_INFO);
|
||||
CRL_INFO *dst;
|
||||
DWORD i, j;
|
||||
char *p;
|
||||
|
||||
if (src->SignatureAlgorithm.pszObjId)
|
||||
size += strlen(src->SignatureAlgorithm.pszObjId) + 1;
|
||||
size += src->SignatureAlgorithm.Parameters.cbData;
|
||||
size += src->Issuer.cbData;
|
||||
for (i = 0; i < src->cCRLEntry; ++i)
|
||||
{
|
||||
const CRL_ENTRY *entry = &src->rgCRLEntry[i];
|
||||
|
||||
size += sizeof(CRL_ENTRY);
|
||||
size += entry->SerialNumber.cbData;
|
||||
for (j = 0; j < entry->cExtension; ++j)
|
||||
{
|
||||
const CERT_EXTENSION *ext = &entry->rgExtension[j];
|
||||
|
||||
size += sizeof(CERT_EXTENSION);
|
||||
size += strlen(ext->pszObjId) + 1;
|
||||
size += ext->Value.cbData;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < src->cExtension; ++j)
|
||||
{
|
||||
const CERT_EXTENSION *ext = &src->rgExtension[j];
|
||||
|
||||
size += sizeof(CERT_EXTENSION);
|
||||
size += strlen(ext->pszObjId) + 1;
|
||||
size += ext->Value.cbData;
|
||||
}
|
||||
|
||||
if (!(dst = LocalAlloc(LPTR, size)))
|
||||
return NULL;
|
||||
p = (char *)(dst + 1);
|
||||
|
||||
dst->dwVersion = src->dwVersion;
|
||||
if (src->SignatureAlgorithm.pszObjId)
|
||||
p = copy_string(p, &dst->SignatureAlgorithm.pszObjId, src->SignatureAlgorithm.pszObjId);
|
||||
p = copy_blob(p, &dst->SignatureAlgorithm.Parameters, &src->SignatureAlgorithm.Parameters);
|
||||
p = copy_blob(p, &dst->Issuer, &src->Issuer);
|
||||
dst->ThisUpdate = src->ThisUpdate;
|
||||
dst->NextUpdate = src->NextUpdate;
|
||||
|
||||
dst->cCRLEntry = src->cCRLEntry;
|
||||
dst->rgCRLEntry = (CRL_ENTRY *)p;
|
||||
p += src->cCRLEntry * sizeof(CRL_ENTRY);
|
||||
|
||||
dst->cExtension = src->cExtension;
|
||||
dst->rgExtension = (CERT_EXTENSION *)p;
|
||||
p += src->cExtension * sizeof(CERT_EXTENSION);
|
||||
|
||||
for (i = 0; i < src->cCRLEntry; ++i)
|
||||
{
|
||||
const CRL_ENTRY *src_entry = &src->rgCRLEntry[i];
|
||||
CRL_ENTRY *dst_entry = &dst->rgCRLEntry[i];
|
||||
|
||||
p = copy_blob(p, &dst_entry->SerialNumber, &src_entry->SerialNumber);
|
||||
dst_entry->RevocationDate = src_entry->RevocationDate;
|
||||
dst_entry->cExtension = src_entry->cExtension;
|
||||
dst_entry->rgExtension = (CERT_EXTENSION *)p;
|
||||
p += src_entry->cExtension * sizeof(CERT_EXTENSION);
|
||||
|
||||
for (j = 0; j < src_entry->cExtension; ++j)
|
||||
p = copy_extension(p, &dst_entry->rgExtension[j], &src_entry->rgExtension[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < src->cExtension; ++j)
|
||||
p = copy_extension(p, &dst->rgExtension[j], &src->rgExtension[j]);
|
||||
|
||||
assert(p - (char *)dst == size);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link)
|
||||
{
|
||||
crl_t *dst;
|
||||
|
@ -47,8 +149,6 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL
|
|||
return NULL;
|
||||
}else {
|
||||
const crl_t *src = (const crl_t*)context;
|
||||
DWORD size = 0;
|
||||
BOOL res;
|
||||
|
||||
if (!(dst = (crl_t *)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store)))
|
||||
return NULL;
|
||||
|
@ -60,11 +160,8 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL
|
|||
memcpy(dst->ctx.pbCrlEncoded, src->ctx.pbCrlEncoded, src->ctx.cbCrlEncoded);
|
||||
dst->ctx.cbCrlEncoded = src->ctx.cbCrlEncoded;
|
||||
|
||||
/* FIXME: We don't need to decode the object here, we could just clone dst info. */
|
||||
res = CryptDecodeObjectEx(dst->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
|
||||
dst->ctx.pbCrlEncoded, dst->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||
&dst->ctx.pCrlInfo, &size);
|
||||
if(!res) {
|
||||
if (!(dst->ctx.pCrlInfo = clone_crl_info(src->ctx.pCrlInfo)))
|
||||
{
|
||||
CertFreeCRLContext(&dst->ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue