Needed by Lenovo USBRecoveryCreator.
-- v2: cryptxml/tests: Add some signature validation tests. cryptxml: Return CRYPT_XML_STATUS_SIGNATURE_VALID from CryptXmlGetStatus(). cryptxml: Add CryptXmlVerifySignature() stub. cryptxml: Implement CryptXmlGetSignature() stub. cryptxml: Implement CryptXmlGetDocContext() stub. cryptxml: Implement CryptXmlClose() stub. cryptxml: Implement CryptXmlOpenToDecode() stub. include: Add cryptxml.h.
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 | 65 +++++++++++++++++++++++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- 3 files changed, 69 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..0a32874df10 --- /dev/null +++ b/dlls/cryptxml/cryptxml.c @@ -0,0 +1,65 @@ +/* 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); + +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 ) +{ + static CRYPT_XML_SIGNED_INFO signed_info = { 0 }; + static CRYPT_XML_KEY_INFO key_info = { 0 }; + static PCRYPT_XML_SIGNATURE signatures[1]; + static CRYPT_XML_SIGNATURE signature; + static CRYPT_XML_DOC_CTXT *context; + + 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 (!(context = calloc( 1, sizeof( *context ) ))) return E_OUTOFMEMORY; + + signature.cbSize = sizeof( CRYPT_XML_SIGNATURE ); + signature.hSignature = (HCRYPTXML)&signature; + signature.wszId = L""; + signature.SignedInfo = signed_info; + signature.SignatureValue.cbData = blob->cbData; + signature.SignatureValue.pbData = blob->pbData; + signature.pKeyInfo = &key_info; + signature.cObject = 0; + signature.rgpObject = NULL; + + signatures[0] = &signature; + + context->cbSize = sizeof( *context ); + context->hDocCtxt = (HCRYPTXML)context; + context->pTransformsConfig = (CRYPT_XML_TRANSFORM_CHAIN_CONFIG *)config; + context->cSignature = 1; + context->rgpSignature = signatures; + + *handle = (HCRYPTXML)context; + 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
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- dlls/cryptxml/cryptxml.c | 10 ++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 0a32874df10..8b8c9217641 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -63,3 +63,13 @@ HRESULT WINAPI CryptXmlOpenToDecode( const CRYPT_XML_TRANSFORM_CHAIN_CONFIG *con *handle = (HCRYPTXML)context; return S_OK; } + +HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) +{ + FIXME( "handle %p stub!\n", handle ); + + if (!handle) return E_INVALIDARG; + + free( handle ); + 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 1a531f9739d..99f0a528863 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -273,6 +273,7 @@ typedef struct _CRYPT_XML_DOC_CTXT PCRYPT_XML_SIGNATURE *rgpSignature; } CRYPT_XML_DOC_CTXT, *PCRYPT_XML_DOC_CTXT;
+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 | 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 8b8c9217641..a4e146ae8ea 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -73,3 +73,16 @@ HRESULT WINAPI CryptXmlClose( HCRYPTXML handle ) free( handle ); return S_OK; } + +HRESULT WINAPI CryptXmlGetDocContext( HCRYPTXML handle, const CRYPT_XML_DOC_CTXT **context ) +{ + CRYPT_XML_DOC_CTXT *doc_context; + + FIXME( "handle %p, context %p stub!\n", handle, context ); + + if (!handle || !context) return E_INVALIDARG; + + doc_context = (CRYPT_XML_DOC_CTXT *)handle; + *context = doc_context; + 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 99f0a528863..c32caf6b10a 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -274,6 +274,7 @@ typedef struct _CRYPT_XML_DOC_CTXT } CRYPT_XML_DOC_CTXT, *PCRYPT_XML_DOC_CTXT;
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 | 19 +++++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 22 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index a4e146ae8ea..f8e378a8d7a 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -86,3 +86,22 @@ HRESULT WINAPI CryptXmlGetDocContext( HCRYPTXML handle, const CRYPT_XML_DOC_CTXT *context = doc_context; return S_OK; } + +HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE **signature ) +{ + CRYPT_XML_SIGNATURE *sig; + + FIXME( "handle %p, signature %p stub!\n", handle, signature ); + + if (!handle || !signature) return E_INVALIDARG; + + sig = (CRYPT_XML_SIGNATURE *)handle; + if (sig->cbSize != sizeof( CRYPT_XML_SIGNATURE )) + { + *signature = NULL; + return CRYPT_XML_E_HANDLE; + } + + *signature = 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 c32caf6b10a..8faa44f8276 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 @@ -275,6 +296,7 @@ typedef struct _CRYPT_XML_DOC_CTXT
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 | 22 +++++++++++++++++++--- dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 1 + 3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index f8e378a8d7a..7d90cd263e3 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -87,6 +87,13 @@ HRESULT WINAPI CryptXmlGetDocContext( HCRYPTXML handle, const CRYPT_XML_DOC_CTXT return S_OK; }
+static BOOL is_handle_signature( HCRYPTXML handle ) +{ + CRYPT_XML_SIGNATURE *sig = (CRYPT_XML_SIGNATURE *)handle; + if (sig->cbSize != sizeof( CRYPT_XML_SIGNATURE )) return FALSE; + return TRUE; +} + HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE **signature ) { CRYPT_XML_SIGNATURE *sig; @@ -94,14 +101,23 @@ HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE FIXME( "handle %p, signature %p stub!\n", handle, signature );
if (!handle || !signature) return E_INVALIDARG; - - sig = (CRYPT_XML_SIGNATURE *)handle; - if (sig->cbSize != sizeof( CRYPT_XML_SIGNATURE )) + if (!(is_handle_signature( handle ))) { *signature = NULL; return CRYPT_XML_E_HANDLE; }
+ sig = (CRYPT_XML_SIGNATURE *)handle; *signature = sig; return S_OK; } + +HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) +{ + FIXME( "handle %p, key %p, flags %lx, stub!\n", handle, key, flags ); + + if (!handle) return E_INVALIDARG; + if (!(is_handle_signature( handle ))) return CRYPT_XML_E_HANDLE; + + 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 8faa44f8276..4a72de68626 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -299,6 +299,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 | 16 ++++++++++++++++ dlls/cryptxml/cryptxml.spec | 2 +- include/cryptxml.h | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/dlls/cryptxml/cryptxml.c b/dlls/cryptxml/cryptxml.c index 7d90cd263e3..ce19d1afba3 100644 --- a/dlls/cryptxml/cryptxml.c +++ b/dlls/cryptxml/cryptxml.c @@ -112,6 +112,22 @@ HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE return S_OK; }
+HRESULT WINAPI CryptXmlGetStatus( HCRYPTXML handle, CRYPT_XML_STATUS *status ) +{ + CRYPT_XML_STATUS ret_status; + + FIXME( "handle %p, status %p stub!\n", handle, status ); + + if (!handle || !status) return E_INVALIDARG; + + ret_status.cbSize = sizeof( CRYPT_XML_STATUS ); + ret_status.dwErrorStatus = CRYPT_XML_STATUS_NO_ERROR; + ret_status.dwInfoStatus = CRYPT_XML_STATUS_SIGNATURE_VALID; + + *status = ret_status; + return S_OK; +} + HRESULT WINAPI CryptXmlVerifySignature( HCRYPTXML handle, BCRYPT_KEY_HANDLE key, DWORD flags ) { FIXME( "handle %p, key %p, flags %lx, stub!\n", handle, key, flags ); 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 4a72de68626..d5682210331 100644 --- a/include/cryptxml.h +++ b/include/cryptxml.h @@ -294,9 +294,32 @@ 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 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 | 156 ++++++++++++++++++++++++++++++++ 4 files changed, 164 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..946163291fe --- /dev/null +++ b/dlls/cryptxml/tests/cryptxml.c @@ -0,0 +1,156 @@ +/* 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_validate_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->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 ); + todo_wine + ok( status.dwErrorStatus == CRYPT_XML_STATUS_ERROR_NOT_RESOLVED, "got status.dwErrorStatus %ld.\n", status.dwErrorStatus ); + todo_wine + 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_validate_signature(); +}
Hans Leidekker (@hans) commented about dlls/cryptxml/cryptxml.c:
- signature.SignedInfo = signed_info;
- signature.SignatureValue.cbData = blob->cbData;
- signature.SignatureValue.pbData = blob->pbData;
- signature.pKeyInfo = &key_info;
- signature.cObject = 0;
- signature.rgpObject = NULL;
- signatures[0] = &signature;
- context->cbSize = sizeof( *context );
- context->hDocCtxt = (HCRYPTXML)context;
- context->pTransformsConfig = (CRYPT_XML_TRANSFORM_CHAIN_CONFIG *)config;
- context->cSignature = 1;
- context->rgpSignature = signatures;
- *handle = (HCRYPTXML)context;
I know it's a stub but using static variables is not thread-safe. You should also (deep) copy the config and blob parameters since they may not survive after the call returns. Ignoring the optional config parameter for now is fine too. I would define a structure that holds everything needed and return that in the handle parameter, something like this:
``` struct xmldoc { ULONG magic; CRYPT_XML_DOC_CTXT ctx; CRYPT_XML_SIGNATURE sig; } ```