crypt32(7/9): Test and fix encoding and decoding of attributes in PKCS signers

Juan Lang juan.lang at gmail.com
Wed Jul 25 20:19:03 CDT 2007


--Juan
-------------- next part --------------
From 5833f9a7f66616a5e2686e8f8663787db5a78611 Mon Sep 17 00:00:00 2001
From: Juan Lang <juanlang at juan.corp.google.com>
Date: Wed, 25 Jul 2007 18:13:45 -0700
Subject: [PATCH] Test and fix encoding and decoding of attributes in PKCS signers
---
 dlls/crypt32/decode.c       |   27 +++++++++++++--------
 dlls/crypt32/encode.c       |   30 ++++++++++++++++-------
 dlls/crypt32/tests/encode.c |   55 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 21 deletions(-)

diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 29e1a2d..52e207e 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -1896,9 +1896,8 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAt
  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
  void *pvStructInfo, DWORD *pcbStructInfo)
 {
-    struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
-     CRYPT_AsnDecodePKCSAttribute, sizeof(CRYPT_ATTRIBUTE), TRUE,
-     offsetof(CRYPT_ATTRIBUTE, pszObjId) };
+    struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodePKCSAttribute,
+     sizeof(CRYPT_ATTRIBUTE), TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
     PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
     BOOL ret;
 
@@ -1921,8 +1920,12 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAt
     {
         DWORD bytesNeeded;
 
-        if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType,
-         lpszStructType, pbEncoded, cbEncoded,
+        if (!cbEncoded)
+            SetLastError(CRYPT_E_ASN1_EOD);
+        else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
+            SetLastError(CRYPT_E_ASN1_CORRUPT);
+        else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(
+         dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded,
          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded)))
         {
             if (!pvStructInfo)
@@ -3813,19 +3816,21 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSi
          { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
            CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
            FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
+         { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
+           offsetof(CMSG_SIGNER_INFO, AuthAttrs),
+           CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
+           TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
          { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
            CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
            FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
            HashEncryptionAlgorithm.pszObjId), 0 },
-         { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CMSG_SIGNER_INFO, AuthAttrs),
-           CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
-           TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
-         { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
-           CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
-           TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
          { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
            CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
            FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
+         { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
+           offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
+           CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
+           TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
         };
 
         ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index 7359ed8..6fb8e87 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -3201,26 +3201,36 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSi
              { &info->Issuer,        CRYPT_AsnEncodeIssuerSerialNumber, 0 },
              { &info->HashAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams,
                0 },
-             { &info->HashEncryptionAlgorithm,
-               CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
             };
-            DWORD cItem = 4;
+            struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } };
+            DWORD cItem = 3, cSwapped = 0;
 
             if (info->AuthAttrs.cAttr)
             {
-                items[cItem].pvStructInfo = &info->AuthAttrs;
-                items[cItem].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+                swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0;
+                swapped[cSwapped].pvStructInfo = &info->AuthAttrs;
+                swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+                items[cItem].pvStructInfo = &swapped[cSwapped];
+                items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
+                cSwapped++;
                 cItem++;
             }
+            items[cItem].pvStructInfo = &info->HashEncryptionAlgorithm;
+            items[cItem].encodeFunc = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
+            cItem++;
+            items[cItem].pvStructInfo = &info->EncryptedHash;
+            items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
+            cItem++;
             if (info->UnauthAttrs.cAttr)
             {
-                items[cItem].pvStructInfo = &info->UnauthAttrs;
-                items[cItem].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+                swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 1;
+                swapped[cSwapped].pvStructInfo = &info->UnauthAttrs;
+                swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
+                items[cItem].pvStructInfo = &swapped[cSwapped];
+                items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
+                cSwapped++;
                 cItem++;
             }
-            items[cItem].pvStructInfo = &info->EncryptedHash;
-            items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
-            cItem++;
             ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
              dwFlags, pEncodePara, pbEncoded, pcbEncoded);
         }
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index 8173a12..d918219 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -4924,6 +4924,14 @@ static const BYTE PKCSSignerWithHash[] =
  0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
  0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
  0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
+static const BYTE PKCSSignerWithAuthAttr[] = {
+0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
+0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
+0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
+0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
+0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
+0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
+0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
 
 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
 {
@@ -4932,6 +4940,10 @@ static void test_encodePKCSSignerInfo(DW
     LPBYTE buf = NULL;
     DWORD size = 0;
     CMSG_SIGNER_INFO info = { 0 };
+    char oid_common_name[] = szOID_COMMON_NAME;
+    CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
+     (LPBYTE)encodedCommonName };
+    CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
 
     SetLastError(0xdeadbeef);
     ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
@@ -5053,6 +5065,29 @@ static void test_encodePKCSSignerInfo(DW
             LocalFree(buf);
         }
     }
+    info.AuthAttrs.cAttr = 1;
+    info.AuthAttrs.rgAttr = &attr;
+    SetLastError(0xdeadbeef);
+    ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
+     CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
+    if (!(dwEncoding & PKCS_7_ASN_ENCODING))
+        ok(!ret && GetLastError() == E_INVALIDARG,
+         "Expected E_INVALIDARG, got %08x\n", GetLastError());
+    else
+    {
+        ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
+        if (buf)
+        {
+            ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
+             size);
+            if (size == sizeof(PKCSSignerWithAuthAttr))
+                ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
+                 "Unexpected value\n");
+            else
+                ok(0, "Unexpected value\n");
+            LocalFree(buf);
+        }
+    }
 }
 
 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
@@ -5157,6 +5192,26 @@ static void test_decodePKCSSignerInfo(DW
          "Unexpected value\n");
         LocalFree(buf);
     }
+    ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
+     PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
+     CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
+    if (buf)
+    {
+        info = (CMSG_SIGNER_INFO *)buf;
+        ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n", 
+         info->AuthAttrs.cAttr);
+        ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
+         "Expected %s, got %s\n", szOID_COMMON_NAME,
+         info->AuthAttrs.rgAttr[0].pszObjId);
+        ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
+         info->AuthAttrs.rgAttr[0].cValue);
+        ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
+         sizeof(encodedCommonName), "Unexpected size %d\n",
+         info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
+        ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
+         encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
+        LocalFree(buf);
+    }
 }
 
 /* Free *pInfo with HeapFree */
-- 
1.4.1


More information about the wine-patches mailing list