Needed by Lenovo USBRecoveryCreator.
-- v8: cryptxml/tests: Add some signature verification tests. cryptxml: Implement CryptXmlGetStatus(). cryptxml: Implement CryptXmlVerifySignature() stub. cryptxml: Implement CryptXmlGetSignature(). cryptxml: Implement CryptXmlGetDocContext(). cryptxml: Implement CryptXmlClose(). cryptxml: Implement CryptXmlOpenToDecode() stub.
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 | 114 ++++++++++++++++++++++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 22 +++++++ 4 files changed, 140 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..ad22e232bac --- /dev/null +++ b/dlls/cryptxml/cryptxml.c @@ -0,0 +1,114 @@ +/* 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); + +#define DOC_MAGIC 0x584d4c44 +#define SIG_MAGIC 0x5349474e + +struct object +{ + ULONG magic; + CRYPT_XML_STATUS status; +}; + +struct xmldoc +{ + struct object hdr; + CRYPT_XML_DOC_CTXT ctx; +}; + +struct signature +{ + struct object hdr; + CRYPT_XML_SIGNATURE sig; + CRYPT_XML_KEY_INFO key_info; + struct xmldoc *doc; +}; + +struct xmldoc *alloc_doc( void ) +{ + struct xmldoc *doc; + + if (!(doc = calloc( 1, sizeof( *doc ) + sizeof( *doc->ctx.rgpSignature ) ))) return NULL; + + doc->hdr.magic = DOC_MAGIC; + doc->hdr.status.cbSize = sizeof( doc->hdr.status ); + doc->hdr.status.dwErrorStatus = CRYPT_XML_STATUS_ERROR_NOT_RESOLVED; + + doc->ctx.cbSize = sizeof( doc->ctx ); + doc->ctx.hDocCtxt = (HCRYPTXML)doc; + doc->ctx.rgpSignature = (CRYPT_XML_SIGNATURE **)(doc + 1); + return doc; +} + +struct signature *alloc_sig( const CRYPT_XML_BLOB *blob ) +{ + struct signature *sig; + + if (!(sig = calloc( 1, sizeof( *sig ) + blob->cbData ))) return NULL; + + sig->hdr.magic = SIG_MAGIC; + sig->hdr.status.cbSize = sizeof( sig->hdr.status ); + sig->hdr.status.dwErrorStatus = CRYPT_XML_STATUS_ERROR_NOT_RESOLVED; + + sig->sig.cbSize = sizeof( sig->sig ); + sig->sig.hSignature = (HCRYPTXML)sig; + sig->sig.SignatureValue.pbData = (BYTE *)(sig + 1); + memcpy( sig->sig.SignatureValue.pbData, blob->pbData, blob->cbData ); + sig->sig.SignatureValue.cbData = blob->cbData; + + sig->sig.pKeyInfo = &sig->key_info; + return sig; +} + +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; + struct signature *sig; + + 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 (!(sig = alloc_sig( blob ))) return E_OUTOFMEMORY; + if (!(doc = alloc_doc())) + { + free( sig ); + return E_OUTOFMEMORY; + } + + doc->ctx.cSignature = 1; + doc->ctx.rgpSignature[0] = &sig->sig; + sig->doc = doc; + + *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 | 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 ad22e232bac..69ad0b70f53 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -112,3 +112,22 @@ HRESULT WINAPI CryptXmlOpenToDecode( const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *con *handle = (HCRYPTXML)doc; return S_OK; } + +HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) +{ + struct object *obj = (struct object *)handle; + struct xmldoc *doc; + struct signature *sig; + + TRACE( "handle %p\n", handle ); + + if (!obj) return E_INVALIDARG; + if (obj->magic != DOC_MAGIC) return S_FALSE; + + doc = (struct xmldoc *)obj; + sig = (struct signature *)doc->ctx.rgpSignature[0]; + + free( sig ); + free( obj ); + 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 | 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 69ad0b70f53..a1b4b7f1df3 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -131,3 +131,20 @@ HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) free( obj ); return S_OK; } + +HRESULT WINAPI CryptXmlGetDocContext( HCRYPTXML handle, const CRYPT_XML_DOC_CTXT **ctx ) +{ + struct xmldoc *doc = (struct xmldoc *)handle; + + TRACE( "handle %p, ctx %p\n", handle, ctx ); + + if (!doc || !ctx) return E_INVALIDARG; + if (doc->hdr.magic != DOC_MAGIC) + { + *ctx = NULL; + return CRYPT_XML_E_HANDLE; + } + + *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..d939935b1bb 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 @@ -296,6 +317,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 | 1 + 3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index a1b4b7f1df3..82680776f6c 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -148,3 +148,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 **ret_sig ) +{ + struct signature *sig = (struct signature *)handle; + + TRACE( "handle %p, sig %p\n", handle, ret_sig ); + + if (!sig || !ret_sig) return E_INVALIDARG; + if (sig->hdr.magic != SIG_MAGIC) + { + *ret_sig = NULL; + return CRYPT_XML_E_HANDLE; + } + + *ret_sig = &sig->sig; + 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 d939935b1bb..a72abcfda5d 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -318,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 | 14 ++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 82680776f6c..8f366901f4f 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -165,3 +165,17 @@ HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE *ret_sig = &sig->sig; return S_OK; } + +HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) +{ + struct signature *sig = (struct signature *)handle; + + FIXME( "handle %p, key %p, flags %lx stub!\n", handle, key, flags ); + + if (!sig) return E_INVALIDARG; + if (sig->hdr.magic != SIG_MAGIC) return CRYPT_XML_E_HANDLE; + + sig->hdr.status.dwErrorStatus = sig->doc->hdr.status.dwErrorStatus = CRYPT_XML_STATUS_NO_ERROR; + sig->hdr.status.dwInfoStatus = sig->doc->hdr.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 8f366901f4f..5df81fde166 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -166,6 +166,18 @@ HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE return S_OK; }
+HRESULT WINAPI CryptXmlGetStatus( HCRYPTXML handle, CRYPT_XML_STATUS *status ) +{ + struct object *obj = (struct object *)handle; + + TRACE( "handle %p, status %p\n", handle, status ); + + if (!obj || !status) return E_INVALIDARG; + + *status = obj->status; + return S_OK; +} + HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) { struct signature *sig = (struct 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 | 171 ++++++++++++++++++++++++++++++++ 4 files changed, 179 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..cb93e6a2e5c --- /dev/null +++ b/dlls/cryptxml/tests/cryptxml.c @@ -0,0 +1,171 @@ +/* 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" + +#define check_status( handle, expected_size, expected_error, expected_info, todo ) check_status_( __LINE__, handle, expected_size, expected_error, expected_info, todo ) +static void check_status_( unsigned int line, HCRYPTXML handle, ULONG expected_size, DWORD expected_error, DWORD expected_info, BOOL todo ) +{ + CRYPT_XML_STATUS status; + HRESULT hr; + + status.cbSize = 0xdeadbeef; + status.dwErrorStatus = 0xdeadbeef; + status.dwInfoStatus = 0xdeadbeef; + + hr = CryptXmlGetStatus( handle, &status ); + ok_(__FILE__, line)( hr == S_OK, "got CryptXmlGetStatus hr %#lx\n", hr ); + ok_(__FILE__, line)( status.cbSize == expected_size, "got status.cbSize = %lu\n", status.cbSize ); + todo_wine_if( todo ) ok_(__FILE__, line)( status.dwErrorStatus == expected_error, "got status.dwErrorStatus = %ld\n", status.dwErrorStatus ); + ok_(__FILE__, line)( status.dwInfoStatus == expected_info, "got status.dwInfoStatus = %ld\n", status.dwInfoStatus ); +} + +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 *ctx; + 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 ); + + ctx = (CRYPT_XML_DOC_CTXT *)0xdeadbeef; + hr = CryptXmlGetDocContext( NULL, &ctx ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + ok( ctx == (CRYPT_XML_DOC_CTXT *)0xdeadbeef, "got ctx %p\n", ctx ); + hr = CryptXmlGetDocContext( handle, NULL ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + + hr = CryptXmlGetDocContext( handle, &ctx ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( ctx->cSignature == 1, "got signature count %lu\n", ctx->cSignature ); + ok( ctx->rgpSignature != NULL, "got NULL rgpSignature\n" ); + + sig = (CRYPT_XML_SIGNATURE *)0xdeadbeef; + hr = CryptXmlGetSignature( NULL, &sig ); + ok( hr == E_INVALIDARG, "got hr %#lx.\n", hr ); + ok( sig == (CRYPT_XML_SIGNATURE *)0xdeadbeef, "got sig %p\n", sig ); + 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( ctx->rgpSignature[0]->hSignature, &sig ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + ok( sig != NULL, "failed to get signature\n" ); + ok( sig->cbSize == sizeof( CRYPT_XML_SIGNATURE ), "got sig->cbSize = %lu\n", sig->cbSize ); + + check_status( handle, sizeof( CRYPT_XML_STATUS ), CRYPT_XML_STATUS_ERROR_NOT_RESOLVED, 0, FALSE ); + + 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 ); + + check_status( handle, sizeof( CRYPT_XML_STATUS ), CRYPT_XML_STATUS_ERROR_DIGEST_INVALID, CRYPT_XML_STATUS_SIGNATURE_VALID, TRUE ); + check_status( sig->hSignature, sizeof( CRYPT_XML_STATUS ), CRYPT_XML_STATUS_ERROR_DIGEST_INVALID, CRYPT_XML_STATUS_SIGNATURE_VALID, TRUE ); + + ctx = (CRYPT_XML_DOC_CTXT *)0xdeadbeef; + hr = CryptXmlGetDocContext( sig->hSignature, &ctx ); + ok( hr == CRYPT_XML_E_HANDLE, "got hr %#lx.\n", hr ); + ok( ctx == NULL, "got ctx %p\n", ctx ); + + hr = CryptXmlClose( sig->hSignature ); + ok( hr == S_FALSE, "got hr %#lx.\n", hr ); + hr = CryptXmlClose( handle ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); +} + +START_TEST(cryptxml) +{ + test_verify_signature(); +}
On Tue Aug 5 01:52:03 2025 +0000, Nikolay Sivov wrote:
Where are the keys and signatures coming from?
From an example.
On Tue Aug 5 01:57:13 2025 +0000, Mohamad Al-Jaf wrote:
From an example.
What example? Are they under copyright?