Juan Lang : crypt32: Partially implement decoding of signed messages.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jul 26 06:37:25 CDT 2007


Module: wine
Branch: master
Commit: 3a85fa6b15abe69c6a4a974689a571df41763ea5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3a85fa6b15abe69c6a4a974689a571df41763ea5

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Jul 25 18:12:16 2007 -0700

crypt32: Partially implement decoding of signed messages.

---

 dlls/crypt32/crypt32_private.h |    4 +++
 dlls/crypt32/decode.c          |   56 ++++++++++++++++++++++++++++++++++++++++
 dlls/crypt32/msg.c             |   22 +++++++++++++++-
 3 files changed, 81 insertions(+), 1 deletions(-)

diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 9b1fc27..14f081f 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -99,6 +99,10 @@ typedef struct _CRYPT_SIGNED_INFO
 BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
  DWORD *pcbData);
 
+BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
+ DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
+ CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo);
+
 /* Helper function to check *pcbEncoded, set it to the required size, and
  * optionally to allocate memory.  Assumes pbEncoded is not NULL.
  * If CRYPT_ENCODE_ALLOC_FLAG is set in dwFlags, *pbEncoded will be set to a
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index f66ae85..29e1a2d 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -3841,6 +3841,62 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
     return ret;
 }
 
+static BOOL WINAPI CRYPT_DecodeSignerArray(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+    BOOL ret;
+    struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
+     CRYPT_AsnDecodePKCSSignerInfo, sizeof(CMSG_SIGNER_INFO), TRUE,
+     offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
+    struct GenericArray *array = (struct GenericArray *)pvStructInfo;
+
+    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pDecodePara, pvStructInfo, *pcbStructInfo);
+
+    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
+     pDecodePara, pvStructInfo, pcbStructInfo, array ? array->rgItems : NULL);
+    return ret;
+}
+
+BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
+ DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
+ CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
+{
+    BOOL ret = FALSE;
+    struct AsnDecodeSequenceItem items[] = {
+     { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version), CRYPT_AsnDecodeInt,
+       sizeof(DWORD), FALSE, FALSE, 0, 0 },
+     /* Placeholder for the hash algorithms - redundant with those in the
+      * signers, so just ignore them.
+      */
+     { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
+     { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
+       CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
+       FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
+     { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
+       offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
+       CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
+       offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
+     { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
+       offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
+       sizeof(struct GenericArray), TRUE, TRUE,
+       offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
+     { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
+       CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
+       offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
+    };
+
+    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
+     pDecodePara, signedInfo, *pcbSignedInfo);
+
+    ret = CRYPT_AsnDecodeSequence(X509_ASN_ENCODING, items,
+     sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
+     pDecodePara, signedInfo, pcbSignedInfo, NULL);
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index a842286..7ccfb53 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -1253,6 +1253,23 @@ static BOOL CDecodeMsg_DecodeHashedContent(CDecodeMsg *msg,
     return ret;
 }
 
+static BOOL CDecodeMsg_DecodeSignedContent(CDecodeMsg *msg,
+ CRYPT_DER_BLOB *blob)
+{
+    BOOL ret;
+    CRYPT_SIGNED_INFO *signedInfo;
+    DWORD size;
+
+    ret = CRYPT_AsnDecodePKCSSignedInfo(blob->pbData, blob->cbData,
+     CRYPT_DECODE_ALLOC_FLAG, NULL, (CRYPT_SIGNED_INFO *)&signedInfo,
+     &size);
+    if (ret)
+    {
+        FIXME("store properties in message\n");
+        LocalFree(signedInfo);
+    }
+    return ret;
+}
 /* Decodes the content in blob as the type given, and updates the value
  * (type, parameters, etc.) of msg based on what blob contains.
  * It doesn't just use msg's type, to allow a recursive call from an implicitly
@@ -1274,10 +1291,13 @@ static BOOL CDecodeMsg_DecodeContent(CDecodeMsg *msg, CRYPT_DER_BLOB *blob,
             msg->type = CMSG_HASHED;
         break;
     case CMSG_ENVELOPED:
-    case CMSG_SIGNED:
         FIXME("unimplemented for type %s\n", MSG_TYPE_STR(type));
         ret = TRUE;
         break;
+    case CMSG_SIGNED:
+        if ((ret = CDecodeMsg_DecodeSignedContent(msg, blob)))
+            msg->type = CMSG_HASHED;
+        break;
     default:
     {
         CRYPT_CONTENT_INFO *info;




More information about the wine-cvs mailing list