crypt32(3/20): Introduce function to encode an array of items as a
set
Juan Lang
juan.lang at gmail.com
Mon Jul 23 20:26:59 CDT 2007
--Juan
-------------- next part --------------
From 1069b25d00aae52a09cfdd3eb256a51ddb89c1db Mon Sep 17 00:00:00 2001
From: Juan Lang <juanlang at juan.corp.google.com>
Date: Mon, 23 Jul 2007 15:29:15 -0700
Subject: [PATCH] Introduce function to encode an array of items as a set
---
dlls/crypt32/encode.c | 126 +++++++++++++++++++++++++++++++++++--------------
1 files changed, 89 insertions(+), 37 deletions(-)
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index a7cb661..e2fcc99 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -1210,6 +1210,91 @@ static BOOL WINAPI CRYPT_DEREncodeSet(DW
return ret;
}
+struct DERSetDescriptor
+{
+ DWORD cItems;
+ const void *items;
+ size_t itemSize;
+ off_t itemOffset;
+ CryptEncodeObjectExFunc encode;
+};
+
+static BOOL WINAPI CRYPT_DEREncodeItemsAsSet(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+ const struct DERSetDescriptor *desc =
+ (const struct DERSetDescriptor *)pvStructInfo;
+ CRYPT_SET_OF setOf = { 0, NULL };
+ BOOL ret = TRUE;
+ DWORD i;
+
+ if (desc->cItems)
+ {
+ setOf.rgValue = CryptMemAlloc(setOf.cValue * sizeof(CRYPT_DER_BLOB));
+ if (!setOf.rgValue)
+ ret = FALSE;
+ else
+ {
+ setOf.cValue = desc->cItems;
+ memset(setOf.rgValue, 0, setOf.cValue * sizeof(CRYPT_DER_BLOB));
+ }
+ }
+ for (i = 0; ret && i < setOf.cValue; i++)
+ {
+ ret = desc->encode(dwCertEncodingType, lpszStructType,
+ (const BYTE *)desc->items + i * desc->itemSize + desc->itemOffset,
+ 0, NULL, NULL, &setOf.rgValue[i].cbData);
+ if (ret)
+ {
+ setOf.rgValue[i].pbData = CryptMemAlloc(setOf.rgValue[i].cbData);
+ if (!setOf.rgValue[i].pbData)
+ ret = FALSE;
+ else
+ ret = desc->encode(dwCertEncodingType, lpszStructType,
+ (const BYTE *)desc->items + i * desc->itemSize +
+ desc->itemOffset, 0, NULL, setOf.rgValue[i].pbData,
+ &setOf.rgValue[i].cbData);
+ }
+ /* Some functions propagate their errors through the size */
+ if (!ret)
+ *pcbEncoded = setOf.rgValue[i].cbData;
+ }
+ if (ret)
+ {
+ DWORD bytesNeeded = 0, lenBytes;
+ BOOL ret;
+
+ for (i = 0; i < setOf.cValue; i++)
+ bytesNeeded += setOf.rgValue[i].cbData;
+ CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes);
+ bytesNeeded += 1 + lenBytes;
+ if (!pbEncoded)
+ *pcbEncoded = bytesNeeded;
+ else if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
+ pbEncoded, pcbEncoded, bytesNeeded)))
+ {
+ if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
+ pbEncoded = *(BYTE **)pbEncoded;
+ qsort(setOf.rgValue, setOf.cValue, sizeof(CRYPT_DER_BLOB),
+ BLOBComp);
+ *pbEncoded++ = ASN_CONSTRUCTOR | ASN_SETOF;
+ CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, &lenBytes);
+ pbEncoded += lenBytes;
+ for (i = 0; i < setOf.cValue; i++)
+ {
+ memcpy(pbEncoded, setOf.rgValue[i].pbData,
+ setOf.rgValue[i].cbData);
+ pbEncoded += setOf.rgValue[i].cbData;
+ }
+ }
+ }
+ for (i = 0; i < setOf.cValue; i++)
+ CryptMemFree(setOf.rgValue[i].pbData);
+ CryptMemFree(setOf.rgValue);
+ return ret;
+}
+
static BOOL WINAPI CRYPT_AsnEncodeRdn(DWORD dwCertEncodingType, CERT_RDN *rdn,
CryptEncodeObjectExFunc nameValueEncodeFunc, BYTE *pbEncoded,
DWORD *pcbEncoded)
@@ -1394,55 +1479,22 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSAt
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
{
BOOL ret = FALSE;
- CRYPT_SET_OF setOf = { 0, NULL };
__TRY
{
- DWORD i;
const CRYPT_ATTRIBUTES *attributes =
(const CRYPT_ATTRIBUTES *)pvStructInfo;
+ struct DERSetDescriptor desc = { attributes->cAttr, attributes->rgAttr,
+ sizeof(CRYPT_ATTRIBUTE), 0, CRYPT_AsnEncodePKCSAttribute };
- ret = TRUE;
- if (attributes->cAttr)
- {
- setOf.cValue = attributes->cAttr;
- setOf.rgValue = CryptMemAlloc(attributes->cAttr *
- sizeof(CRYPT_DER_BLOB));
- if (!setOf.rgValue)
- ret = FALSE;
- else
- memset(setOf.rgValue, 0, setOf.cValue * sizeof(CRYPT_DER_BLOB));
- }
- for (i = 0; ret && i < attributes->cAttr; i++)
- {
- ret = CRYPT_AsnEncodePKCSAttribute(dwCertEncodingType, NULL,
- &attributes->rgAttr[i], 0, NULL, NULL, &setOf.rgValue[i].cbData);
- if (ret)
- {
- setOf.rgValue[i].pbData =
- CryptMemAlloc(setOf.rgValue[i].cbData);
- if (!setOf.rgValue[i].pbData)
- ret = FALSE;
- else
- {
- ret = CRYPT_AsnEncodePKCSAttribute(dwCertEncodingType, NULL,
- &attributes->rgAttr[i], 0, NULL, setOf.rgValue[i].pbData,
- &setOf.rgValue[i].cbData);
- }
- }
- }
- if (ret)
- ret = CRYPT_DEREncodeSet(X509_ASN_ENCODING, NULL, &setOf, dwFlags,
- pEncodePara, pbEncoded, pcbEncoded);
- for (i = 0; i < setOf.cValue; i++)
- CryptMemFree(setOf.rgValue[i].pbData);
+ ret = CRYPT_DEREncodeItemsAsSet(X509_ASN_ENCODING, lpszStructType,
+ &desc, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
__EXCEPT_PAGE_FAULT
{
SetLastError(STATUS_ACCESS_VIOLATION);
}
__ENDTRY
- CryptMemFree(setOf.rgValue);
return ret;
}
--
1.4.1
More information about the wine-patches
mailing list