Needed by Lenovo USBRecoveryCreator.
-- v4: cryptxml/tests: Add some signature verification tests.
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 1 + dlls/cryptxml/Makefile.in | 1 + dlls/cryptxml/cryptxml.spec | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 dlls/cryptxml/Makefile.in create mode 100644 dlls/cryptxml/cryptxml.spec
diff --git a/configure.ac b/configure.ac index c8dadcf9bff..83778c2882a 100644 --- a/configure.ac +++ b/configure.ac @@ -2529,6 +2529,7 @@ WINE_CONFIG_MAKEFILE(dlls/cryptowinrt/tests) WINE_CONFIG_MAKEFILE(dlls/cryptsp) WINE_CONFIG_MAKEFILE(dlls/cryptui) WINE_CONFIG_MAKEFILE(dlls/cryptui/tests) +WINE_CONFIG_MAKEFILE(dlls/cryptxml) WINE_CONFIG_MAKEFILE(dlls/ctapi32) WINE_CONFIG_MAKEFILE(dlls/ctl3d.dll16) WINE_CONFIG_MAKEFILE(dlls/ctl3d32) diff --git a/dlls/cryptxml/Makefile.in b/dlls/cryptxml/Makefile.in new file mode 100644 index 00000000000..f5e925499c2 --- /dev/null +++ b/dlls/cryptxml/Makefile.in @@ -0,0 +1 @@ +MODULE = cryptxml.dll diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec new file mode 100644 index 00000000000..326f5d56b32 --- /dev/null +++ b/dlls/cryptxml/cryptxml.spec @@ -0,0 +1,19 @@ +@ stub CryptXmlAddObject +@ stub CryptXmlClose +@ stub CryptXmlCreateReference +@ stub CryptXmlDigestReference +@ stub CryptXmlEncode +@ stub CryptXmlEnumAlgorithmInfo +@ stub CryptXmlFindAlgorithmInfo +@ stub CryptXmlGetAlgorithmInfo +@ stub CryptXmlGetDocContext +@ stub CryptXmlGetReference +@ stub CryptXmlGetSignature +@ stub CryptXmlGetStatus +@ stub CryptXmlGetTransforms +@ stub CryptXmlImportPublicKey +@ stub CryptXmlOpenToDecode +@ stub CryptXmlOpenToEncode +@ stub CryptXmlSetHMACSecret +@ stub CryptXmlSign +@ stub CryptXmlVerifySignature
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/Makefile.in | 1 + include/cryptxml.h | 283 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 include/cryptxml.h
diff --git a/include/Makefile.in b/include/Makefile.in index 662b149da32..5edd519d2fc 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -104,6 +104,7 @@ SOURCES = \ crtrow.idl \ cryptdlg.h \ cryptuiapi.h \ + cryptxml.h \ ctfutb.idl \ ctxtcall.idl \ custcntl.h \ diff --git a/include/cryptxml.h b/include/cryptxml.h new file mode 100644 index 00000000000..1a531f9739d --- /dev/null +++ b/include/cryptxml.h @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __CRYPTXML_H__ +#define __CRYPTXML_H__ + +#include <wincrypt.h> +#include <bcrypt.h> +#include <ncrypt.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *HCRYPTXML; + +#define CRYPT_XML_FLAG_NO_SERIALIZE 0x80000000 +#define CRYPT_XML_FLAG_ALWAYS_RETURN_ENCODED_OBJECT 0x40000000 +#define CRYPT_XML_FLAG_ENFORCE_ID_NCNAME_FORMAT 0x20000000 +#define CRYPT_XML_FLAG_DISABLE_EXTENSIONS 0x10000000 +#define CRYPT_XML_FLAG_ENFORCE_ID_NAME_FORMAT 0x08000000 +#define CRYPT_XML_FLAG_ECDSA_DSIG11 0x04000000 + +typedef HRESULT (CALLBACK *PFN_CRYPT_XML_DATA_PROVIDER_READ)(void *, BYTE *, ULONG, ULONG *); +typedef HRESULT (CALLBACK *PFN_CRYPT_XML_DATA_PROVIDER_CLOSE)(void *); + +typedef enum _CRYPT_XML_CHARSET +{ + CRYPT_XML_CHARSET_AUTO = 0, + CRYPT_XML_CHARSET_UTF8 = 1, + CRYPT_XML_CHARSET_UTF16LE = 2, + CRYPT_XML_CHARSET_UTF16BE = 3, +} CRYPT_XML_CHARSET; + +typedef struct _CRYPT_XML_BLOB +{ + CRYPT_XML_CHARSET dwCharset; + ULONG cbData; + BYTE *pbData; +} CRYPT_XML_BLOB, *PCRYPT_XML_BLOB; + +typedef struct _CRYPT_XML_DATA_BLOB +{ + ULONG cbData; + BYTE *pbData; +} CRYPT_XML_DATA_BLOB, *PCRYPT_XML_DATA_BLOB; + +typedef struct _CRYPT_XML_DATA_PROVIDER +{ + void *pvCallbackState; + ULONG cbBufferSize; + PFN_CRYPT_XML_DATA_PROVIDER_READ pfnRead; + PFN_CRYPT_XML_DATA_PROVIDER_CLOSE pfnClose; +} CRYPT_XML_DATA_PROVIDER, *PCRYPT_XML_DATA_PROVIDER; + +typedef struct _CRYPT_XML_ALGORITHM +{ + ULONG cbSize; + LPCWSTR wszAlgorithm; + CRYPT_XML_BLOB Encoded; +} CRYPT_XML_ALGORITHM, *PCRYPT_XML_ALGORITHM; + +typedef HRESULT (CALLBACK *PFN_CRYPT_XML_CREATE_TRANSFORM)(const CRYPT_XML_ALGORITHM *, CRYPT_XML_DATA_PROVIDER *, CRYPT_XML_DATA_PROVIDER *); + +typedef struct _CRYPT_XML_TRANSFORM_INFO +{ + ULONG cbSize; + LPCWSTR wszAlgorithm; + ULONG cbBufferSize; + DWORD dwFlags; + PFN_CRYPT_XML_CREATE_TRANSFORM pfnCreateTransform; +} CRYPT_XML_TRANSFORM_INFO, *PCRYPT_XML_TRANSFORM_INFO; + +typedef struct _CRYPT_XML_TRANSFORM_CHAIN_CONFIG +{ + ULONG cbSize; + ULONG cTransformInfo; + PCRYPT_XML_TRANSFORM_INFO *rgpTransformInfo; +} CRYPT_XML_TRANSFORM_CHAIN_CONFIG, *PCRYPT_XML_TRANSFORM_CHAIN_CONFIG; + +typedef enum _CRYPT_XML_PROPERTY_ID +{ + CRYPT_XML_PROPERTY_MAX_HEAP_SIZE = 1, + CRYPT_XML_PROPERTY_SIGNATURE_LOCATION = 2, + CRYPT_XML_PROPERTY_MAX_SIGNATURES = 3, + CRYPT_XML_PROPERTY_DOC_DECLARATION = 4, + CRYPT_XML_PROPERTY_XML_OUTPUT_CHARSET = 5, +} CRYPT_XML_PROPERTY_ID; + +typedef struct _CRYPT_XML_PROPERTY +{ + CRYPT_XML_PROPERTY_ID dwPropId; + const void *pvValue; + ULONG cbValue; +} CRYPT_XML_PROPERTY, *PCRYPT_XML_PROPERTY; + +typedef struct _CRYPT_XML_ISSUER_SERIAL +{ + LPCWSTR wszIssuer; + LPCWSTR wszSerial; +} CRYPT_XML_ISSUER_SERIAL; + +typedef struct _CRYPT_XML_X509DATA_ITEM +{ + DWORD dwType; + union + { + CRYPT_XML_ISSUER_SERIAL IssuerSerial; + CRYPT_XML_DATA_BLOB SKI; + LPCWSTR wszSubjectName; + CRYPT_XML_DATA_BLOB Certificate; + CRYPT_XML_DATA_BLOB CRL; + CRYPT_XML_BLOB Custom; + }; +} CRYPT_XML_X509DATA_ITEM; + +#define CRYPT_XML_X509DATA_TYPE_ISSUER_SERIAL 0x00000001 +#define CRYPT_XML_X509DATA_TYPE_SKI 0x00000002 +#define CRYPT_XML_X509DATA_TYPE_SUBJECT_NAME 0x00000003 +#define CRYPT_XML_X509DATA_TYPE_CERTIFICATE 0x00000004 +#define CRYPT_XML_X509DATA_TYPE_CRL 0x00000005 +#define CRYPT_XML_X509DATA_TYPE_CUSTOM 0x00000006 + +typedef struct _CRYPT_XML_X509DATA +{ + UINT cX509Data; + CRYPT_XML_X509DATA_ITEM *rgX509Data; +} CRYPT_XML_X509DATA; + +typedef struct _CRYPT_XML_KEY_DSA_KEY_VALUE +{ + CRYPT_XML_DATA_BLOB P; + CRYPT_XML_DATA_BLOB Q; + CRYPT_XML_DATA_BLOB G; + CRYPT_XML_DATA_BLOB Y; + CRYPT_XML_DATA_BLOB J; + CRYPT_XML_DATA_BLOB Seed; + CRYPT_XML_DATA_BLOB Counter; +} CRYPT_XML_KEY_DSA_KEY_VALUE; + +typedef struct _CRYPT_XML_KEY_RSA_KEY_VALUE{ + CRYPT_XML_DATA_BLOB Modulus; + CRYPT_XML_DATA_BLOB Exponent; +} CRYPT_XML_KEY_RSA_KEY_VALUE; + +typedef struct _CRYPT_XML_KEY_ECDSA_KEY_VALUE +{ + LPCWSTR wszNamedCurve; + CRYPT_XML_DATA_BLOB X; + CRYPT_XML_DATA_BLOB Y; + CRYPT_XML_BLOB ExplicitPara; +} CRYPT_XML_KEY_ECDSA_KEY_VALUE; + +typedef struct _CRYPT_XML_KEY_VALUE +{ + DWORD dwType; + union + { + CRYPT_XML_KEY_DSA_KEY_VALUE DSAKeyValue; + CRYPT_XML_KEY_RSA_KEY_VALUE RSAKeyValue; + CRYPT_XML_KEY_ECDSA_KEY_VALUE ECDSAKeyValue; + CRYPT_XML_BLOB Custom; + }; +} CRYPT_XML_KEY_VALUE; + +#define CRYPT_XML_KEY_VALUE_TYPE_DSA 0x00000001 +#define CRYPT_XML_KEY_VALUE_TYPE_RSA 0x00000002 +#define CRYPT_XML_KEY_VALUE_TYPE_ECDSA 0x00000003 +#define CRYPT_XML_KEY_VALUE_TYPE_CUSTOM 0x00000004 + +typedef struct _CRYPT_XML_KEY_INFO_ITEM +{ + DWORD dwType; + union + { + LPCWSTR wszKeyName; + CRYPT_XML_KEY_VALUE KeyValue; + CRYPT_XML_BLOB RetrievalMethod; + CRYPT_XML_X509DATA X509Data; + CRYPT_XML_BLOB Custom; + }; +} CRYPT_XML_KEY_INFO_ITEM; + +#define CRYPT_XML_KEYINFO_TYPE_KEYNAME 0x00000001 +#define CRYPT_XML_KEYINFO_TYPE_KEYVALUE 0x00000002 +#define CRYPT_XML_KEYINFO_TYPE_RETRIEVAL 0x00000003 +#define CRYPT_XML_KEYINFO_TYPE_X509DATA 0x00000004 +#define CRYPT_XML_KEYINFO_TYPE_CUSTOM 0x00000005 + +typedef struct _CRYPT_XML_KEY_INFO +{ + ULONG cbSize; + LPCWSTR wszId; + UINT cKeyInfo; + CRYPT_XML_KEY_INFO_ITEM *rgKeyInfo; + BCRYPT_KEY_HANDLE hVerifyKey; +} CRYPT_XML_KEY_INFO, *PCRYPT_XML_KEY_INFO; + +typedef struct _CRYPT_XML_REFERENCE +{ + ULONG cbSize; + HCRYPTXML hReference; + LPCWSTR wszId; + LPCWSTR wszUri; + LPCWSTR wszType; + CRYPT_XML_ALGORITHM DigestMethod; + CRYPT_DATA_BLOB DigestValue; + ULONG cTransform; + CRYPT_XML_ALGORITHM *rgTransform; +} CRYPT_XML_REFERENCE, *PCRYPT_XML_REFERENCE; + +typedef struct _CRYPT_XML_REFERENCES +{ + ULONG cReference; + PCRYPT_XML_REFERENCE *rgpReference; +} CRYPT_XML_REFERENCES, *PCRYPT_XML_REFERENCES; + +typedef struct _CRYPT_XML_OBJECT +{ + ULONG cbSize; + HCRYPTXML hObject; + LPCWSTR wszId; + LPCWSTR wszMimeType; + LPCWSTR wszEncoding; + CRYPT_XML_REFERENCES Manifest; + CRYPT_XML_BLOB Encoded; +} CRYPT_XML_OBJECT, *PCRYPT_XML_OBJECT; + +typedef struct _CRYPT_XML_SIGNED_INFO +{ + ULONG cbSize; + LPCWSTR wszId; + CRYPT_XML_ALGORITHM Canonicalization; + CRYPT_XML_ALGORITHM SignatureMethod; + ULONG cReference; + PCRYPT_XML_REFERENCE *rgpReference; + CRYPT_XML_BLOB Encoded; +} CRYPT_XML_SIGNED_INFO, *PCRYPT_XML_SIGNED_INFO; + +typedef struct _CRYPT_XML_SIGNATURE +{ + ULONG cbSize; + HCRYPTXML hSignature; + LPCWSTR wszId; + CRYPT_XML_SIGNED_INFO SignedInfo; + CRYPT_DATA_BLOB SignatureValue; + CRYPT_XML_KEY_INFO *pKeyInfo; + ULONG cObject; + PCRYPT_XML_OBJECT *rgpObject; +} CRYPT_XML_SIGNATURE, *PCRYPT_XML_SIGNATURE; + +typedef struct _CRYPT_XML_DOC_CTXT +{ + ULONG cbSize; + HCRYPTXML hDocCtxt; + CRYPT_XML_TRANSFORM_CHAIN_CONFIG *pTransformsConfig; + ULONG cSignature; + PCRYPT_XML_SIGNATURE *rgpSignature; +} CRYPT_XML_DOC_CTXT, *PCRYPT_XML_DOC_CTXT; + +HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, + ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle); + +#ifdef __cplusplus +} +#endif + +#endif /* CRYPTXML_H */
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Lenovo USBRecoveryCreator. --- dlls/cryptxml/Makefile.in | 3 ++ dlls/cryptxml/cryptxml.c | 81 +++++++++++++++++++++++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 22 ++++++++++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 dlls/cryptxml/cryptxml.c
diff --git a/dlls/cryptxml/Makefile.in b/dlls/cryptxml/Makefile.in index f5e925499c2..1fe91fe7019 100644 --- a/dlls/cryptxml/Makefile.in +++ b/dlls/cryptxml/Makefile.in @@ -1 +1,4 @@ MODULE = cryptxml.dll + +SOURCES = \ + cryptxml.c diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c new file mode 100644 index 00000000000..76105802b50 --- /dev/null +++ b/dlls/cryptxml/cryptxml.c @@ -0,0 +1,81 @@ +/* CryptXML Implementation + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "cryptxml.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(cryptxml); + +struct xmldoc +{ + CRYPT_XML_DOC_CTXT ctx; + CRYPT_XML_SIGNATURE sig; + CRYPT_XML_SIGNATURE *sigs[1]; + CRYPT_XML_STATUS status; + CRYPT_XML_SIGNED_INFO signed_info; + CRYPT_XML_KEY_INFO key_info; +}; + +HRESULT WINAPI CryptXmlOpenToDecode( const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, + const CRYPT_XML_PROPERTY *property, ULONG property_count, + const CRYPT_XML_BLOB *blob, HCRYPTXML *handle ) +{ + struct xmldoc *doc; + + FIXME( "config %p, flags %lx, property %p, property_count %lu, blob %p, handle %p stub!\n", + config, flags, property, property_count, blob, handle ); + + if (!blob || !handle) return E_INVALIDARG; + if (!(doc = calloc( 1, sizeof( *doc ) ))) return E_OUTOFMEMORY; + if (!(doc->sig.SignatureValue.pbData = malloc( blob->cbData ))) + { + free( doc ); + return E_OUTOFMEMORY; + } + memcpy( doc->sig.SignatureValue.pbData, blob->pbData, blob->cbData ); + + doc->sig.cbSize = sizeof( CRYPT_XML_SIGNATURE ); + doc->sig.hSignature = (HCRYPTXML)&doc->sig; + doc->sig.wszId = L""; + doc->sig.SignedInfo = doc->signed_info; + doc->sig.SignatureValue.cbData = blob->cbData; + doc->sig.pKeyInfo = &doc->key_info; + doc->sig.cObject = 0; + doc->sig.rgpObject = NULL; + + doc->sigs[0] = &doc->sig; + + doc->ctx.cbSize = sizeof( CRYPT_XML_DOC_CTXT ); + doc->ctx.hDocCtxt = (HCRYPTXML)doc; + doc->ctx.pTransformsConfig = NULL; + doc->ctx.cSignature = 1; + doc->ctx.rgpSignature = doc->sigs; + + doc->status.cbSize = sizeof( CRYPT_XML_STATUS ); + doc->status.dwErrorStatus = CRYPT_XML_STATUS_ERROR_NOT_RESOLVED; + doc->status.dwInfoStatus = 0; + + *handle = (HCRYPTXML)doc; + return S_OK; +} diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec index 326f5d56b32..6e9847770a3 100644 --- a/dlls/cryptxml/cryptxml.spec +++ b/dlls/cryptxml/cryptxml.spec @@ -12,7 +12,7 @@ @ stub CryptXmlGetStatus @ stub CryptXmlGetTransforms @ stub CryptXmlImportPublicKey -@ stub CryptXmlOpenToDecode +@ stdcall CryptXmlOpenToDecode(ptr long ptr long ptr ptr) @ stub CryptXmlOpenToEncode @ stub CryptXmlSetHMACSecret @ stub CryptXmlSign diff --git a/include/cryptxml.h b/include/cryptxml.h index 1a531f9739d..b11c33a37c4 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -273,6 +273,28 @@ typedef struct _CRYPT_XML_DOC_CTXT PCRYPT_XML_SIGNATURE *rgpSignature; } CRYPT_XML_DOC_CTXT, *PCRYPT_XML_DOC_CTXT;
+typedef struct _CRYPT_XML_STATUS +{ + ULONG cbSize; + DWORD dwErrorStatus; + DWORD dwInfoStatus; +} CRYPT_XML_STATUS, *PCRYPT_XML_STATUS; + +#define CRYPT_XML_STATUS_NO_ERROR 0x00000000 +#define CRYPT_XML_STATUS_ERROR_NOT_RESOLVED 0x00000001 +#define CRYPT_XML_STATUS_ERROR_DIGEST_INVALID 0x00000002 +#define CRYPT_XML_STATUS_ERROR_NOT_SUPPORTED_ALGORITHM 0x00000004 +#define CRYPT_XML_STATUS_ERROR_NOT_SUPPORTED_TRANSFORM 0x00000008 +#define CRYPT_XML_STATUS_ERROR_SIGNATURE_INVALID 0x00010000 +#define CRYPT_XML_STATUS_ERROR_KEYINFO_NOT_PARSED 0x00020000 + +#define CRYPT_XML_STATUS_INTERNAL_REFERENCE 0x00000001 +#define CRYPT_XML_STATUS_KEY_AVAILABLE 0x00000002 +#define CRYPT_XML_STATUS_DIGESTING 0x00000004 +#define CRYPT_XML_STATUS_DIGEST_VALID 0x00000008 +#define CRYPT_XML_STATUS_SIGNATURE_VALID 0x00010000 +#define CRYPT_XML_STATUS_OPENED_TO_ENCODE 0x80000000 + HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/cryptxml/cryptxml.c | 13 +++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 76105802b50..9ed11d3d9b9 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -79,3 +79,16 @@ HRESULT WINAPI CryptXmlOpenToDecode( const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *con *handle = (HCRYPTXML)doc; return S_OK; } + +HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) +{ + struct xmldoc *doc = (struct xmldoc *)handle; + + TRACE( "handle %p\n", handle ); + + if (!handle) return E_INVALIDARG; + + if (doc->sig.SignatureValue.pbData) free( doc->sig.SignatureValue.pbData ); + free( doc ); + return S_OK; +} diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec index 6e9847770a3..bce70dcf2d3 100644 --- a/dlls/cryptxml/cryptxml.spec +++ b/dlls/cryptxml/cryptxml.spec @@ -1,5 +1,5 @@ @ stub CryptXmlAddObject -@ stub CryptXmlClose +@ stdcall CryptXmlClose(ptr) @ stub CryptXmlCreateReference @ stub CryptXmlDigestReference @ stub CryptXmlEncode diff --git a/include/cryptxml.h b/include/cryptxml.h index b11c33a37c4..388ce73ff07 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -295,6 +295,7 @@ typedef struct _CRYPT_XML_STATUS #define CRYPT_XML_STATUS_SIGNATURE_VALID 0x00010000 #define CRYPT_XML_STATUS_OPENED_TO_ENCODE 0x80000000
+HRESULT WINAPI CryptXmlClose(HCRYPTXML handle); HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/cryptxml/cryptxml.c | 12 ++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 9ed11d3d9b9..733c3f3115e 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -92,3 +92,15 @@ HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) free( doc ); return S_OK; } + +HRESULT WINAPI CryptXmlGetDocContext( HCRYPTXML handle, const CRYPT_XML_DOC_CTXT **ctx ) +{ + struct xmldoc *doc = (struct xmldoc *)handle; + + FIXME( "handle %p, ctx %p semi-stub!\n", handle, ctx ); + + if (!handle || !ctx) return E_INVALIDARG; + + *ctx = &doc->ctx; + return S_OK; +} diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec index bce70dcf2d3..af3235ae85c 100644 --- a/dlls/cryptxml/cryptxml.spec +++ b/dlls/cryptxml/cryptxml.spec @@ -6,7 +6,7 @@ @ stub CryptXmlEnumAlgorithmInfo @ stub CryptXmlFindAlgorithmInfo @ stub CryptXmlGetAlgorithmInfo -@ stub CryptXmlGetDocContext +@ stdcall CryptXmlGetDocContext(ptr ptr) @ stub CryptXmlGetReference @ stub CryptXmlGetSignature @ stub CryptXmlGetStatus diff --git a/include/cryptxml.h b/include/cryptxml.h index 388ce73ff07..81f8da9010e 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -296,6 +296,7 @@ typedef struct _CRYPT_XML_STATUS #define CRYPT_XML_STATUS_OPENED_TO_ENCODE 0x80000000
HRESULT WINAPI CryptXmlClose(HCRYPTXML handle); +HRESULT WINAPI CryptXmlGetDocContext(HCRYPTXML handle, const CRYPT_XML_DOC_CTXT **context); HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/cryptxml/cryptxml.c | 17 +++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 733c3f3115e..59f1235bdcf 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -104,3 +104,20 @@ HRESULT WINAPI CryptXmlGetDocContext( HCRYPTXML handle, const CRYPT_XML_DOC_CTXT *ctx = &doc->ctx; return S_OK; } + +HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE **sig ) +{ + CRYPT_XML_SIGNATURE *signature = (CRYPT_XML_SIGNATURE *)handle; + + FIXME( "handle %p, sig %p semi-stub!\n", handle, sig ); + + if (!handle || !sig) return E_INVALIDARG; + if (signature->cbSize != sizeof( CRYPT_XML_SIGNATURE )) + { + *sig = NULL; + return CRYPT_XML_E_HANDLE; + } + + *sig = signature; + return S_OK; +} diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec index af3235ae85c..245b46a6bf2 100644 --- a/dlls/cryptxml/cryptxml.spec +++ b/dlls/cryptxml/cryptxml.spec @@ -8,7 +8,7 @@ @ stub CryptXmlGetAlgorithmInfo @ stdcall CryptXmlGetDocContext(ptr ptr) @ stub CryptXmlGetReference -@ stub CryptXmlGetSignature +@ stdcall CryptXmlGetSignature(ptr ptr) @ stub CryptXmlGetStatus @ stub CryptXmlGetTransforms @ stub CryptXmlImportPublicKey diff --git a/include/cryptxml.h b/include/cryptxml.h index 81f8da9010e..a72abcfda5d 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -29,6 +29,27 @@ extern "C" {
typedef void *HCRYPTXML;
+#define CRYPT_XML_E_BASE _HRESULT_TYPEDEF_(0x80092100) +#define CRYPT_XML_E_LARGE _HRESULT_TYPEDEF_(0x80092101) +#define CRYPT_XML_E_TOO_MANY_TRANSFORMS _HRESULT_TYPEDEF_(0x80092102) +#define CRYPT_XML_E_ENCODING _HRESULT_TYPEDEF_(0x80092103) +#define CRYPT_XML_E_ALGORITHM _HRESULT_TYPEDEF_(0x80092104) +#define CRYPT_XML_E_TRANSFORM _HRESULT_TYPEDEF_(0x80092105) +#define CRYPT_XML_E_HANDLE _HRESULT_TYPEDEF_(0x80092106) +#define CRYPT_XML_E_OPERATION _HRESULT_TYPEDEF_(0x80092107) +#define CRYPT_XML_E_UNRESOLVED_REFERENCE _HRESULT_TYPEDEF_(0x80092108) +#define CRYPT_XML_E_INVALID_DIGEST _HRESULT_TYPEDEF_(0x80092109) +#define CRYPT_XML_E_INVALID_SIGNATURE _HRESULT_TYPEDEF_(0x8009210A) +#define CRYPT_XML_E_HASH_FAILED _HRESULT_TYPEDEF_(0x8009210B) +#define CRYPT_XML_E_SIGN_FAILED _HRESULT_TYPEDEF_(0x8009210C) +#define CRYPT_XML_E_VERIFY_FAILED _HRESULT_TYPEDEF_(0x8009210D) +#define CRYPT_XML_E_TOO_MANY_SIGNATURES _HRESULT_TYPEDEF_(0x8009210E) +#define CRYPT_XML_E_INVALID_KEYVALUE _HRESULT_TYPEDEF_(0x8009210F) +#define CRYPT_XML_E_UNEXPECTED_XML _HRESULT_TYPEDEF_(0x80092110) +#define CRYPT_XML_E_SIGNER _HRESULT_TYPEDEF_(0x80092111) +#define CRYPT_XML_E_NON_UNIQUE_ID _HRESULT_TYPEDEF_(0x80092112) +#define CRYPT_XML_E_LAST _HRESULT_TYPEDEF_(0x80092112) + #define CRYPT_XML_FLAG_NO_SERIALIZE 0x80000000 #define CRYPT_XML_FLAG_ALWAYS_RETURN_ENCODED_OBJECT 0x40000000 #define CRYPT_XML_FLAG_ENFORCE_ID_NCNAME_FORMAT 0x20000000 @@ -297,6 +318,7 @@ typedef struct _CRYPT_XML_STATUS
HRESULT WINAPI CryptXmlClose(HCRYPTXML handle); HRESULT WINAPI CryptXmlGetDocContext(HCRYPTXML handle, const CRYPT_XML_DOC_CTXT **context); +HRESULT WINAPI CryptXmlGetSignature(HCRYPTXML handle, const CRYPT_XML_SIGNATURE **signature); HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Lenovo USBRecoveryCreator. --- dlls/cryptxml/cryptxml.c | 19 +++++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 59f1235bdcf..63b2ca7c376 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -121,3 +121,22 @@ HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE *sig = signature; return S_OK; } + +HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) +{ + CRYPT_XML_SIGNATURE *sig = (CRYPT_XML_SIGNATURE *)handle; + struct xmldoc *doc; + + FIXME( "handle %p, key %p, flags %lx stub!\n", handle, key, flags ); + + if (!handle) return E_INVALIDARG; + if (sig->cbSize != sizeof( CRYPT_XML_SIGNATURE )) return CRYPT_XML_E_HANDLE; + + doc = CONTAINING_RECORD( sig, struct xmldoc, sig ); + + doc->status.cbSize = sizeof( CRYPT_XML_STATUS ); + doc->status.dwErrorStatus = CRYPT_XML_STATUS_NO_ERROR; + doc->status.dwInfoStatus = CRYPT_XML_STATUS_SIGNATURE_VALID; + + return S_OK; +} diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec index 245b46a6bf2..a1c37493e7b 100644 --- a/dlls/cryptxml/cryptxml.spec +++ b/dlls/cryptxml/cryptxml.spec @@ -16,4 +16,4 @@ @ stub CryptXmlOpenToEncode @ stub CryptXmlSetHMACSecret @ stub CryptXmlSign -@ stub CryptXmlVerifySignature +@ stdcall CryptXmlVerifySignature(ptr ptr long) diff --git a/include/cryptxml.h b/include/cryptxml.h index a72abcfda5d..822a32e12b2 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -321,6 +321,7 @@ HRESULT WINAPI CryptXmlGetDocContext(HCRYPTXML handle, const CRYPT_XML_DOC_CTXT HRESULT WINAPI CryptXmlGetSignature(HCRYPTXML handle, const CRYPT_XML_SIGNATURE **signature); HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle); +HRESULT WINAPI CryptXmlVerifySignature(HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags);
#ifdef __cplusplus }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Lenovo USBRecoveryCreator. --- dlls/cryptxml/cryptxml.c | 12 ++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 63b2ca7c376..7f50e054109 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -122,6 +122,18 @@ HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE return S_OK; }
+HRESULT WINAPI CryptXmlGetStatus( HCRYPTXML handle, CRYPT_XML_STATUS *status ) +{ + struct xmldoc *doc = (struct xmldoc *)handle; + + TRACE( "handle %p, status %p\n", handle, status ); + + if (!handle || !status) return E_INVALIDARG; + + *status = doc->status; + return S_OK; +} + HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) { CRYPT_XML_SIGNATURE *sig = (CRYPT_XML_SIGNATURE *)handle; diff --git a/dlls/cryptxml/cryptxml.spec b/dlls/cryptxml/cryptxml.spec index a1c37493e7b..4beb91a9c5d 100644 --- a/dlls/cryptxml/cryptxml.spec +++ b/dlls/cryptxml/cryptxml.spec @@ -9,7 +9,7 @@ @ stdcall CryptXmlGetDocContext(ptr ptr) @ stub CryptXmlGetReference @ stdcall CryptXmlGetSignature(ptr ptr) -@ stub CryptXmlGetStatus +@ stdcall CryptXmlGetStatus(ptr ptr) @ stub CryptXmlGetTransforms @ stub CryptXmlImportPublicKey @ stdcall CryptXmlOpenToDecode(ptr long ptr long ptr ptr) diff --git a/include/cryptxml.h b/include/cryptxml.h index 822a32e12b2..d5682210331 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -319,6 +319,7 @@ typedef struct _CRYPT_XML_STATUS HRESULT WINAPI CryptXmlClose(HCRYPTXML handle); HRESULT WINAPI CryptXmlGetDocContext(HCRYPTXML handle, const CRYPT_XML_DOC_CTXT **context); HRESULT WINAPI CryptXmlGetSignature(HCRYPTXML handle, const CRYPT_XML_SIGNATURE **signature); +HRESULT WINAPI CryptXmlGetStatus(HCRYPTXML handle, CRYPT_XML_STATUS *status); HRESULT WINAPI CryptXmlOpenToDecode(const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *config, DWORD flags, const CRYPT_XML_PROPERTY *property, ULONG property_count, const CRYPT_XML_BLOB *blob, HCRYPTXML *handle); HRESULT WINAPI CryptXmlVerifySignature(HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 1 + dlls/cryptxml/Makefile.in | 3 +- dlls/cryptxml/tests/Makefile.in | 5 + dlls/cryptxml/tests/cryptxml.c | 157 ++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 dlls/cryptxml/tests/Makefile.in create mode 100644 dlls/cryptxml/tests/cryptxml.c
diff --git a/configure.ac b/configure.ac index 83778c2882a..ed5097e245a 100644 --- a/configure.ac +++ b/configure.ac @@ -2530,6 +2530,7 @@ WINE_CONFIG_MAKEFILE(dlls/cryptsp) WINE_CONFIG_MAKEFILE(dlls/cryptui) WINE_CONFIG_MAKEFILE(dlls/cryptui/tests) WINE_CONFIG_MAKEFILE(dlls/cryptxml) +WINE_CONFIG_MAKEFILE(dlls/cryptxml/tests) WINE_CONFIG_MAKEFILE(dlls/ctapi32) WINE_CONFIG_MAKEFILE(dlls/ctl3d.dll16) WINE_CONFIG_MAKEFILE(dlls/ctl3d32) diff --git a/dlls/cryptxml/Makefile.in b/dlls/cryptxml/Makefile.in index 1fe91fe7019..49414e3cfd8 100644 --- a/dlls/cryptxml/Makefile.in +++ b/dlls/cryptxml/Makefile.in @@ -1,4 +1,5 @@ -MODULE = cryptxml.dll +MODULE = cryptxml.dll +IMPORTLIB = cryptxml
SOURCES = \ cryptxml.c diff --git a/dlls/cryptxml/tests/Makefile.in b/dlls/cryptxml/tests/Makefile.in new file mode 100644 index 00000000000..82a24b26f4d --- /dev/null +++ b/dlls/cryptxml/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = cryptxml.dll +IMPORTS = cryptxml + +SOURCES = \ + cryptxml.c diff --git a/dlls/cryptxml/tests/cryptxml.c b/dlls/cryptxml/tests/cryptxml.c new file mode 100644 index 00000000000..cfefd8fd2ae --- /dev/null +++ b/dlls/cryptxml/tests/cryptxml.c @@ -0,0 +1,157 @@ +/* CryptXML Tests + * + * Copyright (C) 2025 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "cryptxml.h" + +#include "wine/test.h" + +static void test_verify_signature(void) +{ + static const BYTE signature[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<Envelope xmlns="urn:envelope">" + "<Signature xmlns="http://www.w3.org/2000/09/xmldsig#%5C%22%3E" + "<SignedInfo>" + "<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments%5C%22/%3E" + "<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1%5C%22/%3E" + "<Reference URI="">" + "<Transforms>" + "<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature%5C%22/%3E" + "</Transforms>" + "<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1%5C%22/%3E" + "<DigestValue>uooqbWYa5VCqcJCbuymBKqm17vY=</DigestValue>" + "</Reference>" + "</SignedInfo>" + "<SignatureValue>" + "KedJuTob5gtvYx9qM3k3gm7kbLBwVbEQRl26S2tmXjqNND7MRGtoew==" + "</SignatureValue>" + "<KeyInfo>" + "<KeyValue>" + "<DSAKeyValue>" + "<P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9xD7nN1kuFw==</P>" + "<Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q>" + "<G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0NogpsQW5QvnlMpA==</G>" + "<Y>qV38IqrWJG0V/mZQvRVi1OHw9Zj84nDC4jO8P0axi1gb6d+475yhMjSc/BrIVC58W3ydbkK+Ri4OKbaRZlYeRA==</Y>" + "</DSAKeyValue>" + "</KeyValue>" + "</KeyInfo>" + "</Signature>" + "</Envelope>"; + const CRYPT_XML_SIGNATURE *sig; + const CRYPT_XML_DOC_CTXT *doc; + HCRYPTXML handle = NULL; + CRYPT_XML_STATUS status; + CRYPT_XML_BLOB blob; + HRESULT hr; + + hr = CryptXmlOpenToDecode( NULL, 0, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + + handle = (HCRYPTXML)0xdeadbeef; + hr = CryptXmlOpenToDecode( NULL, 0, NULL, 0, NULL, &handle ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + ok( handle == (HCRYPTXML)0xdeadbeef, "got handle %p.\n", handle ); + + blob.dwCharset = CRYPT_XML_CHARSET_UTF8; + blob.cbData = strlen((const char *)signature) - 1; + blob.pbData = (BYTE *)signature; + hr = CryptXmlOpenToDecode( NULL, 0, NULL, 0, &blob, &handle ); + todo_wine + ok( hr == WS_E_INVALID_FORMAT, "got hr %#lx.\n", hr ); + todo_wine + ok( handle == NULL, "got handle %p.\n", handle ); + + hr = CryptXmlClose( NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + + blob.dwCharset = CRYPT_XML_CHARSET_UTF8; + blob.cbData = strlen( (const char *)signature ); + blob.pbData = (BYTE *)signature; + hr = CryptXmlOpenToDecode( NULL, 0, NULL, 0, &blob, &handle ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = CryptXmlGetStatus( handle, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = CryptXmlGetStatus( NULL, &status ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + + hr = CryptXmlGetDocContext( NULL, &doc ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = CryptXmlGetDocContext( handle, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + + hr = CryptXmlGetDocContext( handle, &doc ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( doc->cSignature == 1, "got signature count %lu\n", doc->cSignature ); + ok( doc->rgpSignature != NULL, "got NULL rgpSignature\n" ); + + hr = CryptXmlGetSignature( NULL, &sig ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = CryptXmlGetSignature( handle, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = CryptXmlGetSignature( handle, &sig ); + ok( hr == CRYPT_XML_E_HANDLE, "got hr %#lx.\n", hr ); + ok( sig == NULL, "got sig %p\n", sig ); + hr = CryptXmlGetSignature( doc->hDocCtxt, &sig ); + ok( hr == CRYPT_XML_E_HANDLE, "got hr %#lx.\n", hr ); + + hr = CryptXmlGetSignature( doc->rgpSignature[0]->hSignature, &sig ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( sig != NULL, "failed to get signature\n" ); + + status.cbSize = 0xdeadbeef; + status.dwErrorStatus = 0xdeadbeef; + status.dwInfoStatus = 0xdeadbeef; + hr = CryptXmlGetStatus( handle, &status ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( status.cbSize == sizeof( CRYPT_XML_STATUS ), "got status.cbSize %ld.\n", status.cbSize ); + ok( status.dwErrorStatus == CRYPT_XML_STATUS_ERROR_NOT_RESOLVED, "got status.dwErrorStatus %ld.\n", status.dwErrorStatus ); + ok( status.dwInfoStatus == 0, "got status.dwInfoStatus %ld.\n", status.dwInfoStatus ); + + hr = CryptXmlVerifySignature( NULL, NULL, 0 ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + hr = CryptXmlVerifySignature( handle, NULL, 0 ); + ok( hr == CRYPT_XML_E_HANDLE, "got hr %#lx.\n", hr ); + hr = CryptXmlVerifySignature( handle, sig->pKeyInfo->hVerifyKey, 0 ); + ok( hr == CRYPT_XML_E_HANDLE, "got hr %#lx.\n", hr ); + + hr = CryptXmlVerifySignature( sig->hSignature, sig->pKeyInfo->hVerifyKey, 0 ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + status.cbSize = 0xdeadbeef; + status.dwErrorStatus = 0xdeadbeef; + status.dwInfoStatus = 0xdeadbeef; + hr = CryptXmlGetStatus( handle, &status ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( status.cbSize == sizeof( CRYPT_XML_STATUS ), "got status.cbSize %ld.\n", status.cbSize ); + todo_wine + ok( status.dwErrorStatus == CRYPT_XML_STATUS_ERROR_DIGEST_INVALID, "got status.dwErrorStatus %ld.\n", status.dwErrorStatus ); + ok( status.dwInfoStatus == CRYPT_XML_STATUS_SIGNATURE_VALID, "got status.dwInfoStatus %ld.\n", status.dwInfoStatus ); + + CryptXmlClose( handle ); +} + +START_TEST(cryptxml) +{ + test_verify_signature(); +}
Hans Leidekker (@hans) commented about dlls/cryptxml/cryptxml.c:
*handle = (HCRYPTXML)doc; return S_OK;
}
+HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) +{
- struct xmldoc *doc = (struct xmldoc *)handle;
- TRACE( "handle %p\n", handle );
- if (!handle) return E_INVALIDARG;
- if (doc->sig.SignatureValue.pbData) free( doc->sig.SignatureValue.pbData );
There's no need to check the pointer.
Hans Leidekker (@hans) commented about dlls/cryptxml/cryptxml.c:
+#include <stdarg.h>
+#include "windef.h" +#include "winbase.h" +#include "cryptxml.h"
+#include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(cryptxml);
+struct xmldoc +{
- CRYPT_XML_DOC_CTXT ctx;
- CRYPT_XML_SIGNATURE sig;
- CRYPT_XML_SIGNATURE *sigs[1];
Note that this can handle only one signature per document. I doubt that there are real-world documents with more than one so let's wait and see.
Hans Leidekker (@hans) commented about dlls/cryptxml/cryptxml.c:
*ctx = &doc->ctx; return S_OK;
}
+HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE **sig ) +{
- CRYPT_XML_SIGNATURE *signature = (CRYPT_XML_SIGNATURE *)handle;
- FIXME( "handle %p, sig %p semi-stub!\n", handle, sig );
- if (!handle || !sig) return E_INVALIDARG;
- if (signature->cbSize != sizeof( CRYPT_XML_SIGNATURE ))
This won't work with a handle returned from CryptXmlOpenToDecode(). You could add a magic field to the top of `struct xmldoc` like I suggested earlier and verify that here. You should at least cast the handle to a `struct xmldoc` pointer and return the signature stored there.
Hans Leidekker (@hans) commented about dlls/cryptxml/cryptxml.c:
*sig = signature; return S_OK;
}
+HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) +{
- CRYPT_XML_SIGNATURE *sig = (CRYPT_XML_SIGNATURE *)handle;
Same here.
On Wed Jul 30 13:52:49 2025 +0000, Hans Leidekker wrote:
Note that this can handle only one signature per document. I doubt that there are real-world documents with more than one so let's wait and see.
Yeah, one signature per document. I'm not sure if you want me to change something here though?
On Wed Jul 30 14:10:19 2025 +0000, Mohamad Al-Jaf wrote:
Yeah, one signature per document. I'm not sure if you want me to change something here though?
No it's fine.