wine/dlls/cryptxml/cryptxml.c
Mohamad Al-Jaf 1af15b6e14 cryptxml: Implement CryptXmlGetStatus().
Needed by Lenovo USBRecoveryCreator.
2025-08-18 13:10:21 +02:00

204 lines
5.6 KiB
C

/* 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;
}
HRESULT WINAPI CryptXmlClose( HCRYPTXML handle )
{
struct object *obj = (struct object *)handle;
TRACE( "handle %p\n", handle );
if (!obj) return E_INVALIDARG;
switch (obj->magic)
{
case DOC_MAGIC:
{
struct xmldoc *doc = (struct xmldoc *)obj;
const CRYPT_XML_SIGNATURE *sig = doc->ctx.rgpSignature[0];
struct signature *sig_obj = CONTAINING_RECORD( sig, struct signature, sig );
free( sig_obj );
break;
}
case SIG_MAGIC:
return S_FALSE;
default:
FIXME( "unhandled object magic %lx\n", obj->magic );
return E_NOTIMPL;
}
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;
}
HRESULT WINAPI CryptXmlGetSignature( HCRYPTXML handle, const CRYPT_XML_SIGNATURE **ret_sig )
{
struct signature *sig = (struct signature *)handle;
TRACE( "handle %p, ret_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;
}
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;
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;
}