/
githubmirror
/
xmlsec
Обзор
Документация
Войти
/
githubmirror
/
xmlsec
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/mscng/der_encoded_value.c
227 строк
8 KB
lsh123
Update file headers for doxygen, use common copyright header, bump copyright to 2026 (#1122)
07 апр 2026, 04:13
Не верифицирован
07 апр 2026, 04:13
2e557ee
Код
Авторство
О чём код?
/** * XML Security Library (http://www.aleksey.com/xmlsec). * * This is free software; see the Copyright file in the source distribution for precise wording. * * Copyright (C) 2018-2026 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. */ /** * @addtogroup xmlsec_mscng_crypto * @brief DEREncodedKeyValue processing for MSCng. */ #include "globals.h" #include <xmlsec/xmlsec.h> #include <xmlsec/base64.h> #include <xmlsec/errors.h> #include <xmlsec/keyinfo.h> #include <xmlsec/keys.h> #include <xmlsec/private.h> #include <xmlsec/xmltree.h> #include <xmlsec/mscng/certkeys.h> #include <xmlsec/mscng/crypto.h> #include "../cast_helpers.h" #include "private.h" /****************************************************************************** * * <dsig11:DEREncodedKeyValue /> processing * *****************************************************************************/ static int xmlSecMSCngKeyDataDEREncodedKeyValueXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx); static int xmlSecMSCngKeyDataDEREncodedKeyValueXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx); static xmlSecKeyDataKlass xmlSecMSCngKeyDataDEREncodedKeyValueKlass = { sizeof(xmlSecKeyDataKlass), sizeof(xmlSecKeyData), /* data */ xmlSecNameDEREncodedKeyValue, xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml, /* xmlSecKeyDataUsage usage; */ NULL, /* const xmlChar* href; */ xmlSecNodeDEREncodedKeyValue, /* const xmlChar* dataNodeName; */ xmlSecDSig11Ns, /* const xmlChar* dataNodeNs; */ /* constructors/destructor */ NULL, /* xmlSecKeyDataInitializeMethod initialize; */ NULL, /* xmlSecKeyDataDuplicateMethod duplicate; */ NULL, /* xmlSecKeyDataFinalizeMethod finalize; */ NULL, /* xmlSecKeyDataGenerateMethod generate; */ /* get info */ NULL, /* xmlSecKeyDataGetTypeMethod getType; */ NULL, /* xmlSecKeyDataGetSizeMethod getSize; */ NULL, /* DEPRECATED xmlSecKeyDataGetIdentifier getIdentifier; */ /* read/write */ xmlSecMSCngKeyDataDEREncodedKeyValueXmlRead, /* xmlSecKeyDataXmlReadMethod xmlRead; */ xmlSecMSCngKeyDataDEREncodedKeyValueXmlWrite, /* xmlSecKeyDataXmlWriteMethod xmlWrite; */ NULL, /* xmlSecKeyDataBinReadMethod binRead; */ NULL, /* xmlSecKeyDataBinWriteMethod binWrite; */ /* debug */ NULL, /* xmlSecKeyDataDebugDumpMethod debugDump; */ NULL, /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */ /* reserved for the future */ NULL, /* void* reserved0; */ NULL, /* void* reserved1; */ }; /** * The public key algorithm and value are DER-encoded in accordance with the value that would be used * in the Subject Public Key Info field of an X.509 certificate, per section 4.1.2.7 of [RFC5280]. * The DER-encoded value is then base64-encoded. * * https://www.w3.org/TR/xmldsig-core1/#sec-DEREncodedKeyValue * * @code{.xml} * <!-- targetNamespace="http://www.w3.org/2009/xmldsig11#" --> * <element name="DEREncodedKeyValue" type="dsig11:DEREncodedKeyValueType" /> * <complexType name="DEREncodedKeyValueType"> * <simpleContent> * <extension base="base64Binary"> * <attribute name="Id" type="ID" use="optional"/> * </extension> * </simpleContent> * </complexType> * @endcode * * @return the <dsig11:DEREncodedKeyValue/>element processing key data klass. */ xmlSecKeyDataId xmlSecMSCngKeyDataDEREncodedKeyValueGetKlass(void) { return(&xmlSecMSCngKeyDataDEREncodedKeyValueKlass); } static int xmlSecMSCngKeyDataDEREncodedKeyValueXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlSecBuffer buffer; const xmlSecByte* data; xmlSecSize dataSize; DWORD dataLen; xmlSecKeyDataPtr keyData = NULL; xmlNodePtr cur; int res = -1; int ret; xmlSecAssert2(id == xmlSecMSCngKeyDataDEREncodedKeyValueId, -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(node != NULL, -1); xmlSecAssert2(node->doc != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1); ret = xmlSecBufferInitialize(&buffer, 256); if(ret < 0) { xmlSecInternalError("xmlSecBufferInitialize", xmlSecKeyDataKlassGetName(id)); return(-1); } /* no children are expected */ cur = xmlSecGetNextElementNode(node->children); if(cur != NULL) { xmlSecUnexpectedNodeError(cur, xmlSecKeyDataKlassGetName(id)); goto done; } /* read base64 node content */ ret = xmlSecBufferBase64NodeContentRead(&buffer, node); if(ret < 0) { xmlSecInternalError("xmlSecBufferBase64NodeContentRead", xmlSecKeyDataKlassGetName(id)); goto done; } data = xmlSecBufferGetData(&buffer); dataSize = xmlSecBufferGetSize(&buffer); if((data == NULL) || (dataSize <= 0)) { /* this is not an error if we are reading a doc to be encrypted or signed */ res = 0; goto done; } /* read key from DER (SPKI public key) */ XMLSEC_SAFE_CAST_SIZE_TO_ULONG(dataSize, dataLen, goto done, xmlSecKeyDataKlassGetName(id)); keyData = xmlSecMSCngAppKeyReadPubKeyFromDer(data, dataLen); if(keyData == NULL) { xmlSecInternalError("xmlSecMSCngAppKeyLoadPubKeyDerMemory", xmlSecKeyDataKlassGetName(id)); goto done; } ret = xmlSecKeySetValue(key, keyData); if(ret < 0) { xmlSecInternalError("xmlSecKeySetValue", xmlSecKeyDataKlassGetName(id)); goto done; } keyData = NULL; /* owned by key now */ /* success! */ res = 0; done: if(keyData != NULL) { xmlSecKeyDataDestroy(keyData); } xmlSecBufferFinalize(&buffer); return(res); } static int xmlSecMSCngKeyDataDEREncodedKeyValueXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) { xmlSecKeyDataPtr keyData; LPVOID keyDer = NULL; DWORD keyDerLen = 0; xmlChar* content = NULL; int res = -1; int ret; xmlSecAssert2(id == xmlSecMSCngKeyDataDEREncodedKeyValueId, -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(node != NULL, -1); xmlSecAssert2(keyInfoCtx != NULL, -1); xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeWrite, -1); /* get pubkey */ keyData = xmlSecKeyGetValue(key); if(keyData == NULL) { xmlSecInternalError("xmlSecKeyGetValue", xmlSecKeyDataKlassGetName(id)); goto done; } /* build DER encoded subject public key info */ ret = xmlSecMSCngCreateDerForBcryptPubkey(keyData, &keyDer, &keyDerLen); if(ret < 0) { xmlSecInternalError("xmlSecMSCngCreateDerForBcryptPubkey", xmlSecKeyDataKlassGetName(id)); goto done; } /* write to XML */ content = xmlSecBase64Encode(keyDer, keyDerLen, xmlSecBase64GetDefaultLineSize()); if(content == NULL) { xmlSecInternalError("xmlSecBase64Encode", xmlSecKeyDataKlassGetName(id)); goto done; } xmlNodeAddContent(node, content); /* success */ res = 0; done: if(keyDer != NULL) { LocalFree(keyDer); } if(content != NULL) { xmlFree(content); } return(res); }