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