diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c index 4dc77c2a246..657810e0c6b 100644 --- a/dlls/crypt32/crl.c +++ b/dlls/crypt32/crl.c @@ -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; }