summaryrefslogtreecommitdiff
path: root/src/keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keys.c')
-rw-r--r--src/keys.c1415
1 files changed, 1415 insertions, 0 deletions
diff --git a/src/keys.c b/src/keys.c
new file mode 100644
index 00000000..1d2f7331
--- /dev/null
+++ b/src/keys.c
@@ -0,0 +1,1415 @@
+/**
+ * XML Security Library (http://www.aleksey.com/xmlsec).
+ *
+ * Keys.
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxml/tree.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/list.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/keysmngr.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/errors.h>
+
+/**************************************************************************
+ *
+ * xmlSecKeyUseWith
+ *
+ *************************************************************************/
+/**
+ * xmlSecKeyUseWithInitialize:
+ * @keyUseWith: the pointer to information about key application/user.
+ *
+ * Initializes @keyUseWith object.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeyUseWithInitialize(xmlSecKeyUseWithPtr keyUseWith) {
+ xmlSecAssert2(keyUseWith != NULL, -1);
+
+ memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
+ return(0);
+}
+
+/**
+ * xmlSecKeyUseWithFinalize:
+ * @keyUseWith: the pointer to information about key application/user.
+ *
+ * Finalizes @keyUseWith object.
+ */
+void
+xmlSecKeyUseWithFinalize(xmlSecKeyUseWithPtr keyUseWith) {
+ xmlSecAssert(keyUseWith != NULL);
+
+ xmlSecKeyUseWithReset(keyUseWith);
+ memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
+}
+
+/**
+ * xmlSecKeyUseWithReset:
+ * @keyUseWith: the pointer to information about key application/user.
+ *
+ * Resets the @keyUseWith to its state after initialization.
+ */
+void
+xmlSecKeyUseWithReset(xmlSecKeyUseWithPtr keyUseWith) {
+ xmlSecAssert(keyUseWith != NULL);
+
+ xmlSecKeyUseWithSet(keyUseWith, NULL, NULL);
+}
+
+/**
+ * xmlSecKeyUseWithCopy:
+ * @dst: the pointer to destination object.
+ * @src: the pointer to source object.
+ *
+ * Copies information from @dst to @src.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeyUseWithCopy(xmlSecKeyUseWithPtr dst, xmlSecKeyUseWithPtr src) {
+ xmlSecAssert2(dst != NULL, -1);
+ xmlSecAssert2(src != NULL, -1);
+
+ return(xmlSecKeyUseWithSet(dst, src->application, src->identifier));
+}
+
+/**
+ * xmlSecKeyUseWithCreate:
+ * @application: the application value.
+ * @identifier: the identifier value.
+ *
+ * Creates new xmlSecKeyUseWith object. The caller is responsible for destroying
+ * returned object with @xmlSecKeyUseWithDestroy function.
+ *
+ * Returns: pointer to newly created object or NULL if an error occurs.
+ */
+xmlSecKeyUseWithPtr
+xmlSecKeyUseWithCreate(const xmlChar* application, const xmlChar* identifier) {
+ xmlSecKeyUseWithPtr keyUseWith;
+ int ret;
+
+ /* Allocate a new xmlSecKeyUseWith and fill the fields. */
+ keyUseWith = (xmlSecKeyUseWithPtr)xmlMalloc(sizeof(xmlSecKeyUseWith));
+ if(keyUseWith == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "sizeof(xmlSecKeyUseWith)=%d",
+ sizeof(xmlSecKeyUseWith));
+ return(NULL);
+ }
+ memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
+
+ ret = xmlSecKeyUseWithInitialize(keyUseWith);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyUseWithInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyUseWithDestroy(keyUseWith);
+ return(NULL);
+ }
+
+ ret = xmlSecKeyUseWithSet(keyUseWith, application, identifier);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyUseWithSet",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyUseWithDestroy(keyUseWith);
+ return(NULL);
+ }
+
+ return(keyUseWith);
+}
+
+/**
+ * xmlSecKeyUseWithDuplicate:
+ * @keyUseWith: the pointer to information about key application/user.
+ *
+ * Duplicates @keyUseWith object. The caller is responsible for destroying
+ * returned object with @xmlSecKeyUseWithDestroy function.
+ *
+ * Returns: pointer to newly created object or NULL if an error occurs.
+ */
+xmlSecKeyUseWithPtr
+xmlSecKeyUseWithDuplicate(xmlSecKeyUseWithPtr keyUseWith) {
+ int ret;
+
+ xmlSecKeyUseWithPtr newKeyUseWith;
+
+ xmlSecAssert2(keyUseWith != NULL, NULL);
+
+ newKeyUseWith = xmlSecKeyUseWithCreate(NULL, NULL);
+ if(newKeyUseWith == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyUseWithCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecKeyUseWithCopy(newKeyUseWith, keyUseWith);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyUseWithCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyUseWithDestroy(keyUseWith);
+ return(NULL);
+ }
+
+ return(newKeyUseWith);
+}
+
+/**
+ * xmlSecKeyUseWithDestroy:
+ * @keyUseWith: the pointer to information about key application/user.
+ *
+ * Destroys @keyUseWith created with @xmlSecKeyUseWithCreate or @xmlSecKeyUseWithDuplicate
+ * functions.
+ */
+void
+xmlSecKeyUseWithDestroy(xmlSecKeyUseWithPtr keyUseWith) {
+ xmlSecAssert(keyUseWith != NULL);
+
+ xmlSecKeyUseWithFinalize(keyUseWith);
+ xmlFree(keyUseWith);
+}
+
+/**
+ * xmlSecKeyUseWithSet:
+ * @keyUseWith: the pointer to information about key application/user.
+ * @application: the new application value.
+ * @identifier: the new identifier value.
+ *
+ * Sets @application and @identifier in the @keyUseWith.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeyUseWithSet(xmlSecKeyUseWithPtr keyUseWith, const xmlChar* application, const xmlChar* identifier) {
+ xmlSecAssert2(keyUseWith != NULL, -1);
+
+ if(keyUseWith->application != NULL) {
+ xmlFree(keyUseWith->application);
+ keyUseWith->application = NULL;
+ }
+ if(keyUseWith->identifier != NULL) {
+ xmlFree(keyUseWith->identifier);
+ keyUseWith->identifier = NULL;
+ }
+
+ if(application != NULL) {
+ keyUseWith->application = xmlStrdup(application);
+ if(keyUseWith->application == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "xmlStrlen(application)=%d",
+ xmlStrlen(application));
+ return(-1);
+ }
+ }
+ if(identifier != NULL) {
+ keyUseWith->identifier = xmlStrdup(identifier);
+ if(keyUseWith->identifier == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "xmlStrlen(identifier)=%d",
+ xmlStrlen(identifier));
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecKeyUseWithDebugDump:
+ * @keyUseWith: the pointer to information about key application/user.
+ * @output: the pointer to output FILE.
+ *
+ * Prints xmlSecKeyUseWith debug information to a file @output.
+ */
+void
+xmlSecKeyUseWithDebugDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
+ xmlSecAssert(keyUseWith != NULL);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "=== KeyUseWith: application=\"%s\",identifier=\"%s\"\n",
+ (keyUseWith->application) ? keyUseWith->application : BAD_CAST "",
+ (keyUseWith->identifier) ? keyUseWith->identifier : BAD_CAST "");
+}
+
+/**
+ * xmlSecKeyUseWithDebugXmlDump:
+ * @keyUseWith: the pointer to information about key application/user.
+ * @output: the pointer to output FILE.
+ *
+ * Prints xmlSecKeyUseWith debug information to a file @output in XML format.
+ */
+void
+xmlSecKeyUseWithDebugXmlDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
+ xmlSecAssert(keyUseWith != NULL);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<KeyUseWith>\n");
+
+ fprintf(output, "<Application>");
+ xmlSecPrintXmlString(output, keyUseWith->application);
+ fprintf(output, "</Application>");
+
+ fprintf(output, "<Identifier>");
+ xmlSecPrintXmlString(output, keyUseWith->identifier);
+ fprintf(output, "</Identifier>");
+
+ fprintf(output, "</KeyUseWith>\n");
+}
+
+/***********************************************************************
+ *
+ * KeyUseWith list
+ *
+ **********************************************************************/
+static xmlSecPtrListKlass xmlSecKeyUseWithPtrListKlass = {
+ BAD_CAST "key-use-with-list",
+ (xmlSecPtrDuplicateItemMethod)xmlSecKeyUseWithDuplicate, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ (xmlSecPtrDestroyItemMethod)xmlSecKeyUseWithDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+/**
+ * xmlSecKeyUseWithPtrListGetKlass:
+ *
+ * The key data list klass.
+ *
+ * Returns: pointer to the key data list klass.
+ */
+xmlSecPtrListId
+xmlSecKeyUseWithPtrListGetKlass(void) {
+ return(&xmlSecKeyUseWithPtrListKlass);
+}
+
+/**************************************************************************
+ *
+ * xmlSecKeyReq - what key are we looking for?
+ *
+ *************************************************************************/
+/**
+ * xmlSecKeyReqInitialize:
+ * @keyReq: the pointer to key requirements object.
+ *
+ * Initialize key requirements object. Caller is responsible for
+ * cleaning it with #xmlSecKeyReqFinalize function.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeyReqInitialize(xmlSecKeyReqPtr keyReq) {
+ int ret;
+
+ xmlSecAssert2(keyReq != NULL, -1);
+
+ memset(keyReq, 0, sizeof(xmlSecKeyReq));
+
+ keyReq->keyUsage = xmlSecKeyUsageAny; /* by default you can do whatever you want with the key */
+ ret = xmlSecPtrListInitialize(&keyReq->keyUseWithList, xmlSecKeyUseWithPtrListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+
+ return(0);
+}
+
+/**
+ * xmlSecKeyReqFinalize:
+ * @keyReq: the pointer to key requirements object.
+ *
+ * Cleans the key requirements object initialized with #xmlSecKeyReqInitialize
+ * function.
+ */
+void
+xmlSecKeyReqFinalize(xmlSecKeyReqPtr keyReq) {
+ xmlSecAssert(keyReq != NULL);
+
+ xmlSecPtrListFinalize(&keyReq->keyUseWithList);
+ memset(keyReq, 0, sizeof(xmlSecKeyReq));
+}
+
+/**
+ * xmlSecKeyReqReset:
+ * @keyReq: the pointer to key requirements object.
+ *
+ * Resets key requirements object for new key search.
+ */
+void
+xmlSecKeyReqReset(xmlSecKeyReqPtr keyReq) {
+ xmlSecAssert(keyReq != NULL);
+
+ xmlSecPtrListEmpty(&keyReq->keyUseWithList);
+ keyReq->keyId = NULL;
+ keyReq->keyType = 0;
+ keyReq->keyUsage = xmlSecKeyUsageAny;
+ keyReq->keyBitsSize = 0;
+}
+
+/**
+ * xmlSecKeyReqCopy:
+ * @dst: the pointer to destination object.
+ * @src: the pointer to source object.
+ *
+ * Copies key requirements from @src object to @dst object.
+ *
+ * Returns: 0 on success and a negative value if an error occurs.
+ */
+int
+xmlSecKeyReqCopy(xmlSecKeyReqPtr dst, xmlSecKeyReqPtr src) {
+ int ret;
+
+ xmlSecAssert2(dst != NULL, -1);
+ xmlSecAssert2(src != NULL, -1);
+
+ dst->keyId = src->keyId;
+ dst->keyType = src->keyType;
+ dst->keyUsage = src->keyUsage;
+ dst->keyBitsSize = src->keyBitsSize;
+
+ ret = xmlSecPtrListCopy(&dst->keyUseWithList, &src->keyUseWithList);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecKeyReqMatchKey:
+ * @keyReq: the pointer to key requirements object.
+ * @key: the pointer to key.
+ *
+ * Checks whether @key matches key requirements @keyReq.
+ *
+ * Returns: 1 if key matches requirements, 0 if not and a negative value
+ * if an error occurs.
+ */
+int
+xmlSecKeyReqMatchKey(xmlSecKeyReqPtr keyReq, xmlSecKeyPtr key) {
+ xmlSecAssert2(keyReq != NULL, -1);
+ xmlSecAssert2(xmlSecKeyIsValid(key), -1);
+
+ if((keyReq->keyType != xmlSecKeyDataTypeUnknown) && ((xmlSecKeyGetType(key) & keyReq->keyType) == 0)) {
+ return(0);
+ }
+ if((keyReq->keyUsage != xmlSecKeyDataUsageUnknown) && ((keyReq->keyUsage & key->usage) == 0)) {
+ return(0);
+ }
+
+ return(xmlSecKeyReqMatchKeyValue(keyReq, xmlSecKeyGetValue(key)));
+}
+
+/**
+ * xmlSecKeyReqMatchKeyValue:
+ * @keyReq: the pointer to key requirements.
+ * @value: the pointer to key value.
+ *
+ * Checks whether @keyValue matches key requirements @keyReq.
+ *
+ * Returns: 1 if key value matches requirements, 0 if not and a negative value
+ * if an error occurs.
+ */
+int
+xmlSecKeyReqMatchKeyValue(xmlSecKeyReqPtr keyReq, xmlSecKeyDataPtr value) {
+ xmlSecAssert2(keyReq != NULL, -1);
+ xmlSecAssert2(value != NULL, -1);
+
+ if((keyReq->keyId != xmlSecKeyDataIdUnknown) &&
+ (!xmlSecKeyDataCheckId(value, keyReq->keyId))) {
+
+ return(0);
+ }
+ if((keyReq->keyBitsSize > 0) &&
+ (xmlSecKeyDataGetSize(value) > 0) &&
+ (xmlSecKeyDataGetSize(value) < keyReq->keyBitsSize)) {
+
+ return(0);
+ }
+ return(1);
+}
+
+/**
+ * xmlSecKeyReqDebugDump:
+ * @keyReq: the pointer to key requirements object.
+ * @output: the pointer to output FILE.
+ *
+ * Prints debug information about @keyReq into @output.
+ */
+void
+xmlSecKeyReqDebugDump(xmlSecKeyReqPtr keyReq, FILE* output) {
+ xmlSecAssert(keyReq != NULL);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "=== KeyReq:\n");
+ fprintf(output, "==== keyId: %s\n",
+ (xmlSecKeyDataKlassGetName(keyReq->keyId)) ?
+ xmlSecKeyDataKlassGetName(keyReq->keyId) :
+ BAD_CAST "NULL");
+ fprintf(output, "==== keyType: 0x%08x\n", keyReq->keyType);
+ fprintf(output, "==== keyUsage: 0x%08x\n", keyReq->keyUsage);
+ fprintf(output, "==== keyBitsSize: %d\n", keyReq->keyBitsSize);
+ xmlSecPtrListDebugDump(&(keyReq->keyUseWithList), output);
+}
+
+/**
+ * xmlSecKeyReqDebugXmlDump:
+ * @keyReq: the pointer to key requirements object.
+ * @output: the pointer to output FILE.
+ *
+ * Prints debug information about @keyReq into @output in XML format.
+ */
+void
+xmlSecKeyReqDebugXmlDump(xmlSecKeyReqPtr keyReq, FILE* output) {
+ xmlSecAssert(keyReq != NULL);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<KeyReq>\n");
+
+ fprintf(output, "<KeyId>");
+ xmlSecPrintXmlString(output, xmlSecKeyDataKlassGetName(keyReq->keyId));
+ fprintf(output, "</KeyId>\n");
+
+ fprintf(output, "<KeyType>0x%08x</KeyType>\n", keyReq->keyType);
+ fprintf(output, "<KeyUsage>0x%08x</KeyUsage>\n", keyReq->keyUsage);
+ fprintf(output, "<KeyBitsSize>%d</KeyBitsSize>\n", keyReq->keyBitsSize);
+ xmlSecPtrListDebugXmlDump(&(keyReq->keyUseWithList), output);
+ fprintf(output, "</KeyReq>\n");
+}
+
+
+/**************************************************************************
+ *
+ * xmlSecKey
+ *
+ *************************************************************************/
+/**
+ * xmlSecKeyCreate:
+ *
+ * Allocates and initializes new key. Caller is responsible for
+ * freeing returned object with #xmlSecKeyDestroy function.
+ *
+ * Returns: the pointer to newly allocated @xmlSecKey structure
+ * or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyCreate(void) {
+ xmlSecKeyPtr key;
+
+ /* Allocate a new xmlSecKey and fill the fields. */
+ key = (xmlSecKeyPtr)xmlMalloc(sizeof(xmlSecKey));
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "sizeof(xmlSecKey)=%d",
+ sizeof(xmlSecKey));
+ return(NULL);
+ }
+ memset(key, 0, sizeof(xmlSecKey));
+ key->usage = xmlSecKeyUsageAny;
+ return(key);
+}
+
+/**
+ * xmlSecKeyEmpty:
+ * @key: the pointer to key.
+ *
+ * Clears the @key data.
+ */
+void
+xmlSecKeyEmpty(xmlSecKeyPtr key) {
+ xmlSecAssert(key != NULL);
+
+ if(key->value != NULL) {
+ xmlSecKeyDataDestroy(key->value);
+ }
+ if(key->name != NULL) {
+ xmlFree(key->name);
+ }
+ if(key->dataList != NULL) {
+ xmlSecPtrListDestroy(key->dataList);
+ }
+
+ memset(key, 0, sizeof(xmlSecKey));
+}
+
+/**
+ * xmlSecKeyDestroy:
+ * @key: the pointer to key.
+ *
+ * Destroys the key created using #xmlSecKeyCreate function.
+ */
+void
+xmlSecKeyDestroy(xmlSecKeyPtr key) {
+ xmlSecAssert(key != NULL);
+
+ xmlSecKeyEmpty(key);
+ xmlFree(key);
+}
+
+/**
+ * xmlSecKeyCopy:
+ * @keyDst: the destination key.
+ * @keySrc: the source key.
+ *
+ * Copies key data from @keySrc to @keyDst.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeyCopy(xmlSecKeyPtr keyDst, xmlSecKeyPtr keySrc) {
+ xmlSecAssert2(keyDst != NULL, -1);
+ xmlSecAssert2(keySrc != NULL, -1);
+
+ /* empty destination */
+ xmlSecKeyEmpty(keyDst);
+
+ /* copy everything */
+ if(keySrc->name != NULL) {
+ keyDst->name = xmlStrdup(keySrc->name);
+ if(keyDst->name == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_STRDUP_FAILED,
+ "len=%d", xmlStrlen(keySrc->name));
+ return(-1);
+ }
+ }
+
+ if(keySrc->value != NULL) {
+ keyDst->value = xmlSecKeyDataDuplicate(keySrc->value);
+ if(keyDst->value == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataDuplicate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ if(keySrc->dataList != NULL) {
+ keyDst->dataList = xmlSecPtrListDuplicate(keySrc->dataList);
+ if(keyDst->dataList == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListDuplicate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ keyDst->usage = keySrc->usage;
+ keyDst->notValidBefore = keySrc->notValidBefore;
+ keyDst->notValidAfter = keySrc->notValidAfter;
+ return(0);
+}
+
+/**
+ * xmlSecKeyDuplicate:
+ * @key: the pointer to the #xmlSecKey structure.
+ *
+ * Creates a duplicate of the given @key.
+ *
+ * Returns: the pointer to newly allocated #xmlSecKey structure
+ * or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyDuplicate(xmlSecKeyPtr key) {
+ xmlSecKeyPtr newKey;
+ int ret;
+
+ xmlSecAssert2(key != NULL, NULL);
+
+ newKey = xmlSecKeyCreate();
+ if(newKey == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecKeyCopy(newKey, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDestroy(newKey);
+ return(NULL);
+ }
+
+ return(newKey);
+}
+
+/**
+ * xmlSecKeyMatch:
+ * @key: the pointer to key.
+ * @name: the pointer to key name (may be NULL).
+ * @keyReq: the pointer to key requirements.
+ *
+ * Checks whether the @key matches the given criteria.
+ *
+ * Returns: 1 if the key satisfies the given criteria or 0 otherwise.
+ */
+int
+xmlSecKeyMatch(xmlSecKeyPtr key, const xmlChar *name, xmlSecKeyReqPtr keyReq) {
+ xmlSecAssert2(xmlSecKeyIsValid(key), -1);
+ xmlSecAssert2(keyReq != NULL, -1);
+
+ if((name != NULL) && (!xmlStrEqual(xmlSecKeyGetName(key), name))) {
+ return(0);
+ }
+ return(xmlSecKeyReqMatchKey(keyReq, key));
+}
+
+/**
+ * xmlSecKeyGetType:
+ * @key: the pointer to key.
+ *
+ * Gets @key type.
+ *
+ * Returns: key type.
+ */
+xmlSecKeyDataType
+xmlSecKeyGetType(xmlSecKeyPtr key) {
+ xmlSecKeyDataPtr data;
+
+ xmlSecAssert2(key != NULL, xmlSecKeyDataTypeUnknown);
+
+ data = xmlSecKeyGetValue(key);
+ if(data == NULL) {
+ return(xmlSecKeyDataTypeUnknown);
+ }
+ return(xmlSecKeyDataGetType(data));
+}
+
+/**
+ * xmlSecKeyGetName:
+ * @key: the pointer to key.
+ *
+ * Gets key name (see also #xmlSecKeySetName function).
+ *
+ * Returns: key name.
+ */
+const xmlChar*
+xmlSecKeyGetName(xmlSecKeyPtr key) {
+ xmlSecAssert2(key != NULL, NULL);
+
+ return(key->name);
+}
+
+/**
+ * xmlSecKeySetName:
+ * @key: the pointer to key.
+ * @name: the new key name.
+ *
+ * Sets key name (see also #xmlSecKeyGetName function).
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeySetName(xmlSecKeyPtr key, const xmlChar* name) {
+ xmlSecAssert2(key != NULL, -1);
+
+ if(key->name != NULL) {
+ xmlFree(key->name);
+ key->name = NULL;
+ }
+
+ if(name != NULL) {
+ key->name = xmlStrdup(name);
+ if(key->name == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_STRDUP_FAILED,
+ "len=%d", xmlStrlen(name));
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecKeyGetValue:
+ * @key: the pointer to key.
+ *
+ * Gets key value (see also #xmlSecKeySetValue function).
+ *
+ * Returns: key value (crypto material).
+ */
+xmlSecKeyDataPtr
+xmlSecKeyGetValue(xmlSecKeyPtr key) {
+ xmlSecAssert2(key != NULL, NULL);
+
+ return(key->value);
+}
+
+/**
+ * xmlSecKeySetValue:
+ * @key: the pointer to key.
+ * @value: the new value.
+ *
+ * Sets key value (see also #xmlSecKeyGetValue function).
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecKeySetValue(xmlSecKeyPtr key, xmlSecKeyDataPtr value) {
+ xmlSecAssert2(key != NULL, -1);
+
+ if(key->value != NULL) {
+ xmlSecKeyDataDestroy(key->value);
+ key->value = NULL;
+ }
+ key->value = value;
+
+ return(0);
+}
+
+/**
+ * xmlSecKeyGetData:
+ * @key: the pointer to key.
+ * @dataId: the requested data klass.
+ *
+ * Gets key's data.
+ *
+ * Returns: additional data associated with the @key (see also
+ * #xmlSecKeyAdoptData function).
+ */
+xmlSecKeyDataPtr
+xmlSecKeyGetData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
+
+ xmlSecAssert2(key != NULL, NULL);
+ xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
+
+ /* special cases */
+ if(dataId == xmlSecKeyDataValueId) {
+ return(key->value);
+ } else if(key->dataList != NULL) {
+ xmlSecKeyDataPtr tmp;
+ xmlSecSize pos, size;
+
+ size = xmlSecPtrListGetSize(key->dataList);
+ for(pos = 0; pos < size; ++pos) {
+ tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
+ if((tmp != NULL) && (tmp->id == dataId)) {
+ return(tmp);
+ }
+ }
+ }
+ return(NULL);
+}
+
+/**
+ * xmlSecKeyEnsureData:
+ * @key: the pointer to key.
+ * @dataId: the requested data klass.
+ *
+ * If necessary, creates key data of @dataId klass and adds to @key.
+ *
+ * Returns: pointer to key data or NULL if an error occurs.
+ */
+xmlSecKeyDataPtr
+xmlSecKeyEnsureData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
+ xmlSecKeyDataPtr data;
+ int ret;
+
+ xmlSecAssert2(key != NULL, NULL);
+ xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
+
+ data = xmlSecKeyGetData(key, dataId);
+ if(data != NULL) {
+ return(data);
+ }
+
+ data = xmlSecKeyDataCreate(dataId);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "dataId=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
+ return(NULL);
+ }
+
+ ret = xmlSecKeyAdoptData(key, data);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyAdoptData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "dataId=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
+ xmlSecKeyDataDestroy(data);
+ return(NULL);
+ }
+
+ return(data);
+}
+
+/**
+ * xmlSecKeyAdoptData:
+ * @key: the pointer to key.
+ * @data: the pointer to key data.
+ *
+ * Adds @data to the @key. The @data object will be destroyed
+ * by @key.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecKeyAdoptData(xmlSecKeyPtr key, xmlSecKeyDataPtr data) {
+ xmlSecKeyDataPtr tmp;
+ xmlSecSize pos, size;
+
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
+
+ /* special cases */
+ if(data->id == xmlSecKeyDataValueId) {
+ if(key->value != NULL) {
+ xmlSecKeyDataDestroy(key->value);
+ }
+ key->value = data;
+ return(0);
+ }
+
+ if(key->dataList == NULL) {
+ key->dataList = xmlSecPtrListCreate(xmlSecKeyDataListId);
+ if(key->dataList == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+
+ size = xmlSecPtrListGetSize(key->dataList);
+ for(pos = 0; pos < size; ++pos) {
+ tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
+ if((tmp != NULL) && (tmp->id == data->id)) {
+ return(xmlSecPtrListSet(key->dataList, data, pos));
+ }
+ }
+
+ return(xmlSecPtrListAdd(key->dataList, data));
+}
+
+/**
+ * xmlSecKeyDebugDump:
+ * @key: the pointer to key.
+ * @output: the pointer to output FILE.
+ *
+ * Prints the information about the @key to the @output.
+ */
+void
+xmlSecKeyDebugDump(xmlSecKeyPtr key, FILE *output) {
+ xmlSecAssert(xmlSecKeyIsValid(key));
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "== KEY\n");
+ fprintf(output, "=== method: %s\n",
+ (key->value->id->dataNodeName != NULL) ?
+ (char*)(key->value->id->dataNodeName) : "NULL");
+
+ fprintf(output, "=== key type: ");
+ if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
+ fprintf(output, "Symmetric\n");
+ } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
+ fprintf(output, "Private\n");
+ } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
+ fprintf(output, "Public\n");
+ } else {
+ fprintf(output, "Unknown\n");
+ }
+
+ if(key->name != NULL) {
+ fprintf(output, "=== key name: %s\n", key->name);
+ }
+ fprintf(output, "=== key usage: %d\n", key->usage);
+ if(key->notValidBefore < key->notValidAfter) {
+ fprintf(output, "=== key not valid before: %ld\n", (unsigned long)key->notValidBefore);
+ fprintf(output, "=== key not valid after: %ld\n", (unsigned long)key->notValidAfter);
+ }
+ if(key->value != NULL) {
+ xmlSecKeyDataDebugDump(key->value, output);
+ }
+ if(key->dataList != NULL) {
+ xmlSecPtrListDebugDump(key->dataList, output);
+ }
+}
+
+/**
+ * xmlSecKeyDebugXmlDump:
+ * @key: the pointer to key.
+ * @output: the pointer to output FILE.
+ *
+ * Prints the information about the @key to the @output in XML format.
+ */
+void
+xmlSecKeyDebugXmlDump(xmlSecKeyPtr key, FILE *output) {
+ xmlSecAssert(xmlSecKeyIsValid(key));
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<KeyInfo>\n");
+
+ fprintf(output, "<KeyMethod>");
+ xmlSecPrintXmlString(output, key->value->id->dataNodeName);
+ fprintf(output, "</KeyMethod>\n");
+
+ fprintf(output, "<KeyType>");
+ if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
+ fprintf(output, "Symmetric\n");
+ } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
+ fprintf(output, "Private\n");
+ } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
+ fprintf(output, "Public\n");
+ } else {
+ fprintf(output, "Unknown\n");
+ }
+ fprintf(output, "</KeyType>\n");
+
+ fprintf(output, "<KeyName>");
+ xmlSecPrintXmlString(output, key->name);
+ fprintf(output, "</KeyName>\n");
+
+ if(key->notValidBefore < key->notValidAfter) {
+ fprintf(output, "<KeyValidity notValidBefore=\"%ld\" notValidAfter=\"%ld\"/>\n",
+ (unsigned long)key->notValidBefore,
+ (unsigned long)key->notValidAfter);
+ }
+
+ if(key->value != NULL) {
+ xmlSecKeyDataDebugXmlDump(key->value, output);
+ }
+ if(key->dataList != NULL) {
+ xmlSecPtrListDebugXmlDump(key->dataList, output);
+ }
+
+ fprintf(output, "</KeyInfo>\n");
+}
+
+/**
+ * xmlSecKeyGenerate:
+ * @dataId: the requested key klass (rsa, dsa, aes, ...).
+ * @sizeBits: the new key size (in bits!).
+ * @type: the new key type (session, permanent, ...).
+ *
+ * Generates new key of requested klass @dataId and @type.
+ *
+ * Returns: pointer to newly created key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyGenerate(xmlSecKeyDataId dataId, xmlSecSize sizeBits, xmlSecKeyDataType type) {
+ xmlSecKeyPtr key;
+ xmlSecKeyDataPtr data;
+ int ret;
+
+ xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
+
+ data = xmlSecKeyDataCreate(dataId);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecKeyDataGenerate(data, sizeBits, type);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyDataGenerate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d;type=%d", sizeBits, type);
+ xmlSecKeyDataDestroy(data);
+ return(NULL);
+ }
+
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(data);
+ return(NULL);
+ }
+
+ ret = xmlSecKeySetValue(key, data);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeySetValue",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDataDestroy(data);
+ xmlSecKeyDestroy(key);
+ return(NULL);
+ }
+
+ return(key);
+}
+
+/**
+ * xmlSecKeyGenerateByName:
+ * @name: the requested key klass name (rsa, dsa, aes, ...).
+ * @sizeBits: the new key size (in bits!).
+ * @type: the new key type (session, permanent, ...).
+ *
+ * Generates new key of requested @klass and @type.
+ *
+ * Returns: pointer to newly created key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyGenerateByName(const xmlChar* name, xmlSecSize sizeBits, xmlSecKeyDataType type) {
+ xmlSecKeyDataId dataId;
+
+ xmlSecAssert2(name != NULL, NULL);
+
+ dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), name, xmlSecKeyDataUsageAny);
+ if(dataId == xmlSecKeyDataIdUnknown) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(name),
+ XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ return(xmlSecKeyGenerate(dataId, sizeBits, type));
+}
+
+/**
+ * xmlSecKeyReadBuffer:
+ * @dataId: the key value data klass.
+ * @buffer: the buffer that contains the binary data.
+ *
+ * Reads the key value of klass @dataId from a buffer.
+ *
+ * Returns: pointer to newly created key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyReadBuffer(xmlSecKeyDataId dataId, xmlSecBuffer* buffer) {
+ xmlSecKeyInfoCtx keyInfoCtx;
+ xmlSecKeyPtr key;
+ int ret;
+
+ xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
+ xmlSecAssert2(buffer != NULL, NULL);
+
+ /* create key data */
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyInfoCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDestroy(key);
+ return(NULL);
+ }
+
+ keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
+ ret = xmlSecKeyDataBinRead(dataId, key,
+ xmlSecBufferGetData(buffer),
+ xmlSecBufferGetSize(buffer),
+ &keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyDataBinRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
+ xmlSecKeyDestroy(key);
+ return(NULL);
+ }
+ xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
+
+ return(key);
+}
+
+/**
+ * xmlSecKeyReadBinaryFile:
+ * @dataId: the key value data klass.
+ * @filename: the key binary filename.
+ *
+ * Reads the key value of klass @dataId from a binary file @filename.
+ *
+ * Returns: pointer to newly created key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyReadBinaryFile(xmlSecKeyDataId dataId, const char* filename) {
+ xmlSecKeyPtr key;
+ xmlSecBuffer buffer;
+ int ret;
+
+ xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
+ xmlSecAssert2(filename != NULL, NULL);
+
+ /* read file to buffer */
+ ret = xmlSecBufferInitialize(&buffer, 0);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ ret = xmlSecBufferReadFile(&buffer, filename);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecBufferReadFile",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ key = xmlSecKeyReadBuffer(dataId, &buffer);
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyReadBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "filename=%s",
+ xmlSecErrorsSafeString(filename));
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ xmlSecBufferFinalize(&buffer);
+ return (key);
+}
+
+/**
+ * xmlSecKeyReadMemory:
+ * @dataId: the key value data klass.
+ * @data: the memory containing the key
+ * @dataSize: the size of the memory block
+ *
+ * Reads the key value of klass @dataId from a memory block @data.
+ *
+ * Returns: pointer to newly created key or NULL if an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeyReadMemory(xmlSecKeyDataId dataId, const xmlSecByte* data, xmlSecSize dataSize) {
+ xmlSecBuffer buffer;
+ xmlSecKeyPtr key;
+ int ret;
+
+ xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
+ xmlSecAssert2(data != NULL, NULL);
+ xmlSecAssert2(dataSize > 0, NULL);
+
+ /* read file to buffer */
+ ret = xmlSecBufferInitialize(&buffer, 0);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecBufferInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ if (xmlSecBufferAppend(&buffer, data, dataSize) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecBufferAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ key = xmlSecKeyReadBuffer(dataId, &buffer);
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
+ "xmlSecKeyReadBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecBufferFinalize(&buffer);
+ return(NULL);
+ }
+
+ xmlSecBufferFinalize(&buffer);
+ return (key);
+}
+
+/**
+ * xmlSecKeysMngrGetKey:
+ * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
+ * @keyInfoCtx: the pointer to <dsig:KeyInfo/> node processing context.
+ *
+ * Reads the <dsig:KeyInfo/> node @keyInfoNode and extracts the key.
+ *
+ * Returns: the pointer to key or NULL if the key is not found or
+ * an error occurs.
+ */
+xmlSecKeyPtr
+xmlSecKeysMngrGetKey(xmlNodePtr keyInfoNode, xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyPtr key;
+ int ret;
+
+ xmlSecAssert2(keyInfoCtx != NULL, NULL);
+
+
+ /* first try to read data from <dsig:KeyInfo/> node */
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ if(keyInfoNode != NULL) {
+ ret = xmlSecKeyInfoNodeRead(keyInfoNode, key, keyInfoCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(keyInfoNode)));
+ xmlSecKeyDestroy(key);
+ return(NULL);
+ }
+
+ if((xmlSecKeyGetValue(key) != NULL) &&
+ (xmlSecKeyMatch(key, NULL, &(keyInfoCtx->keyReq)) != 0)) {
+ return(key);
+ }
+ }
+ xmlSecKeyDestroy(key);
+
+ /* if we have keys manager, try it */
+ if(keyInfoCtx->keysMngr != NULL) {
+ key = xmlSecKeysMngrFindKey(keyInfoCtx->keysMngr, NULL, keyInfoCtx);
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrFindKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ if(xmlSecKeyGetValue(key) != NULL) {
+ return(key);
+ }
+ xmlSecKeyDestroy(key);
+ }
+
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_KEY_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+}
+
+/***********************************************************************
+ *
+ * Keys list
+ *
+ **********************************************************************/
+static xmlSecPtrListKlass xmlSecKeyPtrListKlass = {
+ BAD_CAST "keys-list",
+ (xmlSecPtrDuplicateItemMethod)xmlSecKeyDuplicate, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ (xmlSecPtrDestroyItemMethod)xmlSecKeyDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugXmlDump,/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+/**
+ * xmlSecKeyPtrListGetKlass:
+ *
+ * The keys list klass.
+ *
+ * Returns: keys list id.
+ */
+xmlSecPtrListId
+xmlSecKeyPtrListGetKlass(void) {
+ return(&xmlSecKeyPtrListKlass);
+}
+