Juan Lang : crypt32: Add support for decoding PKCS_SMIME_CAPABILITIES.
Alexandre Julliard
julliard at winehq.org
Thu Aug 21 10:02:15 CDT 2008
Module: wine
Branch: master
Commit: ac5c7d22d02ca6dc88b209573051dbb61c65ce83
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ac5c7d22d02ca6dc88b209573051dbb61c65ce83
Author: Juan Lang <juan.lang at gmail.com>
Date: Wed Aug 20 12:11:41 2008 -0700
crypt32: Add support for decoding PKCS_SMIME_CAPABILITIES.
---
dlls/crypt32/decode.c | 111 +++++++++++++++++++++++++++++++++++++++++--
dlls/crypt32/tests/encode.c | 4 --
2 files changed, 106 insertions(+), 9 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 8df801a..64d4818 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -1997,13 +1997,18 @@ static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
*pcbStructInfo = bytesNeeded;
blob->cbData = encodedLen;
- if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
- blob->pbData = (LPBYTE)pbEncoded;
- else
+ if (encodedLen)
{
- assert(blob->pbData);
- memcpy(blob->pbData, pbEncoded, blob->cbData);
+ if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
+ blob->pbData = (LPBYTE)pbEncoded;
+ else
+ {
+ assert(blob->pbData);
+ memcpy(blob->pbData, pbEncoded, blob->cbData);
+ }
}
+ else
+ blob->pbData = NULL;
}
if (pcbDecoded)
*pcbDecoded = encodedLen;
@@ -2028,6 +2033,97 @@ static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
+static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ BOOL ret;
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
+ CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
+ offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
+ { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
+ CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
+ offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
+ };
+ PCRYPT_SMIME_CAPABILITY capability = (PCRYPT_SMIME_CAPABILITY)pvStructInfo;
+
+ TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pvStructInfo, *pcbStructInfo);
+
+ ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
+ pcbDecoded, capability ? capability->pszObjId : NULL);
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
+ DWORD *pcbDecoded)
+{
+ struct AsnArrayDescriptor arrayDesc = { 0,
+ CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
+ offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
+ PCRYPT_SMIME_CAPABILITIES capabilities =
+ (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
+ BOOL ret;
+
+ ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
+ NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
+ capabilities ? capabilities->rgCapability : NULL);
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, *pcbStructInfo);
+
+ __TRY
+ {
+ DWORD bytesNeeded;
+
+ if (!cbEncoded)
+ SetLastError(CRYPT_E_ASN1_EOD);
+ else if (pbEncoded[0] != ASN_SEQUENCEOF)
+ SetLastError(CRYPT_E_ASN1_CORRUPT);
+ else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
+ cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
+ NULL)))
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ PCRYPT_SMIME_CAPABILITIES capabilities;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
+ capabilities->rgCapability =
+ (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
+ sizeof(CRYPT_SMIME_CAPABILITIES));
+ ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
+ cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
+ &bytesNeeded, NULL);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ }
+ __ENDTRY
+ TRACE("returning %d\n", ret);
+ return ret;
+}
+
static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
DWORD *pcbDecoded)
@@ -4603,6 +4699,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(X509_ENHANCED_KEY_USAGE):
decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
break;
+ case LOWORD(PKCS_SMIME_CAPABILITIES):
+ decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
+ break;
case LOWORD(PKCS_ATTRIBUTES):
decodeFunc = CRYPT_AsnDecodePKCSAttributes;
break;
@@ -4624,6 +4723,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
decodeFunc = CRYPT_AsnDecodeExtensions;
else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
decodeFunc = CRYPT_AsnDecodeUtcTime;
+ else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
+ decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index 9214609..d6bcf61 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -5262,7 +5262,6 @@ static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
emptySequence, sizeof(emptySequence),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
@@ -5274,7 +5273,6 @@ static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
(BYTE *)&ptr, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
@@ -5289,7 +5287,6 @@ static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
@@ -5307,7 +5304,6 @@ static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
(BYTE *)&ptr, &size);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
More information about the wine-cvs
mailing list