Module: wine Branch: master Commit: 3a85fa6b15abe69c6a4a974689a571df41763ea5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3a85fa6b15abe69c6a4a974689...
Author: Juan Lang juan.lang@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;