summaryrefslogtreecommitdiff
path: root/src/xkms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xkms.c')
-rw-r--r--src/xkms.c4981
1 files changed, 4981 insertions, 0 deletions
diff --git a/src/xkms.c b/src/xkms.c
new file mode 100644
index 00000000..d10099bb
--- /dev/null
+++ b/src/xkms.c
@@ -0,0 +1,4981 @@
+/**
+ * XML Security Library (http://www.aleksey.com/xmlsec).
+ *
+ * "XML Key Management Specification v 2.0" implementation
+ * http://www.w3.org/TR/xkms2/
+ *
+ * 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"
+
+#ifndef XMLSEC_NO_XKMS
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/buffer.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/keys.h>
+#include <xmlsec/keysmngr.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/keyinfo.h>
+#include <xmlsec/soap.h>
+#include <xmlsec/xkms.h>
+#include <xmlsec/private.h>
+#include <xmlsec/private/xkms.h>
+#include <xmlsec/errors.h>
+
+#define XMLSEC_XKMS_ID_ATTRIBUTE_LEN 32
+
+/* The ID attribute in XKMS is 'Id' */
+static const xmlChar* xmlSecXkmsServerIds[] = { BAD_CAST "Id", NULL };
+
+#ifndef XMLSEC_NO_SOAP
+static int xmlSecXkmsServerCtxWriteSoap11FatalError (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr envNode);
+static int xmlSecXkmsServerCtxWriteSoap12FatalError (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr envNode);
+#endif /* XMLSEC_NO_SOAP */
+
+static int xmlSecXkmsServerCtxRequestAbstractTypeNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr* node);
+static int xmlSecXkmsServerCtxSignatureNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxMessageExtensionNodesRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr* node);
+static int xmlSecXkmsServerCtxOpaqueClientDataNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxPendingNotificationNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxRespondWithNodesRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr* node);
+static int xmlSecXkmsServerCtxPendingRequestNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr* node);
+static int xmlSecXkmsServerCtxQueryKeyBindingNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead(xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr* node);
+static int xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite(xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+static int xmlSecXkmsServerCtxKeyInfoNodeWrite (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+static int xmlSecXkmsServerCtxUseKeyWithNodesRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr* node);
+static int xmlSecXkmsServerCtxUseKeyWithNodesWrite (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+static int xmlSecXkmsServerCtxTimeInstantNodeRead (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxResultTypeNodeWrite (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxRequestSignatureValueNodeWrite(xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+static int xmlSecXkmsServerCtxKeyBindingNodeWrite (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+static int xmlSecXkmsServerCtxValidityIntervalNodeWrite (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+static int xmlSecXkmsServerCtxKeyBindingStatusNodeWrite (xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node,
+ xmlSecKeyPtr key);
+
+
+static const xmlSecQName2IntegerInfo gXmlSecXkmsResultMajorInfo[] =
+{
+ { xmlSecXkmsNs, xmlSecResultMajorCodeSuccess,
+ xmlSecXkmsResultMajorSuccess },
+ { xmlSecXkmsNs, xmlSecResultMajorCodeVersionMismatch,
+ xmlSecXkmsResultMajorVersionMismatch },
+ { xmlSecXkmsNs, xmlSecResultMajorCodeSender,
+ xmlSecXkmsResultMajorSender },
+ { xmlSecXkmsNs, xmlSecResultMajorCodeReceiver,
+ xmlSecXkmsResultMajorReceiver },
+ { xmlSecXkmsNs, xmlSecResultMajorCodeRepresent,
+ xmlSecXkmsResultMajorRepresent },
+ { xmlSecXkmsNs, xmlSecResultMajorCodePending,
+ xmlSecXkmsResultMajorPending, },
+ { NULL , NULL, 0 } /* MUST be last in the list */
+};
+
+static const xmlSecQName2IntegerInfo gXmlSecXkmsMinorErrorInfo[] =
+{
+ { xmlSecXkmsNs, xmlSecResultMinorCodeNoMatch,
+ xmlSecXkmsResultMinorNoMatch },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeTooManyResponses,
+ xmlSecXkmsResultMinorTooManyResponses },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeIncomplete,
+ xmlSecXkmsResultMinorIncomplete },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeFailure,
+ xmlSecXkmsResultMinorFailure },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeRefused,
+ xmlSecXkmsResultMinorRefused },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeNoAuthentication,
+ xmlSecXkmsResultMinorNoAuthentication },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeMessageNotSupported,
+ xmlSecXkmsResultMinorMessageNotSupported },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeUnknownResponseId,
+ xmlSecXkmsResultMinorUnknownResponseId },
+ { xmlSecXkmsNs, xmlSecResultMinorCodeNotSynchronous,
+ xmlSecXkmsResultMinorSynchronous },
+ { NULL, NULL, 0 } /* MUST be last in the list */
+};
+
+static const xmlSecQName2IntegerInfo gXmlSecXkmsKeyBindingStatusInfo[] =
+{
+ { xmlSecXkmsNs, xmlSecKeyBindingStatusValid,
+ xmlSecXkmsKeyBindingStatusValid },
+ { xmlSecXkmsNs, xmlSecKeyBindingStatusInvalid,
+ xmlSecXkmsKeyBindingStatusInvalid },
+ { xmlSecXkmsNs, xmlSecKeyBindingStatusIndeterminate,
+ xmlSecXkmsKeyBindingStatusIndeterminate },
+ { NULL, NULL, 0 } /* MUST be last in the list */
+};
+
+static const xmlSecQName2BitMaskInfo gXmlSecXkmsKeyUsageInfo[] =
+{
+ { xmlSecXkmsNs, xmlSecKeyUsageEncryption,
+ xmlSecKeyUsageEncrypt | xmlSecKeyUsageDecrypt },
+ { xmlSecXkmsNs, xmlSecKeyUsageSignature,
+ xmlSecKeyUsageSign | xmlSecKeyUsageVerify },
+ { xmlSecXkmsNs, xmlSecKeyUsageExchange,
+ xmlSecKeyUsageKeyExchange},
+ { NULL, NULL, 0 } /* MUST be last in the list */
+};
+
+static const xmlSecQName2BitMaskInfo gXmlSecXkmsKeyBindingReasonInfo[] =
+{
+ { xmlSecXkmsNs, xmlSecKeyBindingReasonIssuerTrust,
+ XMLSEC_XKMS_KEY_BINDING_REASON_MASK_ISSUER_TRAST },
+ { xmlSecXkmsNs, xmlSecKeyBindingReasonRevocationStatus,
+ XMLSEC_XKMS_KEY_BINDING_REASON_MASK_REVOCATION_STATUS },
+ { xmlSecXkmsNs, xmlSecKeyBindingReasonValidityInterval,
+ XMLSEC_XKMS_KEY_BINDING_REASON_MASK_VALIDITY_INTERVAL },
+ { xmlSecXkmsNs, xmlSecKeyBindingReasonSignature,
+ XMLSEC_XKMS_KEY_BINDING_REASON_MASK_SIGNATURE },
+ { NULL, NULL, 0 } /* MUST be last in the list */
+};
+
+static const xmlSecQName2BitMaskInfo gXmlSecXkmsResponseMechanismInfo[] =
+{
+ { xmlSecXkmsNs, xmlSecResponseMechanismRepresent,
+ XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_REPRESENT },
+ { xmlSecXkmsNs, xmlSecResponseMechanismPending,
+ XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_PENDING },
+ { xmlSecXkmsNs, xmlSecResponseMechanismRequestSignatureValue,
+ XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_REQUEST_SIGNATURE_VALUE },
+ { NULL, NULL, 0 } /* MUST be last in the list */
+};
+
+static const xmlSecQName2IntegerInfo gXmlSecXkmsFormatInfo[] =
+{
+ { NULL, xmlSecXkmsFormatStrPlain,
+ xmlSecXkmsServerFormatPlain },
+#ifndef XMLSEC_NO_SOAP
+ { NULL, xmlSecXkmsFormatStrSoap11,
+ xmlSecXkmsServerFormatSoap11 },
+ { NULL, xmlSecXkmsFormatStrSoap12,
+ xmlSecXkmsServerFormatSoap12 },
+#endif /* XMLSEC_NO_SOAP */
+ { NULL, NULL, 0 } /* MUST be last in the list */
+};
+
+/**
+ * xmlSecXkmsServerFormatFromString:
+ * @str the string.
+ *
+ * Gets xmlSecXkmsServerFormat from string @str.
+ *
+ * Returns: corresponding format or xmlSecXkmsServerFormatUnknown
+ * if format could not be recognized.
+ */
+xmlSecXkmsServerFormat
+xmlSecXkmsServerFormatFromString(const xmlChar* str) {
+ int res;
+ int ret;
+
+ xmlSecAssert2(str != NULL, xmlSecXkmsServerFormatUnknown);
+
+ ret = xmlSecQName2IntegerGetInteger(gXmlSecXkmsFormatInfo, NULL, str, &res);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2IntegerGetInteger",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(xmlSecXkmsServerFormatUnknown);
+ }
+
+ return((xmlSecXkmsServerFormat)res);
+}
+
+/**
+ * xmlSecXkmsServerFormatToString:
+ * @format: the format.
+ *
+ * Gets string from @format.
+ *
+ * Returns: string corresponding to @format or NULL if an error occurs.
+ */
+const xmlChar*
+xmlSecXkmsServerFormatToString (xmlSecXkmsServerFormat format) {
+ xmlSecQName2IntegerInfoConstPtr info;
+
+ xmlSecAssert2(format != xmlSecXkmsServerFormatUnknown, NULL);
+
+ info = xmlSecQName2IntegerGetInfo(gXmlSecXkmsFormatInfo, format);
+ if(info == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2IntegerGetInfo",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ return(info->qnameLocalPart);
+}
+
+/**
+ * xmlSecXkmsServerCtxCreate:
+ * @keysMngr: the pointer to keys manager.
+ *
+ * Creates XKMS request server side processing context.
+ * The caller is responsible for destroying returned object by calling
+ * #xmlSecXkmsServerCtxDestroy function.
+ *
+ * Returns: pointer to newly allocated context object or NULL if an error
+ * occurs.
+ */
+xmlSecXkmsServerCtxPtr
+xmlSecXkmsServerCtxCreate(xmlSecKeysMngrPtr keysMngr) {
+ xmlSecXkmsServerCtxPtr ctx;
+ int ret;
+
+ ctx = (xmlSecXkmsServerCtxPtr) xmlMalloc(sizeof(xmlSecXkmsServerCtx));
+ if(ctx == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "sizeof(xmlSecXkmsServerCtx)=%d",
+ sizeof(xmlSecXkmsServerCtx));
+ return(NULL);
+ }
+
+ ret = xmlSecXkmsServerCtxInitialize(ctx, keysMngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxDestroy(ctx);
+ return(NULL);
+ }
+ return(ctx);
+}
+
+/**
+ * xmlSecXkmsServerCtxDestroy:
+ * @ctx: the pointer to XKMS processing context.
+ *
+ * Destroy context object created with #xmlSecXkmsServerCtxCreate function.
+ */
+void
+xmlSecXkmsServerCtxDestroy(xmlSecXkmsServerCtxPtr ctx) {
+ xmlSecAssert(ctx != NULL);
+
+ xmlSecXkmsServerCtxFinalize(ctx);
+ xmlFree(ctx);
+}
+
+/**
+ * xmlSecXkmsServerCtxInitialize:
+ * @ctx: the pointer to XKMS processing context.
+ * @keysMngr: the pointer to keys manager.
+ *
+ * Initializes XKMS element processing context.
+ * The caller is responsible for cleaning up returned object by calling
+ * #xmlSecXkmsServerCtxFinalize function.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerCtxInitialize(xmlSecXkmsServerCtxPtr ctx, xmlSecKeysMngrPtr keysMngr) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+
+ memset(ctx, 0, sizeof(xmlSecXkmsServerCtx));
+
+ ctx->resultMajor = xmlSecXkmsResultMajorSuccess;
+ ctx->resultMinor = xmlSecXkmsResultMinorNone;
+ ctx->responseLimit = XMLSEC_XKMS_NO_RESPONSE_LIMIT;
+ ctx->idLen = XMLSEC_XKMS_ID_ATTRIBUTE_LEN;
+
+ /* initialize key info */
+ ret = xmlSecKeyInfoCtxInitialize(&(ctx->keyInfoReadCtx), keysMngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ ctx->keyInfoReadCtx.mode = xmlSecKeyInfoModeRead;
+
+ ret = xmlSecKeyInfoCtxInitialize(&(ctx->keyInfoWriteCtx), keysMngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ ctx->keyInfoWriteCtx.mode = xmlSecKeyInfoModeWrite;
+
+ /* enabled RespondWith */
+ ret = xmlSecPtrListInitialize(&(ctx->enabledRespondWithIds), xmlSecXkmsRespondWithIdListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* enabled ServerRequest */
+ ret = xmlSecPtrListInitialize(&(ctx->enabledServerRequestIds), xmlSecXkmsServerRequestIdListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+
+
+ /* initialize keys list */
+ ret = xmlSecPtrListInitialize(&(ctx->keys), xmlSecKeyPtrListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* initialize RespondWith list */
+ ret = xmlSecPtrListInitialize(&(ctx->respWithList), xmlSecXkmsRespondWithIdListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsServerCtxFinalize:
+ * @ctx: the pointer to XKMS processing context.
+ *
+ * Cleans up @ctx object.
+ */
+void
+xmlSecXkmsServerCtxFinalize(xmlSecXkmsServerCtxPtr ctx) {
+ xmlSecAssert(ctx != NULL);
+
+ xmlSecXkmsServerCtxReset(ctx);
+
+ if(ctx->expectedService != NULL) {
+ xmlFree(ctx->expectedService);
+ }
+ if(ctx->idPrefix != NULL) {
+ xmlFree(ctx->idPrefix);
+ }
+
+ xmlSecKeyInfoCtxFinalize(&(ctx->keyInfoReadCtx));
+ xmlSecKeyInfoCtxFinalize(&(ctx->keyInfoWriteCtx));
+ xmlSecPtrListFinalize(&(ctx->enabledRespondWithIds));
+ xmlSecPtrListFinalize(&(ctx->enabledServerRequestIds));
+ xmlSecPtrListFinalize(&(ctx->keys));
+ xmlSecPtrListFinalize(&(ctx->respWithList));
+ memset(ctx, 0, sizeof(xmlSecXkmsServerCtx));
+}
+
+/**
+ * xmlSecXkmsServerCtxReset:
+ * @ctx: the pointer to XKMS processing context.
+ *
+ * Resets @ctx object, user settings are not touched.
+ */
+void
+xmlSecXkmsServerCtxReset(xmlSecXkmsServerCtxPtr ctx) {
+ xmlSecAssert(ctx != NULL);
+
+ ctx->resultMajor = xmlSecXkmsResultMajorSuccess;
+ ctx->resultMinor = xmlSecXkmsResultMinorNone;
+ xmlSecKeyInfoCtxReset(&(ctx->keyInfoReadCtx));
+ xmlSecKeyInfoCtxReset(&(ctx->keyInfoWriteCtx));
+ xmlSecPtrListEmpty(&(ctx->keys));
+ xmlSecPtrListEmpty(&(ctx->respWithList));
+
+ ctx->requestNode = NULL;
+ ctx->opaqueClientDataNode = NULL;
+ ctx->firtsMsgExtNode = NULL;
+ ctx->keyInfoNode = NULL;
+ ctx->requestId = xmlSecXkmsServerRequestIdUnknown;
+
+ if(ctx->id != NULL) {
+ xmlFree(ctx->id); ctx->id = NULL;
+ }
+ if(ctx->service != NULL) {
+ xmlFree(ctx->service); ctx->service = NULL;
+ }
+ if(ctx->nonce != NULL) {
+ xmlFree(ctx->nonce); ctx->nonce = NULL;
+ }
+ if(ctx->originalRequestId != NULL) {
+ xmlFree(ctx->originalRequestId); ctx->originalRequestId = NULL;
+ }
+ if(ctx->pendingNotificationMechanism != NULL) {
+ xmlFree(ctx->pendingNotificationMechanism);
+ ctx->pendingNotificationMechanism = NULL;
+ }
+ if(ctx->pendingNotificationIdentifier != NULL) {
+ xmlFree(ctx->pendingNotificationIdentifier);
+ ctx->pendingNotificationIdentifier = NULL;
+ }
+ if(ctx->compoundRequestContexts != NULL) {
+ xmlSecPtrListDestroy(ctx->compoundRequestContexts);
+ ctx->compoundRequestContexts = NULL;
+ }
+
+ ctx->responseLimit = XMLSEC_XKMS_NO_RESPONSE_LIMIT;
+ ctx->responseMechanismMask = 0;
+}
+
+/**
+ * xmlSecXkmsServerCtxCopyUserPref:
+ * @dst: the pointer to destination context.
+ * @src: the pointer to source context.
+ *
+ * Copies user preference from @src context to @dst.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerCtxCopyUserPref(xmlSecXkmsServerCtxPtr dst, xmlSecXkmsServerCtxPtr src) {
+ int ret;
+
+ xmlSecAssert2(dst != NULL, -1);
+ xmlSecAssert2(src != NULL, -1);
+
+ dst->userData = src->userData;
+ dst->flags = src->flags;
+ dst->flags2 = src->flags2;
+
+ ret = xmlSecKeyInfoCtxCopyUserPref(&(dst->keyInfoReadCtx), &(src->keyInfoReadCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoCtxCopyUserPref",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecKeyInfoCtxCopyUserPref(&(dst->keyInfoWriteCtx), &(src->keyInfoWriteCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoCtxCopyUserPref",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ if(src->expectedService != NULL) {
+ dst->expectedService = xmlStrdup(src->expectedService);
+ if(dst->expectedService == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ if(src->idPrefix != NULL) {
+ dst->idPrefix = xmlStrdup(src->idPrefix);
+ if(dst->idPrefix == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ src->idLen = dst->idLen;
+
+
+ ret = xmlSecPtrListCopy(&(dst->enabledRespondWithIds), &(src->enabledRespondWithIds));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecPtrListCopy(&(dst->enabledServerRequestIds), &(src->enabledServerRequestIds));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListCopy",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsServerCtxProcess:
+ * @ctx: the pointer to XKMS processing context.
+ * @node: the pointer to request node.
+ * @format: the request/response format.
+ * @doc: the pointer to response parent XML document (might be NULL).
+ *
+ * Reads XKMS request from @node and creates response to a newly created node.
+ * Caller is responsible for adding the returned node to the XML document.
+ *
+ * Returns: pointer to newly created XKMS response node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecXkmsServerCtxProcess(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node,
+ xmlSecXkmsServerFormat format, xmlDocPtr doc) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, NULL);
+ xmlSecAssert2(ctx->requestId == NULL, NULL);
+ xmlSecAssert2(ctx->requestNode == NULL, NULL);
+ xmlSecAssert2(node != NULL, NULL);
+
+ ctx->requestNode = xmlSecXkmsServerCtxRequestUnwrap(ctx, node, format);
+ if(ctx->requestNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRequestUnwrap",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(node->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ goto done;
+ }
+
+ ret = xmlSecXkmsServerCtxRequestRead(ctx, ctx->requestNode);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdListFindByNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ctx->requestNode=%s",
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ goto done;
+ }
+
+ ret = xmlSecXkmsServerRequestExecute(ctx->requestId, ctx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ctx->requestNode=%s",
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ goto done;
+ }
+
+done:
+ /* always try to write response back */
+ if(ctx->requestId != NULL) {
+ xmlNodePtr respNode;
+ xmlNodePtr wrappedRespNode;
+
+ respNode = xmlSecXkmsServerCtxResponseWrite(ctx, doc);
+ if(respNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResponseWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ctx->requestNode=%s",
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ goto error;
+ }
+
+
+ wrappedRespNode = xmlSecXkmsServerCtxResponseWrap(ctx, respNode, format, doc);
+ if(wrappedRespNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResponseWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ctx->requestNode=%s",
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ xmlFreeNode(respNode);
+ goto error;
+ }
+
+ return(wrappedRespNode);
+ }
+
+error:
+ /* last attempt: create fatatl error response */
+ return(xmlSecXkmsServerCtxFatalErrorResponseCreate(ctx, format, doc));
+}
+
+/**
+ * xmlSecXkmsServerCtxRequestRead:
+ * @ctx: the pointer to XKMS processing context.
+ * @node: the pointer to request node.
+ *
+ * Reads XKMS request from @node and stores data in @ctx.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerCtxRequestRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->requestId == NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* find out what the request is */
+ if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
+ ctx->requestId = xmlSecXkmsServerRequestIdListFindByNode(&(ctx->enabledServerRequestIds), node);
+ } else {
+ ctx->requestId = xmlSecXkmsServerRequestIdListFindByNode(xmlSecXkmsServerRequestIdsGet(), node);
+ }
+ if(ctx->requestId == xmlSecXkmsServerRequestIdUnknown) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdListFindByNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(node->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorMessageNotSupported);
+ return(-1);
+ }
+
+ xmlSecAddIDs(node->doc, node, xmlSecXkmsServerIds);
+ ret = xmlSecXkmsServerRequestNodeRead(ctx->requestId, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "request=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctx->requestId)));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsServerCtxResponseWrite:
+ * @ctx: the pointer to XKMS processing context.
+ * @doc: the pointer to response parent XML document (might be NULL).
+ *
+ * Writes XKMS response from context to a newly created node. Caller is
+ * responsible for adding the returned node to the XML document.
+ *
+ * Returns: pointer to newly created XKMS response node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecXkmsServerCtxResponseWrite(xmlSecXkmsServerCtxPtr ctx, xmlDocPtr doc) {
+ xmlNodePtr respNode;
+
+ xmlSecAssert2(ctx != NULL, NULL);
+ xmlSecAssert2(ctx->requestId != NULL, NULL);
+
+ /* now write results */
+ respNode = xmlSecXkmsServerRequestNodeWrite(ctx->requestId, ctx, doc, NULL);
+ if(respNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "request=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctx->requestId)));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ return(respNode);
+}
+
+/**
+ * xmlSecXkmsServerCtxRequestUnwrap:
+ * @ctx: the pointer to XKMS processing context.
+ * @node: the pointer to request node.
+ * @format: the request/response format.
+ *
+ * Removes SOAP or other envelope from XKMS request.
+ *
+ * Returns: pointer to "real" XKMS request node or NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecXkmsServerCtxRequestUnwrap(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecXkmsServerFormat format) {
+ xmlNodePtr result = NULL;
+
+ xmlSecAssert2(ctx != NULL, NULL);
+ xmlSecAssert2(node != NULL, NULL);
+
+ switch(format) {
+ case xmlSecXkmsServerFormatPlain:
+ result = node;
+ break;
+#ifndef XMLSEC_NO_SOAP
+ case xmlSecXkmsServerFormatSoap11:
+ /* verify that it is actually soap Envelope node */
+ if(xmlSecSoap11CheckEnvelope(node) != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11CheckEnvelope",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ /* check that Body has exactly one entry */
+ if(xmlSecSoap11GetBodyEntriesNumber(node) != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11GetBodyEntriesNumber",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ /* this one enntry is our xkms request */
+ result = xmlSecSoap11GetBodyEntry(node, 0);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11GetBodyEntry",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ break;
+ case xmlSecXkmsServerFormatSoap12:
+ /* verify that it is actually soap Envelope node */
+ if(xmlSecSoap12CheckEnvelope(node) != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12CheckEnvelope",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ /* check that Body has exactly one entry */
+ if(xmlSecSoap12GetBodyEntriesNumber(node) != 1) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12GetBodyEntriesNumber",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ /* this one enntry is our xkms request */
+ result = xmlSecSoap12GetBodyEntry(node, 0);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12GetBodyEntry",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ break;
+#endif /* XMLSEC_NO_SOAP */
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+ "format=%d",
+ format);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ return(result);
+}
+
+/**
+ * xmlSecXkmsServerCtxResponseWrap:
+ * @ctx: the pointer to XKMS processing context.
+ * @node: the pointer to response node.
+ * @format: the request/response format.
+ * @doc: the pointer to response parent XML document (might be NULL).
+ *
+ * Creates SOAP or other envelope around XKMS response.
+ * Caller is responsible for adding the returned node to the XML document.
+ *
+ * Returns: pointer to newly created response envelope node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecXkmsServerCtxResponseWrap(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecXkmsServerFormat format, xmlDocPtr doc) {
+ xmlNodePtr result = NULL;
+
+ xmlSecAssert2(ctx != NULL, NULL);
+ xmlSecAssert2(node != NULL, NULL);
+
+ switch(format) {
+ case xmlSecXkmsServerFormatPlain:
+ result = node; /* do nothing */
+ break;
+#ifndef XMLSEC_NO_SOAP
+ case xmlSecXkmsServerFormatSoap11:
+ result = xmlSecSoap11CreateEnvelope(doc);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11CreateEnvelope",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ if(xmlSecSoap11AddBodyEntry(result, node) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11AddBodyEntry",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+ break;
+ case xmlSecXkmsServerFormatSoap12:
+ result = xmlSecSoap12CreateEnvelope(doc);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12CreateEnvelope",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ if(xmlSecSoap12AddBodyEntry(result, node) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12AddBodyEntry",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+ break;
+#endif /* XMLSEC_NO_SOAP */
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+ "format=%d",
+ format);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ return(result);
+}
+
+/**
+ * xmlSecXkmsServerCtxFatalErrorResponseCreate:
+ * @ctx: the pointer to XKMS processing context.
+ * @format: the request/response format.
+ * @doc: the pointer to response parent XML document (might be NULL).
+ *
+ * Creates a "fatal error" SOAP or other envelope respons. Caller is
+ * responsible for adding the returned node to the XML document.
+ *
+ * Returns: pointer to newly created fatal error response (it might be NULL).
+ */
+xmlNodePtr
+xmlSecXkmsServerCtxFatalErrorResponseCreate(xmlSecXkmsServerCtxPtr ctx, xmlSecXkmsServerFormat format, xmlDocPtr doc) {
+ xmlNodePtr result = NULL;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ /* make sure that we have an error */
+ if(ctx->resultMajor == xmlSecXkmsResultMajorSuccess) {
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ }
+
+ switch(format) {
+ case xmlSecXkmsServerFormatPlain:
+ /* try to create fatal error response with XKMS Status request */
+ result = xmlSecXkmsServerRequestNodeWrite(xmlSecXkmsServerRequestResultId, ctx, doc, NULL);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ break;
+#ifndef XMLSEC_NO_SOAP
+ case xmlSecXkmsServerFormatSoap11:
+ result = xmlSecSoap11CreateEnvelope(doc);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11CreateEnvelope",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ ret = xmlSecXkmsServerCtxWriteSoap11FatalError(ctx, result);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxWriteSoap11FatalError",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ xmlFreeNode(result);
+ return(NULL);
+ }
+
+ break;
+ case xmlSecXkmsServerFormatSoap12:
+ result = xmlSecSoap12CreateEnvelope(doc);
+ if(result == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12CreateEnvelope",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ ret = xmlSecXkmsServerCtxWriteSoap12FatalError(ctx, result);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxWriteSoap12FatalError",
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ xmlFreeNode(result);
+ return(NULL);
+ }
+
+ break;
+#endif /* XMLSEC_NO_SOAP */
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+ "format=%d",
+ format);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(NULL);
+ }
+
+ return(result);
+}
+
+#ifndef XMLSEC_NO_SOAP
+static int
+xmlSecXkmsServerCtxWriteSoap11FatalError(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr envNode) {
+ const xmlChar* faultCodeHref = NULL;
+ const xmlChar* faultCodeLocalPart = NULL;
+ xmlChar* faultString = NULL;
+ int len;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(envNode != NULL, -1);
+
+ if((ctx->resultMajor == xmlSecXkmsResultMajorVersionMismatch) ||
+ (ctx->requestNode == NULL)) {
+ /* we were not able to parse the envelope or its general version mismatch error */
+ faultCodeHref = xmlSecSoap11Ns;
+ faultCodeLocalPart = xmlSecSoapFaultCodeVersionMismatch;
+ faultString = xmlStrdup(xmlSecXkmsSoapFaultReasonUnsupportedVersion);
+ if(faultString == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ } else if((ctx->resultMajor == xmlSecXkmsResultMajorSender) &&
+ (ctx->requestId == NULL)) {
+ /* we understood the request but were not able to parse input message */
+ faultCodeHref = xmlSecSoap11Ns;
+ faultCodeLocalPart = xmlSecSoapFaultCodeClient;
+
+ len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) +
+ xmlStrlen(xmlSecXkmsSoapFaultReasonMessageInvalid) + 1;
+ faultString = xmlMalloc(len + 1);
+ if(faultString == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ xmlSecStrPrintf(faultString, len , xmlSecXkmsSoapFaultReasonMessageInvalid,
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ } else if((ctx->resultMajor == xmlSecXkmsResultMajorReceiver) &&
+ (ctx->requestId == NULL)) {
+ /* we understood the request but were not able to process it */
+ faultCodeHref = xmlSecSoap11Ns;
+ faultCodeLocalPart = xmlSecSoapFaultCodeServer;
+ faultString = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
+ if(faultString == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ } else if((ctx->requestId == NULL) && (ctx->requestNode != NULL)) {
+ /* we parsed the envelope but were not able to understand this request */
+ faultCodeHref = xmlSecSoap11Ns;
+ faultCodeLocalPart = xmlSecSoapFaultCodeClient;
+
+ len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) +
+ xmlStrlen(xmlSecXkmsSoapFaultReasonMessageNotSupported) + 1;
+ faultString = xmlMalloc(len + 1);
+ if(faultString == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ xmlSecStrPrintf(faultString, len , xmlSecXkmsSoapFaultReasonMessageNotSupported,
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ } else {
+ /* just some error */
+ faultCodeHref = xmlSecSoap11Ns;
+ faultCodeLocalPart = xmlSecSoapFaultCodeServer;
+ faultString = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
+ if(faultString == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ }
+
+ if(xmlSecSoap11AddFaultEntry(envNode, faultCodeHref, faultCodeLocalPart, faultString, NULL) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap11AddFaultEntry",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ xmlFree(faultString);
+ return(-1);
+ }
+
+ xmlFree(faultString);
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxWriteSoap12FatalError(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr envNode) {
+ xmlSecSoap12FaultCode faultCode = xmlSecSoap12FaultCodeUnknown;
+ const xmlChar* faultSubCodeHref = NULL;
+ const xmlChar* faultSubCodeLocalPart = NULL;
+ xmlChar* faultReason = NULL;
+ int len;
+ xmlNodePtr faultNode;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(envNode != NULL, -1);
+
+ if((ctx->resultMajor == xmlSecXkmsResultMajorVersionMismatch) ||
+ (ctx->requestNode == NULL)) {
+ /* we were not able to parse the envelope or its general version mismatch error */
+ faultCode = xmlSecSoap12FaultCodeVersionMismatch;
+ faultReason = xmlStrdup(xmlSecXkmsSoapFaultReasonUnsupportedVersion);
+ if(faultReason == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ } else if((ctx->resultMajor == xmlSecXkmsResultMajorSender) &&
+ (ctx->requestId == NULL)) {
+ /* we understood the request but were not able to parse input message */
+ faultCode = xmlSecSoap12FaultCodeSender;
+ faultSubCodeHref = xmlSecXkmsNs;
+ faultSubCodeLocalPart = xmlSecXkmsSoapSubcodeValueMessageNotSupported;
+
+ len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) +
+ xmlStrlen(xmlSecXkmsSoapFaultReasonMessageInvalid) + 1;
+ faultReason = xmlMalloc(len + 1);
+ if(faultReason == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ xmlSecStrPrintf(faultReason, len , xmlSecXkmsSoapFaultReasonMessageInvalid,
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ } else if((ctx->resultMajor == xmlSecXkmsResultMajorReceiver) &&
+ (ctx->requestId == NULL)) {
+ /* we understood the request but were not able to process it */
+ faultCode = xmlSecSoap12FaultCodeReceiver;
+ faultReason = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
+ if(faultReason == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ } else if((ctx->requestId == NULL) && (ctx->requestNode != NULL)) {
+ /* we parsed the envelope but were not able to understand this request */
+ faultCode = xmlSecSoap12FaultCodeSender;
+ faultSubCodeHref = xmlSecXkmsNs;
+ faultSubCodeLocalPart = xmlSecXkmsSoapSubcodeValueBadMessage;
+
+ len = xmlStrlen(BAD_CAST xmlSecErrorsSafeString(ctx->requestNode->name)) +
+ xmlStrlen(xmlSecXkmsSoapFaultReasonMessageNotSupported) + 1;
+ faultReason = xmlMalloc(len + 1);
+ if(faultReason == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlMalloc",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ xmlSecStrPrintf(faultReason, len , xmlSecXkmsSoapFaultReasonMessageNotSupported,
+ xmlSecErrorsSafeString(ctx->requestNode->name));
+ } else {
+ /* just some error */
+ faultCode = xmlSecSoap12FaultCodeReceiver;
+ faultReason = xmlStrdup(xmlSecXkmsSoapFaultReasonServiceUnavailable);
+ if(faultReason == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ }
+ xmlSecAssert2(faultCode != xmlSecSoap12FaultCodeUnknown, -1);
+ xmlSecAssert2(faultReason != NULL, -1);
+
+ faultNode = xmlSecSoap12AddFaultEntry(envNode, faultCode, faultReason,
+ xmlSecXkmsSoapFaultReasonLang, NULL, NULL);
+ if(faultNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12AddFaultEntry",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ xmlFree(faultReason);
+ return(-1);
+ }
+ xmlFree(faultReason);
+
+ if((faultSubCodeHref != NULL) && (faultSubCodeLocalPart != NULL)) {
+ /* make sure that we have subcode (xkms) namespace declared */
+ if(xmlNewNs(faultNode, faultSubCodeHref, BAD_CAST "xkms") == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewNs",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "ns=%s",
+ xmlSecErrorsSafeString(faultSubCodeHref));
+ return(-1);
+ }
+ if(xmlSecSoap12AddFaultSubcode(faultNode, faultSubCodeHref, faultSubCodeLocalPart) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecSoap12AddFaultSubcode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "href=%s,value=%s",
+ xmlSecErrorsSafeString(faultSubCodeHref),
+ xmlSecErrorsSafeString(faultSubCodeLocalPart));
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+#endif /* XMLSEC_NO_SOAP */
+
+
+/**
+ * xmlSecXkmsServerCtxSetResult:
+ * @ctx: the pointer to XKMS processing context.
+ * @resultMajor: the major result code.
+ * @resultMinor: the minor result code.
+ *
+ * Sets the major/minor result code in the context if no other result is already
+ * reported.
+ */
+void
+xmlSecXkmsServerCtxSetResult(xmlSecXkmsServerCtxPtr ctx, xmlSecXkmsResultMajor resultMajor,
+ xmlSecXkmsResultMinor resultMinor) {
+ xmlSecAssert(ctx != NULL);
+
+ if((ctx->resultMajor == xmlSecXkmsResultMajorSuccess) &&
+ (resultMinor != xmlSecXkmsResultMajorSuccess)) {
+ ctx->resultMajor = resultMajor;
+ ctx->resultMinor = resultMinor;
+ } else if((ctx->resultMajor == xmlSecXkmsResultMajorSuccess) &&
+ (ctx->resultMinor == xmlSecXkmsResultMinorNone)) {
+ xmlSecAssert(resultMajor == xmlSecXkmsResultMajorSuccess);
+
+ ctx->resultMinor = resultMinor;
+ }
+}
+
+
+/**
+ * xmlSecXkmsServerCtxDebugDump:
+ * @ctx: the pointer to XKMS processing context.
+ * @output: the pointer to output FILE.
+ *
+ * Prints the debug information about @ctx to @output.
+ */
+void
+xmlSecXkmsServerCtxDebugDump(xmlSecXkmsServerCtxPtr ctx, FILE* output) {
+ xmlSecAssert(ctx != NULL);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "= XKMS SERVER CONTEXT: %s\n",
+ (ctx->requestId != xmlSecXkmsServerRequestIdUnknown &&
+ xmlSecXkmsServerRequestKlassGetName(ctx->requestId)) ?
+ xmlSecXkmsServerRequestKlassGetName(ctx->requestId) :
+ BAD_CAST "NULL");
+
+ xmlSecQName2IntegerDebugDump(gXmlSecXkmsResultMajorInfo,
+ ctx->resultMajor, BAD_CAST "resultMajor", output);
+ xmlSecQName2IntegerDebugDump(gXmlSecXkmsMinorErrorInfo,
+ ctx->resultMinor, BAD_CAST "resultMinor", output);
+
+ fprintf(output, "== id: %s\n",
+ (ctx->id) ? ctx->id : BAD_CAST "");
+ fprintf(output, "== service: %s\n",
+ (ctx->service) ? ctx->service : BAD_CAST "");
+ fprintf(output, "== nonce: %s\n",
+ (ctx->nonce) ? ctx->nonce : BAD_CAST "");
+ fprintf(output, "== originalRequestId: %s\n",
+ (ctx->originalRequestId) ? ctx->originalRequestId : BAD_CAST "");
+ fprintf(output, "== pendingNotificationMechanism: %s\n",
+ (ctx->pendingNotificationMechanism) ?
+ ctx->pendingNotificationMechanism :
+ BAD_CAST "");
+ fprintf(output, "== pendingNotificationIdentifier: %s\n",
+ (ctx->pendingNotificationIdentifier) ?
+ ctx->pendingNotificationIdentifier :
+ BAD_CAST "");
+ if(ctx->responseLimit != XMLSEC_XKMS_NO_RESPONSE_LIMIT) {
+ fprintf(output, "== ResponseLimit: %d\n", ctx->responseLimit);
+ }
+ xmlSecQName2BitMaskDebugDump(gXmlSecXkmsResponseMechanismInfo,
+ ctx->responseMechanismMask, BAD_CAST "responseMechanism", output);
+
+ if(ctx->expectedService != NULL) {
+ fprintf(output, "== expected service: %s\n", ctx->expectedService);
+ }
+ fprintf(output, "== flags: 0x%08x\n", ctx->flags);
+ fprintf(output, "== flags2: 0x%08x\n", ctx->flags2);
+
+ fprintf(output, "== Key Info Read Ctx:\n");
+ xmlSecKeyInfoCtxDebugDump(&(ctx->keyInfoReadCtx), output);
+
+ fprintf(output, "== Key Info Write Ctx:\n");
+ xmlSecKeyInfoCtxDebugDump(&(ctx->keyInfoWriteCtx), output);
+
+ if(xmlSecPtrListGetSize(&(ctx->enabledRespondWithIds)) > 0) {
+ fprintf(output, "== Enabled RespondWith: ");
+ xmlSecTransformIdListDebugDump(&(ctx->enabledRespondWithIds), output);
+ } else {
+ fprintf(output, "== Enabled RespondWith: all\n");
+ }
+
+ if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
+ fprintf(output, "== Enabled ServerRequest: ");
+ xmlSecTransformIdListDebugDump(&(ctx->enabledServerRequestIds), output);
+ } else {
+ fprintf(output, "== Enabled ServerRequest: all\n");
+ }
+
+ fprintf(output, "== RespondWith List:\n");
+ xmlSecPtrListDebugDump(&(ctx->respWithList), output);
+
+ fprintf(output, "== Keys:\n");
+ xmlSecPtrListDebugDump(&(ctx->keys), output);
+
+ if(ctx->compoundRequestContexts != NULL) {
+ fprintf(output, "== Compound Request:\n");
+ xmlSecPtrListDebugDump(ctx->compoundRequestContexts, output);
+ }
+}
+
+/**
+ * xmlSecXkmsServerCtxDebugXmlDump:
+ * @ctx: the pointer to XKMS processing context.
+ * @output: the pointer to output FILE.
+ *
+ * Prints the debug information about @ctx to @output in XML format.
+ */
+void
+xmlSecXkmsServerCtxDebugXmlDump(xmlSecXkmsServerCtxPtr ctx, FILE* output) {
+ xmlSecAssert(ctx != NULL);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<XkmsServerRequestContext name=\"");
+ xmlSecPrintXmlString(output,
+ (ctx->requestId != xmlSecXkmsServerRequestIdUnknown) ?
+ xmlSecXkmsServerRequestKlassGetName(ctx->requestId) :
+ BAD_CAST "NULL"
+ );
+ fprintf(output, "\">\n");
+
+ xmlSecQName2IntegerDebugXmlDump(gXmlSecXkmsResultMajorInfo,
+ ctx->resultMajor, BAD_CAST "MajorError", output);
+ xmlSecQName2IntegerDebugXmlDump(gXmlSecXkmsMinorErrorInfo,
+ ctx->resultMinor, BAD_CAST "MinorError", output);
+
+ fprintf(output, "<Id>");
+ xmlSecPrintXmlString(output, ctx->id);
+ fprintf(output, "</Id>\n");
+
+ fprintf(output, "<Service>");
+ xmlSecPrintXmlString(output, ctx->service);
+ fprintf(output, "</Service>\n");
+
+ fprintf(output, "<Nonce>");
+ xmlSecPrintXmlString(output, ctx->nonce);
+ fprintf(output, "</Nonce>\n");
+
+ fprintf(output, "<OriginalRequestId>");
+ xmlSecPrintXmlString(output, ctx->originalRequestId);
+ fprintf(output, "</OriginalRequestId>\n");
+
+ fprintf(output, "<PendingNotificationMechanism>");
+ xmlSecPrintXmlString(output, ctx->pendingNotificationMechanism);
+ fprintf(output, "</PendingNotificationMechanism>\n");
+
+ fprintf(output, "<PendingNotificationIdentifier>");
+ xmlSecPrintXmlString(output, ctx->pendingNotificationIdentifier);
+ fprintf(output, "</PendingNotificationIdentifier>\n");
+
+ if(ctx->responseLimit != XMLSEC_XKMS_NO_RESPONSE_LIMIT) {
+ fprintf(output, "<ResponseLimit>%d</ResponseLimit>\n", ctx->responseLimit);
+ }
+ xmlSecQName2BitMaskDebugXmlDump(gXmlSecXkmsResponseMechanismInfo,
+ ctx->responseMechanismMask, BAD_CAST "ResponseMechanism", output);
+
+
+ fprintf(output, "<ExpectedService>");
+ xmlSecPrintXmlString(output, ctx->expectedService);
+ fprintf(output, "</ExpectedService>\n");
+
+ fprintf(output, "<Flags>%08x</Flags>\n", ctx->flags);
+ fprintf(output, "<Flags2>%08x</Flags2>\n", ctx->flags2);
+
+ fprintf(output, "<KeyInfoReadCtx>\n");
+ xmlSecKeyInfoCtxDebugXmlDump(&(ctx->keyInfoReadCtx), output);
+ fprintf(output, "</KeyInfoReadCtx>\n");
+
+ fprintf(output, "<KeyInfoWriteCtx>\n");
+ xmlSecKeyInfoCtxDebugXmlDump(&(ctx->keyInfoWriteCtx), output);
+ fprintf(output, "</KeyInfoWriteCtx>\n");
+
+ if(xmlSecPtrListGetSize(&(ctx->enabledRespondWithIds)) > 0) {
+ fprintf(output, "<EnabledRespondWith>\n");
+ xmlSecTransformIdListDebugXmlDump(&(ctx->enabledRespondWithIds), output);
+ fprintf(output, "</EnabledRespondWith>\n");
+ } else {
+ fprintf(output, "<EnabledRespondWith>all</EnabledRespondWith>\n");
+ }
+
+ if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
+ fprintf(output, "<EnabledServerRequest>\n");
+ xmlSecTransformIdListDebugXmlDump(&(ctx->enabledServerRequestIds), output);
+ fprintf(output, "</EnabledServerRequest>\n");
+ } else {
+ fprintf(output, "<EnabledServerRequest>all</EnabledServerRequest>\n");
+ }
+
+
+ fprintf(output, "<RespondWithList>\n");
+ xmlSecPtrListDebugXmlDump(&(ctx->respWithList), output);
+ fprintf(output, "</RespondWithList>\n");
+
+ fprintf(output, "<Keys>\n");
+ xmlSecPtrListDebugXmlDump(&(ctx->keys), output);
+ fprintf(output, "</Keys>\n");
+
+ if(ctx->compoundRequestContexts != NULL) {
+ fprintf(output, "<CompoundRequest>\n");
+ xmlSecPtrListDebugXmlDump(ctx->compoundRequestContexts, output);
+ fprintf(output, "</CompoundRequest>\n");
+ }
+
+ fprintf(output, "</XkmsServerRequestContext>\n");
+}
+
+/**
+ * <xkms:MessageAbstractType Id Service Nonce?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ *
+ * <xkms:RequestAbstractType Id Service Nonce? OriginalRequestId? ResponseLimit?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:ResponseMechanism>*
+ * <xkms:RespondWith>*
+ * <xkms:PendingNotification Mechanism Identifier>?
+ *
+ * XML Schema:
+ *
+ * <!-- RequestAbstractType -->
+ * <complexType name="RequestAbstractType" abstract="true">
+ * <complexContent>
+ * <extension base="xkms:MessageAbstractType">
+ * <sequence>
+ * <element ref="xkms:ResponseMechanism" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * <element ref="xkms:RespondWith" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * <element ref="xkms:PendingNotification" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="OriginalRequestId" type="anyURI"
+ * use="optional"/>
+ * <attribute name="ResponseLimit" type="integer" use="optional"/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /RequestAbstractType -->
+ *
+ * <!-- MessageAbstractType -->
+ * <complexType name="MessageAbstractType" abstract="true">
+ * <sequence>
+ * <element ref="ds:Signature" minOccurs="0"/>
+ * <element ref="xkms:MessageExtension" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * <element ref="xkms:OpaqueClientData" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="Id" type="ID" use="required"/>
+ * <attribute name="Service" type="anyURI" use="required"/>
+ * <attribute name="Nonce" type="base64Binary" use="optional"/>
+ * </complexType>
+ * <!-- /MessageAbstractType -->
+ */
+static int
+xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
+ xmlNodePtr cur;
+ xmlChar* tmp;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2((*node) != NULL, -1);
+
+ cur = (*node);
+ xmlSecAssert2(cur != NULL, -1);
+
+ /* required Id attribute */
+ xmlSecAssert2(ctx->id == NULL, -1);
+ ctx->id = xmlGetProp(cur, xmlSecAttrId);
+ if(ctx->id == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlGetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s;node=%s",
+ xmlSecErrorsSafeString(xmlSecAttrId),
+ xmlSecErrorsSafeString(cur->name));
+ return(-1);
+ }
+
+ /* required Service attribute */
+ xmlSecAssert2(ctx->service == NULL, -1);
+ ctx->service = xmlGetProp(cur, xmlSecAttrService);
+ if(ctx->service == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlGetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s;node=%s",
+ xmlSecErrorsSafeString(xmlSecAttrService),
+ xmlSecErrorsSafeString(cur->name));
+ return(-1);
+ }
+
+ /* check service */
+ if((ctx->expectedService != NULL) && (!xmlStrEqual(ctx->expectedService, ctx->service))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "expectedService=%s;actualService=%s",
+ xmlSecErrorsSafeString(ctx->expectedService),
+ xmlSecErrorsSafeString(ctx->service));
+ return(-1);
+ }
+
+ /* optional Nonce attribute */
+ xmlSecAssert2(ctx->nonce == NULL, -1);
+ ctx->nonce = xmlGetProp(cur, xmlSecAttrNonce);
+
+ /* optional OriginalRequestId attribute */
+ xmlSecAssert2(ctx->originalRequestId == NULL, -1);
+ ctx->originalRequestId = xmlGetProp(cur, xmlSecAttrOriginalRequestId);
+
+ /* optional ResponseLimit attribute */
+ xmlSecAssert2(ctx->responseLimit == XMLSEC_XKMS_NO_RESPONSE_LIMIT, -1);
+ tmp = xmlGetProp(cur, xmlSecAttrResponseLimit);
+ if(tmp != NULL) {
+ ctx->responseLimit = atoi((char*)tmp);
+ xmlFree(tmp);
+ }
+
+ /* now read children */
+ cur = xmlSecGetNextElementNode(cur->children);
+
+ /* first node is optional <dsig:Signature/> node */
+ if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeSignature, xmlSecDSigNs)) {
+ ret = xmlSecXkmsServerCtxSignatureNodeRead(ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxSignatureNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next is zero or more <xkms:MessageExtension/> nodes */
+ ret = xmlSecXkmsServerCtxMessageExtensionNodesRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxMessageExtensionNodesRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* next is optional <xkms:OpaqueClientData/> node */
+ if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeOpaqueClientData, xmlSecXkmsNs)) {
+ ret = xmlSecXkmsServerCtxOpaqueClientDataNodeRead(ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxOpaqueClientDataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next is zero or more <xkms:ResponseMechanism/> nodes */
+ ret = xmlSecQName2BitMaskNodesRead(gXmlSecXkmsResponseMechanismInfo, &cur,
+ xmlSecNodeResponseMechanism, xmlSecXkmsNs,
+ ((ctx->flags & XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_RESPONSE_MECHANISM) != 0) ? 1 : 0,
+ &ctx->responseMechanismMask);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2BitMaskNodesRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecNodeResponseMechanism));
+ return(-1);
+ }
+
+ /* next is zero or more <xkms:RespondWith/> nodes */
+ ret = xmlSecXkmsServerCtxRespondWithNodesRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRespondWithNodesRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* next is optional <xkms:PendingNotification/> node */
+ if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodePendingNotification, xmlSecXkmsNs)) {
+ ret = xmlSecXkmsServerCtxPendingNotificationNodeRead(ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxPendingNotificationNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ (*node) = cur;
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxSignatureNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* todo: verify signature and make sure that correct data was signed */
+ return(0);
+}
+
+/**
+ * <!-- MessageExtension -->
+ * <element name="MessageExtension" type="xkms:MessageExtensionAbstractType"
+ * abstract="true"/>
+ * <complexType name="MessageExtensionAbstractType" abstract="true"/>
+ * <!-- /MessageExtension -->
+ */
+static int
+xmlSecXkmsServerCtxMessageExtensionNodesRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->firtsMsgExtNode == NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = (*node);
+ while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeMessageExtension, xmlSecXkmsNs)) {
+ if(ctx->firtsMsgExtNode == NULL) {
+ ctx->firtsMsgExtNode = cur;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ (*node) = cur;
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxOpaqueClientDataNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(ctx->opaqueClientDataNode == NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* remember that node, will copy it in the response later */
+ ctx->opaqueClientDataNode = node;
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxRespondWithNodesRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = (*node);
+ while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeRespondWith, xmlSecXkmsNs)) {
+ xmlSecXkmsRespondWithId id = xmlSecXkmsRespondWithIdUnknown;
+
+ if(xmlSecPtrListGetSize(&(ctx->enabledRespondWithIds)) > 0) {
+ id = xmlSecXkmsRespondWithIdListFindByNodeValue(&(ctx->enabledRespondWithIds), cur);
+ } else {
+ id = xmlSecXkmsRespondWithIdListFindByNodeValue(xmlSecXkmsRespondWithIdsGet(), cur);
+ }
+
+ if(id != xmlSecXkmsRespondWithIdUnknown) {
+ ret = xmlSecXkmsRespondWithNodeRead(id, ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecCreateTree",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ } else if((ctx->flags & XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_RESPOND_WITH) != 0) {
+ xmlChar* content ;
+
+ content = xmlNodeGetContent(cur);
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(cur->name),
+ xmlSecErrorsSafeString(content));
+ if(content != NULL) {
+ xmlFree(content);
+ }
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ (*node) = cur;
+ return(0);
+}
+
+/**
+ * XML Schema:
+ * <!-- PendingNotification -->
+ * <element name="PendingNotification" type="xkms:PendingNotificationType"/>
+ * <complexType name="PendingNotificationType">
+ * <attribute name="Mechanism" type="anyURI" use="required"/>
+ * <attribute name="Identifier" type="anyURI" use="required"/>
+ * </complexType>
+ * <!-- /PendingNotification -->
+ */
+static int
+xmlSecXkmsServerCtxPendingNotificationNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ xmlSecAssert2(ctx->pendingNotificationMechanism == NULL, -1);
+ ctx->pendingNotificationMechanism = xmlGetProp(node, xmlSecAttrMechanism);
+ if(ctx->pendingNotificationMechanism == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlGetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s;node=%s",
+ xmlSecErrorsSafeString(xmlSecAttrMechanism),
+ xmlSecErrorsSafeString(node->name));
+ return(-1);
+ }
+
+ xmlSecAssert2(ctx->pendingNotificationIdentifier == NULL, -1);
+ ctx->pendingNotificationIdentifier = xmlGetProp(node, xmlSecAttrIdentifier);
+ if(ctx->pendingNotificationIdentifier == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlGetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s;node=%s",
+ xmlSecErrorsSafeString(xmlSecAttrIdentifier),
+ xmlSecErrorsSafeString(node->name));
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * <xkms:PendingRequestType Id Service Nonce? OriginalRequestId? ResponseLimit? ResponseId?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:ResponseMechanism>*
+ * <xkms:RespondWith>*
+ * <xkms:PendingNotification Mechanism Identifier>?
+ *
+ * XML Schema:
+ *
+ * <!-- PendingRequest -->
+ * <element name="PendingRequest" type="xkms:PendingRequestType"/>
+ * <complexType name="PendingRequestType">
+ * <complexContent>
+ * <extension base="xkms:RequestAbstractType">
+ * <attribute name="ResponseId" type="anyURI" use="optional"/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /PendingRequest --> *
+ */
+static int
+xmlSecXkmsServerCtxPendingRequestNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first read "parent" type */
+ ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* todo: read responseId */
+ return(0);
+}
+
+/**
+ * <xkms:QueryKeyBinding Id?
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:TimeInstant Time>?
+ *
+ * XML Schema:
+ * <!-- QueryKeyBinding -->
+ * <element name="QueryKeyBinding" type="xkms:QueryKeyBindingType"/>
+ * <complexType name="QueryKeyBindingType">
+ * <complexContent>
+ * <extension base="xkms:KeyBindingAbstractType">
+ * <sequence>
+ * <element ref="xkms:TimeInstant" minOccurs="0"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /QueryKeyBinding -->
+ */
+static int
+xmlSecXkmsServerCtxQueryKeyBindingNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first read "parent" type */
+ cur = node;
+ ret = xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* next is optional <xkms:TimeInstant/> node */
+ if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeTimeInstant, xmlSecXkmsNs)) {
+ ret = xmlSecXkmsServerCtxTimeInstantNodeRead(ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxTimeInstantNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* check that there is nothing after the last node */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * <xkms:KeyBindingAbstractType Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ *
+ * XML Schema:
+ * <!-- KeyBindingAbstractType-->
+ * <complexType name="KeyBindingAbstractType" abstract="true">
+ * <sequence>
+ * <element ref="ds:KeyInfo" minOccurs="0"/>
+ * <element ref="xkms:KeyUsage" minOccurs="0" maxOccurs="3"/>
+ * <element ref="xkms:UseKeyWith" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * </sequence>
+ * <attribute name="Id" type="ID" use="optional"/>
+ * </complexType>
+ * <!-- /KeyBindingAbstractType-->
+ */
+static int
+xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2((*node) != NULL, -1);
+
+ cur = (*node);
+ xmlSecAssert2(cur != NULL, -1);
+
+ /* we don't care about Id attribute in this node */
+ cur = xmlSecGetNextElementNode(cur->children);
+
+ /* first node is optional <dsig:KeyInfo/> node. for now we only remember pointer */
+ xmlSecAssert2(ctx->keyInfoNode == NULL, -1);
+ if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs)) {
+ ctx->keyInfoNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next is zero or more <xkms:KeyUsage/> nodes */
+ ret = xmlSecQName2BitMaskNodesRead(gXmlSecXkmsKeyUsageInfo, &cur,
+ xmlSecNodeKeyUsage, xmlSecXkmsNs,
+ ((ctx->flags & XMLSEC_XKMS_SERVER_FLAGS_STOP_ON_UNKNOWN_KEY_USAGE) != 0) ? 1 : 0,
+ &(ctx->keyInfoReadCtx.keyReq.keyUsage));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2BitMaskNodesRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyUsage));
+ return(-1);
+ }
+
+ /* next is zero or more <xkms:UseKeyWith/> nodes */
+ ret = xmlSecXkmsServerCtxUseKeyWithNodesRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxUseKeyWithNodesRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ (*node) = cur;
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+
+ /* generate and add Id attribute */
+ ret = xmlSecGenerateAndAddID(node, xmlSecAttrId, ctx->idPrefix, ctx->idLen);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGenerateAndAddID",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* <dsig:KeyInfo/> node */
+ cur = xmlSecAddChild(node, xmlSecNodeKeyInfo, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
+ return(-1);
+ }
+
+ ret = xmlSecXkmsServerCtxKeyInfoNodeWrite(ctx, cur, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxKeyInfoNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* next is <xkms:KeyUsage/> node */
+ ret = xmlSecQName2BitMaskNodesWrite(gXmlSecXkmsKeyUsageInfo, node,
+ xmlSecNodeKeyUsage, xmlSecXkmsNs,
+ key->usage);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2BitMaskNodesWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyUsage));
+ return(-1);
+ }
+
+ /* and the last node is <xkms:UseKeyWith/> */
+ ret = xmlSecXkmsServerCtxUseKeyWithNodesWrite(ctx, node, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxUseKeyWithNodesWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxKeyInfoNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* add child nodes as requested in <xkms:RespondWith/> nodes */
+ ret = xmlSecXkmsRespondWithIdListWrite(&(ctx->respWithList), ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdListWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecKeyInfoNodeWrite(node, key, &(ctx->keyInfoWriteCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+
+/**
+ * XML Schema:
+ * <!-- UseKeyWith -->
+ * <element name="UseKeyWith" type="xkms:UseKeyWithType"/>
+ * <complexType name="UseKeyWithType">
+ * <attribute name="Application" type="anyURI" use="required"/>
+ * <attribute name="Identifier" type="string" use="required"/>
+ * </complexType>
+ * <!-- /UseKeyWith -->
+ */
+static int
+xmlSecXkmsServerCtxUseKeyWithNodesRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr* node) {
+ xmlSecPtrListPtr list;
+ xmlNodePtr cur;
+ xmlSecKeyUseWithPtr keyUseWith;
+ xmlChar* application;
+ xmlChar* identifier;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ list = &(ctx->keyInfoReadCtx.keyReq.keyUseWithList);
+ xmlSecAssert2(xmlSecPtrListGetSize(list) == 0, -1);
+
+ cur = (*node);
+ while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeUseKeyWith, xmlSecXkmsNs)) {
+ application = xmlGetProp(cur, xmlSecAttrApplication);
+ if(application == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlGetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s;node=%s",
+ xmlSecErrorsSafeString(xmlSecAttrApplication),
+ xmlSecErrorsSafeString(cur->name));
+ return(-1);
+ }
+
+ identifier = xmlGetProp(cur, xmlSecAttrIdentifier);
+ if(identifier == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlGetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s;node=%s",
+ xmlSecErrorsSafeString(xmlSecAttrIdentifier),
+ xmlSecErrorsSafeString(cur->name));
+ xmlFree(application);
+ return(-1);
+ }
+
+ keyUseWith = xmlSecKeyUseWithCreate(application, identifier);
+ if(keyUseWith == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyUseWithCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(application);
+ xmlFree(identifier);
+ return(-1);
+ }
+ xmlFree(application);
+ xmlFree(identifier);
+
+ ret = xmlSecPtrListAdd(list, keyUseWith);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyUseWithDestroy(keyUseWith);
+ return(-1);
+ }
+
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ (*node) = cur;
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxUseKeyWithNodesWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+
+ /* todo: write UseKeyWith */
+ return(0);
+}
+
+
+static int
+xmlSecXkmsServerCtxTimeInstantNodeRead(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* todo: parse xml schema dataTime or use libxml? */
+ return(0);
+}
+
+/**
+ * <xkms:ResultType Id Service Nonce? ResultMajor ResultMinor? RequestId?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:RequestSignatureValue>*
+ *
+ * XML Schema:
+ * <!-- ResultType -->
+ * <element name="Result" type="xkms:ResultType"/>
+ * <complexType name="ResultType">
+ * <complexContent>
+ * <extension base="xkms:MessageAbstractType">
+ * <sequence>
+ * <element ref="xkms:RequestSignatureValue" minOccurs="0"/>
+ * </sequence>
+ * <attribute name="ResultMajor" type="QName" use="required"/>
+ * <attribute name="ResultMinor" type="QName" use="optional"/>
+ * <attribute name="RequestId" type="anyURI" use="optional"/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /ResultType -->
+ */
+static int
+xmlSecXkmsServerCtxResultTypeNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* generate and add Id attribute */
+ ret = xmlSecGenerateAndAddID(node, xmlSecAttrId, ctx->idPrefix, ctx->idLen);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGenerateAndAddID",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* todo: generate nonce? */
+
+ /* set Service atribute (required) */
+ if((ctx->service == NULL) || (xmlSetProp(node, xmlSecAttrService, ctx->service) == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrService),
+ xmlSecErrorsSafeString(ctx->service));
+ return(-1);
+ }
+
+
+ /* set RequestId atribute (optional) */
+ if((ctx->id != NULL) && (xmlSetProp(node, xmlSecAttrRequestId, ctx->id) == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrRequestId),
+ xmlSecErrorsSafeString(ctx->id));
+ return(-1);
+ }
+
+
+ /* set major code (required) */
+ ret = xmlSecQName2IntegerAttributeWrite(gXmlSecXkmsResultMajorInfo, node,
+ xmlSecAttrResultMajor, ctx->resultMajor);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2IntegerAttributeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s,value=%d",
+ xmlSecErrorsSafeString(xmlSecAttrResultMajor),
+ ctx->resultMajor);
+ return(-1);
+ }
+
+ /* set minor code (optional) */
+ if(ctx->resultMinor != xmlSecXkmsResultMinorNone) {
+ ret = xmlSecQName2IntegerAttributeWrite(gXmlSecXkmsMinorErrorInfo, node,
+ xmlSecAttrResultMinor, ctx->resultMinor);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2IntegerAttributeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s,value=%d",
+ xmlSecErrorsSafeString(xmlSecAttrResultMinor),
+ ctx->resultMinor);
+ return(-1);
+ }
+ }
+
+ /* todo: create signature template */
+
+ /* todo: create message extension nodes? */
+
+ /* <xkms:OpaqueClientData/>: An XKMS service SHOULD return the value of
+ * the <OpaqueClientData> element unmodified in a request in a response
+ * with status code Succes */
+ if((ctx->resultMajor == xmlSecXkmsResultMajorSuccess) && (ctx->opaqueClientDataNode != NULL)) {
+ xmlNodePtr copyNode;
+
+ copyNode = xmlDocCopyNode(ctx->opaqueClientDataNode, node->doc, 1);
+ if(copyNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(ctx->opaqueClientDataNode->name));
+ return(-1);
+ }
+
+ if(xmlSecAddChildNode(node, copyNode) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChildNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(copyNode->name));
+ return(-1);
+ }
+ }
+
+ ret = xmlSecXkmsServerCtxRequestSignatureValueNodeWrite(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRequestSignatureValueNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * A service SHOULD include the <RequestSignatureValue> element in a response
+ * if the following conditions are satisfied and MUST NOT include the value
+ * otherwise:
+ *
+ *
+ * - The <ds:Signature> element was present in the corresponding request
+ * - The service successfully verified the <ds:Signature> element in the
+ * corresponding request, and
+ * - The ResponseMechanism RequestSignatureValue was specified.
+ *
+ */
+static int
+xmlSecXkmsServerCtxRequestSignatureValueNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* todo: check all conditions for RequestSignatureValue */
+ if((ctx->responseMechanismMask & XMLSEC_XKMS_RESPONSE_MECHANISM_MASK_REQUEST_SIGNATURE_VALUE) == 0) {
+ /* The ResponseMechanism RequestSignatureValue was not specified. */
+ return(0);
+ }
+
+ /* todo: write RequestSignatureValue */
+ return(0);
+}
+
+
+/**
+ *
+ * <xkms:UnverifiedKeyBindingType Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:ValidityInterval NotBefore NotOnOrAfter>?
+ *
+ * XML Schema:
+ *
+ * <!-- UnverifiedKeyBinding -->
+ * <element name="UnverifiedKeyBinding" type="xkms:UnverifiedKeyBindingType"/>
+ * <complexType name="UnverifiedKeyBindingType">
+ * <complexContent>
+ * <extension base="xkms:KeyBindingAbstractType">
+ * <sequence>
+ * <element ref="xkms:ValidityInterval" minOccurs="0"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /UnverifiedKeyBinding -->
+ */
+static int
+xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first write "parent" type */
+ ret = xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite(ctx, node, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* <xkms:ValidityInterval/> node */
+ ret = xmlSecXkmsServerCtxValidityIntervalNodeWrite(ctx, node, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxValidityIntervalNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int
+xmlSecXkmsServerCtxValidityIntervalNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* todo: write key validity interval */
+ return(0);
+}
+
+/**
+ * <xkms:KeyBinding Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:ValidityInterval NotBefore NotOnOrAfter>?
+ * <xkms:Status StatusValue>
+ * (<xkms:ValidReason>?
+ * <xkms:IndeterminateReason>?
+ * <xkms:InvalidReason>?
+ * )*
+ *
+ * XML Schema:
+ *
+ * <!-- KeyBinding -->
+ * <element name="KeyBinding" type="xkms:KeyBindingType"/>
+ * <complexType name="KeyBindingType">
+ * <complexContent>
+ * <extension base="xkms:UnverifiedKeyBindingType">
+ * <sequence>
+ * <element ref="xkms:Status"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /KeyBinding -->
+ */
+static int
+xmlSecXkmsServerCtxKeyBindingNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first write "parent" type */
+ ret = xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(ctx, node, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxKeyBindingAbstractTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* <xkms:Status/> node */
+ ret = xmlSecXkmsServerCtxKeyBindingStatusNodeWrite(ctx, node, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxKeyBindingStatusNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * <xkms:Status StatusValue>
+ * (<xkms:ValidReason>?
+ * <xkms:IndeterminateReason>?
+ * <xkms:InvalidReason>?
+ * )*
+ *
+ * XML Schema:
+ *
+ * <!-- Status -->
+ * <element name="Status" type="xkms:StatusType"/>
+ * <complexType name="StatusType">
+ * <sequence>
+ * <element ref="xkms:ValidReason" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * <element ref="xkms:IndeterminateReason" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * <element ref="xkms:InvalidReason" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * </sequence>
+ * <attribute name="StatusValue" type="xkms:KeyBindingStatus"
+ * use="required"/>
+ * </complexType>
+ * <simpleType name="KeyBindingStatus">
+ * <restriction base="QName">
+ * <enumeration value="xkms:Valid"/>
+ * <enumeration value="xkms:Invalid"/>
+ * <enumeration value="xkms:Indeterminate"/>
+ * </restriction>
+ * </simpleType>
+ * <!-- /Status -->
+ */
+static int
+xmlSecXkmsServerCtxKeyBindingStatusNodeWrite(xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node, xmlSecKeyPtr key) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(key != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = xmlSecAddChild(node, xmlSecNodeStatus, xmlSecXkmsNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeStatus));
+ return(-1);
+ }
+
+ /* if we are here then the key was validated */
+ ret = xmlSecQName2IntegerAttributeWrite(gXmlSecXkmsKeyBindingStatusInfo, cur,
+ xmlSecAttrStatusValue, xmlSecXkmsKeyBindingStatusValid);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecQName2IntegerAttributeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecAttrStatusValue));
+ return(-1);
+ }
+
+ /* todo: write the reasons */
+ return(0);
+}
+
+/************************************************************************
+ *
+ * xmlSecXkmsServerCtx list
+ *
+ ************************************************************************/
+static xmlSecPtrListKlass xmlSecXkmsServerCtxPtrListKlass = {
+ BAD_CAST "xkms-server-ctx-list",
+ NULL, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ (xmlSecPtrDestroyItemMethod)xmlSecXkmsServerCtxDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerCtxDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerCtxDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+xmlSecPtrListId
+xmlSecXkmsServerCtxPtrListGetKlass(void) {
+ return(&xmlSecXkmsServerCtxPtrListKlass);
+}
+
+
+/**************************************************************************
+ *
+ * Global xmlSecXkmsRespondWithIds list functions
+ *
+ *************************************************************************/
+static xmlSecPtrList xmlSecAllXkmsRespondWithIds;
+
+
+/**
+ * xmlSecXkmsRespondWithIdsGet:
+ *
+ * Gets global registered RespondWith klasses list.
+ *
+ * Returns: the pointer to list of all registered RespondWith klasses.
+ */
+xmlSecPtrListPtr
+xmlSecXkmsRespondWithIdsGet(void) {
+ return(&xmlSecAllXkmsRespondWithIds);
+}
+
+/**
+ * xmlSecXkmsRespondWithIdsInit:
+ *
+ * Initializes the RespondWith klasses. This function is called from the
+ * #xmlSecInit function and the application should not call it directly.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsRespondWithIdsInit(void) {
+ int ret;
+
+ ret = xmlSecPtrListInitialize(xmlSecXkmsRespondWithIdsGet(), xmlSecXkmsRespondWithIdListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListPtrInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecXkmsRespondWithIdListId");
+ return(-1);
+ }
+
+ ret = xmlSecXkmsRespondWithIdsRegisterDefault();
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegisterDefault",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsRespondWithIdsShutdown:
+ *
+ * Shuts down the keys data klasses. This function is called from the
+ * #xmlSecShutdown function and the application should not call it directly.
+ */
+void
+xmlSecXkmsRespondWithIdsShutdown(void) {
+ xmlSecPtrListFinalize(xmlSecXkmsRespondWithIdsGet());
+}
+
+/**
+ * xmlSecXkmsRespondWithIdsRegister:
+ * @id: the RespondWith klass.
+ *
+ * Registers @id in the global list of RespondWith klasses.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithId id) {
+ int ret;
+
+ xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
+
+ ret = xmlSecPtrListAdd(xmlSecXkmsRespondWithIdsGet(), (xmlSecPtr)id);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "RespondWith=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)));
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsRespondWithIdsRegisterDefault:
+ *
+ * Registers default (implemented by XML Security Library)
+ * RespondWith klasses: KeyName, KeyValue,...
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsRespondWithIdsRegisterDefault(void) {
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithKeyNameId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithKeyNameId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithKeyValueId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithKeyValueId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithPrivateKeyId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithPrivateKeyId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithRetrievalMethodId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithRetrievalMethodId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithX509CertId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithX509CertId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithX509ChainId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithX509ChainId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithX509CRLId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithX509CRLId)));
+ return(-1);
+ }
+
+ /* TODO: OCSP, PGP, PGPWeb, SPKI */
+ /*
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithPGPId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithPGPId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsRespondWithIdsRegister(xmlSecXkmsRespondWithSPKIId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsRespondWithIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(xmlSecXkmsRespondWithSPKIId)));
+ return(-1);
+ }
+ */
+ return(0);
+}
+
+
+/************************************************************************
+ *
+ * XKMS RespondWith Klass
+ *
+ ************************************************************************/
+/**
+ * xmlSecXkmsRespondWithNodeRead:
+ * @id: the RespondWith class.
+ * @ctx: the XKMS request processing context.
+ * @node: the pointer to <xkms:RespondWith/> node.
+ *
+ * Reads the content of the <xkms:RespondWith/> @node.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsRespondWithNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ if(id->readNode != NULL) {
+ return((id->readNode)(id, ctx, node));
+ }
+ return(0);
+}
+
+/**
+ * xmlSecXkmsRespondWithNodeWrite:
+ * @id: the RespondWith class.
+ * @ctx: the XKMS request processing context.
+ * @node: the pointer to <xkms:RespondWith/> node.
+ *
+ * Writes the content of the <xkms:RespondWith/> @node.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsRespondWithNodeWrite(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ if(id->writeNode != NULL) {
+ return((id->writeNode)(id, ctx, node));
+ }
+ return(0);
+}
+
+/**
+ * xmlSecXkmsRespondWithDebugDump:
+ * @id: the RespondWith class.
+ * @output: the output file.
+ *
+ * Writes debug information about @id into the @output.
+ */
+void
+xmlSecXkmsRespondWithDebugDump(xmlSecXkmsRespondWithId id, FILE* output) {
+ xmlSecAssert(id != xmlSecXkmsRespondWithIdUnknown);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "=== RespondWith: \"%s\" (href=\"%s\")\n",
+ xmlSecErrorsSafeString(id->valueName),
+ xmlSecErrorsSafeString(id->valueNs));
+}
+
+/**
+ * xmlSecXkmsRespondWithDebugXmlDump:
+ * @id: the RespondWith class.
+ * @output: the output file.
+ *
+ * Writes debug information about @id into the @output in XML format.
+ */
+void
+xmlSecXkmsRespondWithDebugXmlDump(xmlSecXkmsRespondWithId id, FILE* output) {
+ xmlSecAssert(id != xmlSecXkmsRespondWithIdUnknown);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<RespondWith href=\"");
+ xmlSecPrintXmlString(output, id->valueNs);
+ fprintf(output, "\">");
+ xmlSecPrintXmlString(output, id->valueName);
+ fprintf(output, "</RespondWith>\n");
+}
+
+int
+xmlSecXkmsRespondWithDefaultNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ ret = xmlSecXkmsRespondWithIdListFind(&(ctx->respWithList), id);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithIdListFind",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ } else if(ret > 0) {
+ /* do nothing, we already have it in the list */
+ return(0);
+ }
+
+ ret = xmlSecPtrListAdd(&(ctx->respWithList), id);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+int
+xmlSecXkmsRespondWithDefaultNodeWrite(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
+ xmlSecAssert2(id->nodeName != NULL, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = xmlSecAddChild(node, id->nodeName, id->nodeNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(id->nodeName));
+ return(-1);
+ }
+
+ return(0);
+}
+
+/************************************************************************
+ *
+ * XKMS RespondWith Klass List
+ *
+ ************************************************************************/
+static xmlSecPtrListKlass xmlSecXkmsRespondWithIdListKlass = {
+ BAD_CAST "respond-with-ids-list",
+ NULL, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ NULL, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsRespondWithDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsRespondWithDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+xmlSecPtrListId
+xmlSecXkmsRespondWithIdListGetKlass(void) {
+ return(&xmlSecXkmsRespondWithIdListKlass);
+}
+
+int
+xmlSecXkmsRespondWithIdListFind(xmlSecPtrListPtr list, xmlSecXkmsRespondWithId id) {
+ xmlSecSize i, size;
+
+ xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsRespondWithIdListId), -1);
+ xmlSecAssert2(id != xmlSecXkmsRespondWithIdUnknown, -1);
+
+ size = xmlSecPtrListGetSize(list);
+ for(i = 0; i < size; ++i) {
+ if((xmlSecXkmsRespondWithId)xmlSecPtrListGetItem(list, i) == id) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithIdListFindByNodeValue(xmlSecPtrListPtr list, xmlNodePtr node) {
+ xmlSecXkmsRespondWithId result = xmlSecXkmsRespondWithIdUnknown;
+ xmlSecXkmsRespondWithId id;
+ xmlChar* content;
+ xmlChar* qnameLocalPart = NULL;
+ xmlChar* qnamePrefix = NULL;
+ const xmlChar* qnameHref;
+ xmlNsPtr ns;
+ xmlSecSize i, size;
+
+ xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsRespondWithIdListId), xmlSecXkmsRespondWithIdUnknown);
+ xmlSecAssert2(node != NULL, xmlSecXkmsRespondWithIdUnknown);
+
+ content = xmlNodeGetContent(node);
+ if(content == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNodeGetContent",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(node->name));
+ return(xmlSecXkmsRespondWithIdUnknown);
+ }
+
+ qnameLocalPart = (xmlChar*)xmlStrchr(content, ':');
+ if(qnameLocalPart != NULL) {
+ qnamePrefix = content;
+ *(qnameLocalPart++) = '\0';
+ } else {
+ qnamePrefix = NULL;
+ qnameLocalPart = content;
+ }
+
+ /* search namespace href */
+ ns = xmlSearchNs(node->doc, node, qnamePrefix);
+ if((ns == NULL) && (qnamePrefix != NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSearchNs",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "node=%s,qnamePrefix=%s",
+ xmlSecErrorsSafeString(node->name),
+ xmlSecErrorsSafeString(qnamePrefix));
+ xmlFree(content);
+ return(xmlSecXkmsRespondWithIdUnknown);
+ }
+ qnameHref = (ns != NULL) ? ns->href : BAD_CAST NULL;
+
+ size = xmlSecPtrListGetSize(list);
+ for(i = 0; i < size; ++i) {
+ id = (xmlSecXkmsRespondWithId)xmlSecPtrListGetItem(list, i);
+ if((id != xmlSecXkmsRespondWithIdUnknown) &&
+ xmlStrEqual(id->valueName, qnameLocalPart) &&
+ xmlStrEqual(id->valueNs, qnameHref)) {
+ result = id;
+ break;
+ }
+ }
+
+ xmlFree(content);
+ return(result);
+}
+
+int
+xmlSecXkmsRespondWithIdListWrite(xmlSecPtrListPtr list, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecXkmsRespondWithId id;
+ xmlSecSize i, size;
+ int ret;
+
+ xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsRespondWithIdListId), -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ size = xmlSecPtrListGetSize(list);
+ for(i = 0; i < size; ++i) {
+ id = (xmlSecXkmsRespondWithId)xmlSecPtrListGetItem(list, i);
+ if(id != xmlSecXkmsRespondWithIdUnknown) {
+ ret = xmlSecXkmsRespondWithNodeWrite(id, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ }
+
+ return(0);
+}
+
+/********************************************************************
+ *
+ * XML Sec Library RespondWith Ids
+ *
+ *******************************************************************/
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithKeyNameKlass = {
+ xmlSecRespondWithKeyName, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeKeyName, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithDefaultNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithKeyNameGetKlass:
+ *
+ * The respond with KeyName klass.
+ *
+ * Returns: respond with KeyName klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithKeyNameGetKlass(void) {
+ return(&xmlSecXkmsRespondWithKeyNameKlass);
+}
+
+
+
+static int xmlSecXkmsRespondWithKeyValueNodeRead (xmlSecXkmsRespondWithId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithKeyValueKlass = {
+ xmlSecRespondWithKeyValue, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeKeyValue, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithKeyValueNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithKeyValueGetKlass:
+ *
+ * The respond with KeyValue klass.
+ *
+ * Returns: respond with KeyValue klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithKeyValueGetKlass(void) {
+ return(&xmlSecXkmsRespondWithKeyValueKlass);
+}
+
+static int
+xmlSecXkmsRespondWithKeyValueNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsRespondWithKeyValueId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* do usual stuff */
+ ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithDefaultNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* and now set some parameters in the ctx to look for a public or private
+ * key and to write a public key
+ */
+ ctx->keyInfoReadCtx.keyReq.keyType |= (xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
+ ctx->keyInfoWriteCtx.keyReq.keyType |= xmlSecKeyDataTypePublic;
+
+ return(0);
+}
+
+static int xmlSecXkmsRespondWithPrivateKeyNodeRead (xmlSecXkmsRespondWithId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithPrivateKeyKlass = {
+ xmlSecRespondWithPrivateKey, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeKeyValue, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithPrivateKeyNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithPrivateKeyGetKlass:
+ *
+ * The respond with PrivateKey klass.
+ *
+ * Returns: respond with PrivateKey klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithPrivateKeyGetKlass(void) {
+ return(&xmlSecXkmsRespondWithPrivateKeyKlass);
+}
+
+static int
+xmlSecXkmsRespondWithPrivateKeyNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsRespondWithPrivateKeyId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* do usual stuff */
+ ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithDefaultNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* and now set some parameters in the ctx to look for a private
+ * key and to write a private key
+ */
+ ctx->keyInfoReadCtx.keyReq.keyType |= xmlSecKeyDataTypePrivate;
+ ctx->keyInfoWriteCtx.keyReq.keyType |= xmlSecKeyDataTypePrivate;
+
+ return(0);
+}
+
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithRetrievalMethodKlass = {
+ xmlSecRespondWithRetrievalMethod, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeRetrievalMethod, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithDefaultNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithRetrievalMethodGetKlass:
+ *
+ * The respond with RetrievalMethod klass.
+ *
+ * Returns: respond with RetrievalMethod klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithRetrievalMethodGetKlass(void) {
+ return(&xmlSecXkmsRespondWithRetrievalMethodKlass);
+}
+
+
+
+static int xmlSecXkmsRespondWithX509CertNodeRead (xmlSecXkmsRespondWithId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithX509CertKlass = {
+ xmlSecRespondWithX509Cert, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeX509Data, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithX509CertNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithX509CertGetKlass:
+ *
+ * The respond with X509Cert klass.
+ *
+ * Returns: respond with X509Cert klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithX509CertGetKlass(void) {
+ return(&xmlSecXkmsRespondWithX509CertKlass);
+}
+
+static int
+xmlSecXkmsRespondWithX509CertNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsRespondWithX509CertId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* do usual stuff */
+ ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithDefaultNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int xmlSecXkmsRespondWithX509ChainNodeRead (xmlSecXkmsRespondWithId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithX509ChainKlass = {
+ xmlSecRespondWithX509Chain, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeX509Data, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithX509ChainNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithX509ChainGetKlass:
+ *
+ * The respond with X509Chain klass.
+ *
+ * Returns: respond with X509Chain klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithX509ChainGetKlass(void) {
+ return(&xmlSecXkmsRespondWithX509ChainKlass);
+}
+
+static int
+xmlSecXkmsRespondWithX509ChainNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsRespondWithX509ChainId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* do usual stuff */
+ ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithDefaultNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static int xmlSecXkmsRespondWithX509CRLNodeRead (xmlSecXkmsRespondWithId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithX509CRLKlass = {
+ xmlSecRespondWithX509CRL, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeX509Data, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithX509CRLNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithX509CRLGetKlass:
+ *
+ * The respond with X509CRL klass.
+ *
+ * Returns: respond with X509CRL klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithX509CRLGetKlass(void) {
+ return(&xmlSecXkmsRespondWithX509CRLKlass);
+}
+
+static int
+xmlSecXkmsRespondWithX509CRLNodeRead(xmlSecXkmsRespondWithId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsRespondWithX509CRLId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* do usual stuff */
+ ret = xmlSecXkmsRespondWithDefaultNodeRead(id, ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecXkmsRespondWithKlassGetName(id)),
+ "xmlSecXkmsRespondWithDefaultNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithPGPKlass = {
+ xmlSecRespondWithPGP, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodePGPData, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithDefaultNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithPGPGetKlass:
+ *
+ * The respond with PGP klass.
+ *
+ * Returns: respond with PGP klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithPGPGetKlass(void) {
+ return(&xmlSecXkmsRespondWithPGPKlass);
+}
+
+static xmlSecXkmsRespondWithKlass xmlSecXkmsRespondWithSPKIKlass = {
+ xmlSecRespondWithSPKI, /* const xmlChar* valueName; */
+ xmlSecXkmsNs, /* const xmlChar* valueNs; */
+ xmlSecNodeSPKIData, /* const xmlChar* nodeName; */
+ xmlSecDSigNs, /* const xmlChar* nodeNs; */
+ xmlSecXkmsRespondWithDefaultNodeRead, /* xmlSecXkmsRespondWithNodeReadMethod readNode; */
+ xmlSecXkmsRespondWithDefaultNodeWrite, /* xmlSecXkmsRespondWithNodeWriteMethod writeNode; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsRespondWithSPKIGetKlass:
+ *
+ * The respond with SPKI klass.
+ *
+ * Returns: respond with SPKI klass.
+ */
+xmlSecXkmsRespondWithId
+xmlSecXkmsRespondWithSPKIGetKlass(void) {
+ return(&xmlSecXkmsRespondWithSPKIKlass);
+}
+
+/**************************************************************************
+ *
+ * Global xmlSecXkmsServerRequestIds list functions
+ *
+ *************************************************************************/
+static xmlSecPtrList xmlSecAllXkmsServerRequestIds;
+
+
+/**
+ * xmlSecXkmsServerRequestIdsGet:
+ *
+ * Gets global registered ServerRequest klasses list.
+ *
+ * Returns: the pointer to list of all registered ServerRequest klasses.
+ */
+xmlSecPtrListPtr
+xmlSecXkmsServerRequestIdsGet(void) {
+ return(&xmlSecAllXkmsServerRequestIds);
+}
+
+/**
+ * xmlSecXkmsServerRequestIdsInit:
+ *
+ * Initializes the ServerRequest klasses. This function is called from the
+ * #xmlSecInit function and the application should not call it directly.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerRequestIdsInit(void) {
+ int ret;
+
+ ret = xmlSecPtrListInitialize(xmlSecXkmsServerRequestIdsGet(), xmlSecXkmsServerRequestIdListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListPtrInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecXkmsServerRequestIdListId");
+ return(-1);
+ }
+
+ ret = xmlSecXkmsServerRequestIdsRegisterDefault();
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdsRegisterDefault",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsServerRequestIdsShutdown:
+ *
+ * Shuts down the keys data klasses. This function is called from the
+ * #xmlSecShutdown function and the application should not call it directly.
+ */
+void
+xmlSecXkmsServerRequestIdsShutdown(void) {
+ xmlSecPtrListFinalize(xmlSecXkmsServerRequestIdsGet());
+}
+
+/**
+ * xmlSecXkmsServerRequestIdsRegister:
+ * @id: the ServerRequest klass.
+ *
+ * Registers @id in the global list of ServerRequest klasses.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestId id) {
+ int ret;
+
+ xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
+
+ ret = xmlSecPtrListAdd(xmlSecXkmsServerRequestIdsGet(), (xmlSecPtr)id);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "ServerRequest=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(id)));
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecXkmsServerRequestIdsRegisterDefault:
+ *
+ * Registers default (implemented by XML Security Library)
+ * ServerRequest klasses: KeyName, KeyValue,...
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerRequestIdsRegisterDefault(void) {
+ if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestResultId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestResultId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestStatusId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestStatusId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestCompoundId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestCompoundId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestLocateId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestLocateId)));
+ return(-1);
+ }
+
+ if(xmlSecXkmsServerRequestIdsRegister(xmlSecXkmsServerRequestValidateId) < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdsRegister",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "name=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(xmlSecXkmsServerRequestValidateId)));
+ return(-1);
+ }
+
+ return(0);
+}
+
+
+/************************************************************************
+ *
+ * XKMS ServerRequest Klass
+ *
+ ************************************************************************/
+/**
+ * xmlSecXkmsServerRequestNodeRead:
+ * @id: the ServerRequest class.
+ * @ctx: the XKMS request processing context.
+ * @node: the pointer to <xkms:ServerRequest/> node.
+ *
+ * Reads the content of the <xkms:ServerRequest/> @node.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerRequestNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node) {
+ xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ if(id->readNode != NULL) {
+ return((id->readNode)(id, ctx, node));
+ }
+ return(0);
+}
+
+/**
+ * xmlSecXkmsServerExecute:
+ * @id: the ServerRequest class.
+ * @ctx: the XKMS request processing context.
+ *
+ * Executes XKMS server request.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecXkmsServerRequestExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
+ xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ if(id->execute != NULL) {
+ return((id->execute)(id, ctx));
+ }
+ return(0);
+}
+
+
+/**
+ * xmlSecXkmsServerResponseNodeWrite:
+ * @id: the ServerRequest class.
+ * @ctx: the XKMS request processing context.
+ * @doc: the pointer to response parent XML document (might be NULL).
+ * @node: the pointer to response parent XML node (might be NULL).
+ *
+ * Writes XKMS response from context to a newly created node. Caller is
+ * responsible for adding the returned node to the XML document.
+ *
+ * Returns: pointer to newly created XKMS response node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecXkmsServerRequestNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx,
+ xmlDocPtr doc, xmlNodePtr node) {
+ xmlNodePtr respNode;
+ int ret;
+
+ xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, NULL);
+ xmlSecAssert2(ctx != NULL, NULL);
+
+ /* create the response root node */
+ if(node == NULL) {
+ xmlNsPtr ns;
+
+ respNode = xmlNewDocNode(doc, NULL, id->resultNodeName, NULL);
+ if(respNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewDocNode",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(id->resultNodeName));
+ return(NULL);
+ }
+ ns = xmlNewNs(respNode, id->resultNodeNs, NULL);
+ if(ns == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewNs",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "ns=%s",
+ xmlSecErrorsSafeString(id->resultNodeNs));
+ xmlFreeNode(respNode);
+ return(NULL);
+ }
+ xmlSetNs(respNode, ns);
+ } else {
+ respNode = xmlSecAddChild(node, id->resultNodeName, id->resultNodeNs);
+ if(respNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(id->resultNodeName));
+ return(NULL);
+ }
+ }
+
+ if(id->writeNode != NULL) {
+ ret = (id->writeNode)(id, ctx, respNode);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "writeNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(id->resultNodeName));
+ xmlFreeNode(respNode);
+ return(NULL);
+ }
+ }
+
+ return(respNode);
+}
+
+/**
+ * xmlSecXkmsServerRequestDebugDump:
+ * @id: the ServerRequest class.
+ * @output: the output file.
+ *
+ * Writes debug information about @id into the @output.
+ */
+void
+xmlSecXkmsServerRequestDebugDump(xmlSecXkmsServerRequestId id, FILE* output) {
+ xmlSecAssert(id != xmlSecXkmsServerRequestIdUnknown);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "=== ServerRequest: %s\n", xmlSecErrorsSafeString(id->name));
+}
+
+/**
+ * xmlSecXkmsServerRequestDebugXmlDump:
+ * @id: the ServerRequest class.
+ * @output: the output file.
+ *
+ * Writes debug information about @id into the @output in XML format.
+ */
+void
+xmlSecXkmsServerRequestDebugXmlDump(xmlSecXkmsServerRequestId id, FILE* output) {
+ xmlSecAssert(id != xmlSecXkmsServerRequestIdUnknown);
+ xmlSecAssert(output != NULL);
+
+ fprintf(output, "<ServerRequest>");
+ xmlSecPrintXmlString(output, id->name);
+ fprintf(output, "</ServerRequest>\n");
+}
+
+/************************************************************************
+ *
+ * XKMS ServerRequest Klass List
+ *
+ ************************************************************************/
+static xmlSecPtrListKlass xmlSecXkmsServerRequestIdListKlass = {
+ BAD_CAST "xkms-server-request-ids-list",
+ NULL, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
+ NULL, /* xmlSecPtrDestroyItemMethod destroyItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerRequestDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
+ (xmlSecPtrDebugDumpItemMethod)xmlSecXkmsServerRequestDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
+};
+
+xmlSecPtrListId
+xmlSecXkmsServerRequestIdListGetKlass(void) {
+ return(&xmlSecXkmsServerRequestIdListKlass);
+}
+
+int
+xmlSecXkmsServerRequestIdListFind(xmlSecPtrListPtr list, xmlSecXkmsServerRequestId id) {
+ xmlSecSize i, size;
+
+ xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsServerRequestIdListId), -1);
+ xmlSecAssert2(id != xmlSecXkmsServerRequestIdUnknown, -1);
+
+ size = xmlSecPtrListGetSize(list);
+ for(i = 0; i < size; ++i) {
+ if((xmlSecXkmsServerRequestId)xmlSecPtrListGetItem(list, i) == id) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestIdListFindByName(xmlSecPtrListPtr list, const xmlChar* name) {
+ xmlSecXkmsServerRequestId id;
+ xmlSecSize i, size;
+
+ xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsServerRequestIdListId), xmlSecXkmsServerRequestIdUnknown);
+ xmlSecAssert2(name != NULL, xmlSecXkmsServerRequestIdUnknown);
+
+ size = xmlSecPtrListGetSize(list);
+ for(i = 0; i < size; ++i) {
+ id = (xmlSecXkmsServerRequestId)xmlSecPtrListGetItem(list, i);
+ if((id != xmlSecXkmsServerRequestIdUnknown) && xmlStrEqual(id->name, name)) {
+ return(id);
+ }
+ }
+ return(xmlSecXkmsServerRequestIdUnknown);
+}
+
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestIdListFindByNode(xmlSecPtrListPtr list, xmlNodePtr node) {
+ xmlSecXkmsServerRequestId id;
+ xmlSecSize i, size;
+
+ xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecXkmsServerRequestIdListId), xmlSecXkmsServerRequestIdUnknown);
+ xmlSecAssert2(node != NULL, xmlSecXkmsServerRequestIdUnknown);
+
+ size = xmlSecPtrListGetSize(list);
+ for(i = 0; i < size; ++i) {
+ id = (xmlSecXkmsServerRequestId)xmlSecPtrListGetItem(list, i);
+ if((id != xmlSecXkmsServerRequestIdUnknown) &&
+ xmlSecCheckNodeName(node, id->requestNodeName, id->requestNodeNs)) {
+
+ return(id);
+ }
+ }
+ return(xmlSecXkmsServerRequestIdUnknown);
+}
+
+/********************************************************************
+ *
+ * XML Sec Library ServerRequest Ids
+ *
+ *******************************************************************/
+
+
+/********************************************************************
+ *
+ * Result response
+ *
+ *******************************************************************/
+static int xmlSecXkmsServerRequestResultNodeWrite (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+
+static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestResultKlass = {
+ xmlSecXkmsServerRequestResultName, /* const xmlChar* name; */
+ NULL, /* const xmlChar* requestNodeName; */
+ NULL, /* const xmlChar* requestNodeNs; */
+ xmlSecNodeResult, /* const xmlChar* responseNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* responseNodeNs; */
+ 0, /* xmlSecBitMask flags; */
+ NULL, /* xmlSecXkmsServerRequestNodeReadMethod readNode; */
+ xmlSecXkmsServerRequestResultNodeWrite, /* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
+ NULL, /* xmlSecXkmsServerRequestExecuteMethod execute; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsServerRequestResultGetKlass:
+ *
+ * The Result response klass.
+ *
+ * Returns: Result response klass.
+ */
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestResultGetKlass(void) {
+ return(&xmlSecXkmsServerRequestResultKlass);
+}
+
+static int
+xmlSecXkmsServerRequestResultNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestResultId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* set missing parameters (if any) */
+ if(ctx->service == NULL) {
+ ctx->service = xmlStrdup((ctx->expectedService != NULL) ? ctx->expectedService : BAD_CAST "");
+ if(ctx->service == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlStrdup",
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ /* first write the "parent" type */
+ ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResultTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/********************************************************************
+ *
+ * StatusRequest/StatusResponse
+ *
+ *******************************************************************/
+static int xmlSecXkmsServerRequestStatusNodeRead (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestStatusNodeWrite (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+
+static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestStatusKlass = {
+ xmlSecXkmsServerRequestStatusName, /* const xmlChar* name; */
+ xmlSecNodeStatusRequest, /* const xmlChar* requestNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* requestNodeNs; */
+ xmlSecNodeStatusResult, /* const xmlChar* responseNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* responseNodeNs; */
+ 0, /* xmlSecBitMask flags; */
+ xmlSecXkmsServerRequestStatusNodeRead, /* xmlSecXkmsServerRequestNodeReadMethod readNode; */
+ xmlSecXkmsServerRequestStatusNodeWrite, /* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
+ NULL, /* xmlSecXkmsServerRequestExecuteMethod execute; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsServerRequestStatusGetKlass:
+ *
+ * The StatusRequest klass.
+ *
+ * Returns: StatusRequest klass.
+ */
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestStatusGetKlass(void) {
+ return(&xmlSecXkmsServerRequestStatusKlass);
+}
+
+/**
+ *
+ * <xkms:StatusRequest Id Service Nonce? OriginalRequestId? ResponseLimit? ResponseId?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:ResponseMechanism>*
+ * <xkms:RespondWith>*
+ * <xkms:PendingNotification Mechanism Identifier>?
+ *
+ * XML Schema:
+ * <!-- StatusRequest -->
+ * <element name="StatusRequest" type="xkms:StatusRequestType"/>
+ * <complexType name="StatusRequestType">
+ * <complexContent>
+ * <extension base="xkms:PendingRequestType"/>
+ * </complexContent>
+ * </complexType>
+ * <!-- /StatusRequest -->
+ */
+static int
+xmlSecXkmsServerRequestStatusNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestStatusId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = node;
+
+ /* first read "parent" type */
+ ret = xmlSecXkmsServerCtxPendingRequestNodeRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxPendingRequestNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* check that there is nothing after the last node */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ *
+ * <xkms:StatusResult Id Service Nonce? ResultMajor ResultMinor? RequestId? Success? Failure? Pending?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:RequestSignatureValue>*
+ *
+ * XML Schema:
+ *
+ * <!-- StatusResult -->
+ * <element name="StatusResult" type="xkms:StatusResultType"/>
+ * <complexType name="StatusResultType">
+ * <complexContent>
+ * <extension base="xkms:ResultType">
+ * <attribute name="Success" type="integer" use="optional"/>
+ * <attribute name="Failure" type="integer" use="optional"/>
+ * <attribute name="Pending" type="integer" use="optional"/>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /StatusResult --> *
+ */
+static int
+xmlSecXkmsServerRequestStatusNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestStatusId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first write the "parent" type */
+ ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResultTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* todo: add optional StatusResult attributes */
+ return(0);
+}
+
+/********************************************************************
+ *
+ * CompoundRequest/CompoundResponse
+ *
+ *******************************************************************/
+static int xmlSecXkmsServerRequestCompoundNodeRead (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestCompoundNodeWrite(xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestCompoundExecute (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx);
+
+static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestCompoundKlass = {
+ xmlSecXkmsServerRequestCompoundName, /* const xmlChar* name; */
+ xmlSecNodeCompoundRequest, /* const xmlChar* requestNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* requestNodeNs; */
+ xmlSecNodeCompoundResult, /* const xmlChar* responseNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* responseNodeNs; */
+ 0, /* xmlSecBitMask flags; */
+ xmlSecXkmsServerRequestCompoundNodeRead, /* xmlSecXkmsServerRequestNodeReadMethod readNode; */
+ xmlSecXkmsServerRequestCompoundNodeWrite, /* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
+ xmlSecXkmsServerRequestCompoundExecute, /* xmlSecXkmsServerRequestExecuteMethod execute; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsServerRequestCompoundGetKlass:
+ *
+ * The CompoundRequest klass.
+ *
+ * Returns: CompoundRequest klass.
+ */
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestCompoundGetKlass(void) {
+ return(&xmlSecXkmsServerRequestCompoundKlass);
+}
+
+/**
+ * <xkms:CompoundRequest Id Service Nonce? OriginalRequestId? ResponseLimit?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:ResponseMechanism>*
+ * <xkms:RespondWith>*
+ * <xkms:PendingNotification Mechanism Identifier>?
+ * (
+ * <xkms:LocateRequest>?
+ * <xkms:ValidateRequest>?
+ * <xkms:RegisterRequest>?
+ * <xkms:ReissueRequest>?
+ * <xkms:RecoverRequest>?
+ * <xkms:RevokeRequest>?
+ * )*
+ *
+ * XML Schema:
+ *
+ * <!-- CompoundRequest -->
+ * <element name="CompoundRequest" type="xkms:CompoundRequestType"/>
+ * <complexType name="CompoundRequestType">
+ * <complexContent>
+ * <extension base="xkms:RequestAbstractType">
+ * <choice maxOccurs="unbounded">
+ * <element ref="xkms:LocateRequest"/>
+ * <element ref="xkms:ValidateRequest"/>
+ * <element ref="xkms:RegisterRequest"/>
+ * <element ref="xkms:ReissueRequest"/>
+ * <element ref="xkms:RecoverRequest"/>
+ * <element ref="xkms:RevokeRequest"/>
+ * </choice>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /CompoundRequest -->
+ */
+static int
+xmlSecXkmsServerRequestCompoundNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecPtrListPtr serverRequestIdsList;
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestCompoundId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = node;
+
+ /* first read "parent" type */
+ ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* create list for compound requests */
+ xmlSecAssert2(ctx->compoundRequestContexts == NULL, -1);
+ ctx->compoundRequestContexts = xmlSecPtrListCreate(xmlSecXkmsServerCtxPtrListId);
+ if(ctx->compoundRequestContexts == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* get the list of enabled or all request klasses */
+ if(xmlSecPtrListGetSize(&(ctx->enabledServerRequestIds)) > 0) {
+ serverRequestIdsList = &(ctx->enabledServerRequestIds);
+ } else {
+ serverRequestIdsList = xmlSecXkmsServerRequestIdsGet();
+ }
+ xmlSecAssert2(serverRequestIdsList != NULL, -1);
+
+ while(cur != NULL) {
+ xmlSecXkmsServerCtxPtr ctxChild;
+
+ /* create a new context */
+ ctxChild = xmlSecXkmsServerCtxCreate(ctx->keyInfoReadCtx.keysMngr);
+ if(ctxChild == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* copy all settings from us */
+ ret = xmlSecXkmsServerCtxCopyUserPref(ctxChild, ctx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxCopyUserPref",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxDestroy(ctxChild);
+ return(-1);
+ }
+
+ /* add it to the list */
+ ret = xmlSecPtrListAdd(ctx->compoundRequestContexts, ctxChild);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxDestroy(ctxChild);
+ return(-1);
+ }
+
+ /* and now process request from current node */
+ ctxChild->requestId = xmlSecXkmsServerRequestIdListFindByNode(serverRequestIdsList, cur);
+ if((ctxChild->requestId == xmlSecXkmsServerRequestIdUnknown) ||
+ ((ctxChild->requestId->flags & XMLSEC_XKMS_SERVER_REQUEST_KLASS_ALLOWED_IN_COUMPOUND) == 0)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestIdListFindByNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(node->name));
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorMessageNotSupported);
+ return(-1);
+ }
+
+ ret = xmlSecXkmsServerRequestNodeRead(ctxChild->requestId, ctxChild, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "request=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctxChild->requestId)));
+ xmlSecXkmsServerCtxSetResult(ctxChild, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* check that there is nothing after the last node */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * <xkms:CompoundResult Id Service Nonce? ResultMajor ResultMinor? RequestId?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:RequestSignatureValue>*
+ * (
+ * <xkms:LocateResult>?
+ * <xkms:ValidateResult>?
+ * <xkms:RegisterResult>?
+ * <xkms:ReissueResult>?
+ * <xkms:RecoverResult>?
+ * <xkms:RevokeResult>?
+ * )*
+ *
+ *
+ * XML Schema:
+ *
+ * <!-- CompoundResponse -->
+ * <element name="CompoundResult" type="xkms:CompoundResultType"/>
+ * <complexType name="CompoundResultType">
+ * <complexContent>
+ * <extension base="xkms:ResultType">
+ * <choice maxOccurs="unbounded">
+ * <element ref="xkms:LocateResult"/>
+ * <element ref="xkms:ValidateResult"/>
+ * <element ref="xkms:RegisterResult"/>
+ * <element ref="xkms:ReissueResult"/>
+ * <element ref="xkms:RecoverResult"/>
+ * <element ref="xkms:RevokeResult"/>
+ * </choice>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /CompoundResponse -->
+ */
+static int
+xmlSecXkmsServerRequestCompoundNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestCompoundId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* walk thru the list of chilren and pickup first error */
+ if(ctx->compoundRequestContexts != NULL) {
+ xmlSecSize pos;
+
+ for(pos = 0; pos < xmlSecPtrListGetSize(ctx->compoundRequestContexts); pos++) {
+ xmlSecXkmsServerCtxPtr ctxChild;
+
+ ctxChild = (xmlSecXkmsServerCtxPtr)xmlSecPtrListGetItem(ctx->compoundRequestContexts, pos);
+ if(ctxChild == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListGetItem",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ if(ctxChild->resultMajor != xmlSecXkmsResultMajorSuccess) {
+ xmlSecXkmsServerCtxSetResult(ctx, ctxChild->resultMajor, ctxChild->resultMinor);
+ break;
+ }
+ }
+ }
+
+ /* first write the "parent" type */
+ ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResultTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* write compound result */
+ if(ctx->compoundRequestContexts != NULL) {
+ xmlSecSize pos;
+
+ for(pos = 0; pos < xmlSecPtrListGetSize(ctx->compoundRequestContexts); pos++) {
+ xmlSecXkmsServerCtxPtr ctxChild;
+ xmlNodePtr cur;
+
+ ctxChild = (xmlSecXkmsServerCtxPtr)xmlSecPtrListGetItem(ctx->compoundRequestContexts, pos);
+ if(ctxChild == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListGetItem",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cur = xmlSecXkmsServerRequestNodeWrite(ctxChild->requestId, ctxChild, node->doc, node);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "request=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctxChild->requestId)));
+ return(-1);
+ }
+
+ if(xmlSecAddChildNode(node, cur) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChildNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFreeNode(cur);
+ return(-1);
+ }
+ }
+ }
+
+ return(0);
+}
+
+static int
+xmlSecXkmsServerRequestCompoundExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestCompoundId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ if(ctx->compoundRequestContexts != NULL) {
+ xmlSecSize pos;
+
+ for(pos = 0; pos < xmlSecPtrListGetSize(ctx->compoundRequestContexts); pos++) {
+ xmlSecXkmsServerCtxPtr ctxChild;
+
+ ctxChild = (xmlSecXkmsServerCtxPtr)xmlSecPtrListGetItem(ctx->compoundRequestContexts, pos);
+ if(ctxChild == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListGetItem",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorReceiver, xmlSecXkmsResultMinorFailure);
+ continue;
+ }
+
+ ret = xmlSecXkmsServerRequestExecute(ctxChild->requestId, ctxChild);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerRequestExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "request=%s",
+ xmlSecErrorsSafeString(xmlSecXkmsServerRequestKlassGetName(ctxChild->requestId)));
+ xmlSecXkmsServerCtxSetResult(ctxChild, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorFailure);
+ continue;
+ }
+ }
+ }
+
+ return(0);
+}
+
+
+/********************************************************************
+ *
+ * LocateRequest/LocateResponse
+ *
+ *******************************************************************/
+static int xmlSecXkmsServerRequestLocateNodeRead (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestLocateNodeWrite (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestLocateExecute (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx);
+
+static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestLocateKlass = {
+ xmlSecXkmsServerRequestLocateName, /* const xmlChar* name; */
+ xmlSecNodeLocateRequest, /* const xmlChar* requestNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* requestNodeNs; */
+ xmlSecNodeLocateResult, /* const xmlChar* responseNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* responseNodeNs; */
+ XMLSEC_XKMS_SERVER_REQUEST_KLASS_ALLOWED_IN_COUMPOUND, /* xmlSecBitMask flags; */
+ xmlSecXkmsServerRequestLocateNodeRead, /* xmlSecXkmsServerRequestNodeReadMethod readNode; */
+ xmlSecXkmsServerRequestLocateNodeWrite, /* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
+ xmlSecXkmsServerRequestLocateExecute, /* xmlSecXkmsServerRequestExecuteMethod execute; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsServerRequestLocateGetKlass:
+ *
+ * The LocateRequest klass.
+ *
+ * Returns: LocateRequest klass.
+ */
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestLocateGetKlass(void) {
+ return(&xmlSecXkmsServerRequestLocateKlass);
+}
+
+/**
+ * <xkms:LocateRequest Id Service Nonce? OriginalRequestId? ResponseLimit?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:ResponseMechanism>*
+ * <xkms:RespondWith>*
+ * <xkms:PendingNotification Mechanism Identifier>?
+ * <xkms:QueryKeyBinding Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:TimeInstant Time>?
+ *
+ * XML Schema:
+ *
+ * <!-- LocateRequest -->
+ * <element name="LocateRequest" type="xkms:LocateRequestType"/>
+ * <complexType name="LocateRequestType">
+ * <complexContent>
+ * <extension base="xkms:RequestAbstractType">
+ * <sequence>
+ * <element ref="xkms:QueryKeyBinding"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /LocateRequest -->
+ */
+static int
+xmlSecXkmsServerRequestLocateNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestLocateId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = node;
+
+ /* first read "parent" type */
+ ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* now read required <xkms:QueryKeyBinding/> node */
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeQueryKeyBinding, xmlSecXkmsNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeQueryKeyBinding));
+ return(-1);
+ }
+
+ /* read <xkms:QueryKeyBinding/> node */
+ ret = xmlSecXkmsServerCtxQueryKeyBindingNodeRead(ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxQueryKeyBindingNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* check that there is nothing after the last node */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * <xkms:LocateResult Id Service Nonce? ResultMajor ResultMinor? RequestId?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:RequestSignatureValue>*
+ * (<xkms:UnverifiedKeyBinding Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:ValidityInterval NotBefore NotOnOrAfter>?
+ * )*
+ *
+ * XML Schema:
+ * <!-- LocateResult -->
+ * <element name="LocateResult" type="xkms:LocateResultType"/>
+ * <complexType name="LocateResultType">
+ * <complexContent>
+ * <extension base="xkms:ResultType">
+ * <sequence>
+ * <element ref="xkms:UnverifiedKeyBinding" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /LocateResult -->
+ */
+static int
+xmlSecXkmsServerRequestLocateNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecSize pos, size;
+ xmlSecKeyPtr key;
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestLocateId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first write the "parent" type */
+ ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResultTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* write keys in <xkms:UnverifiedKeyBinding> nodes */
+ size = xmlSecPtrListGetSize(&(ctx->keys));
+ for(pos = 0; pos < size; ++pos) {
+ key = (xmlSecKeyPtr)xmlSecPtrListGetItem(&(ctx->keys), pos);
+ if(key == NULL) {
+ continue;
+ }
+
+ cur = xmlSecAddChild(node, xmlSecNodeUnverifiedKeyBinding, xmlSecXkmsNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeUnverifiedKeyBinding));
+ return(-1);
+ }
+
+ ret = xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite(ctx, cur, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxUnverifiedKeyBindingNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+static int
+xmlSecXkmsServerRequestLocateExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
+ xmlSecKeyPtr key = NULL;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestLocateId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ /* now we are ready to search for key */
+ if((ctx->keyInfoReadCtx.keysMngr != NULL) && (ctx->keyInfoReadCtx.keysMngr->getKey != NULL)) {
+ /* todo: set parameters to locate but not validate the key */
+ key = (ctx->keyInfoReadCtx.keysMngr->getKey)(ctx->keyInfoNode, &(ctx->keyInfoReadCtx));
+ }
+
+ /* check that we got what we needed */
+ if((key == NULL) || (!xmlSecKeyMatch(key, NULL, &(ctx->keyInfoReadCtx.keyReq)))) {
+ if(key != NULL) {
+ xmlSecKeyDestroy(key);
+ }
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorNoMatch);
+ return(-1);
+ }
+
+ xmlSecAssert2(key != NULL, -1);
+ ret = xmlSecPtrListAdd(&(ctx->keys), key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDestroy(key);
+ return(-1);
+ }
+
+ return(0);
+}
+
+
+/********************************************************************
+ *
+ * ValidateRequest/ValidateResponse
+ *
+ *******************************************************************/
+static int xmlSecXkmsServerRequestValidateNodeRead (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestValidateNodeWrite(xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx,
+ xmlNodePtr node);
+static int xmlSecXkmsServerRequestValidateExecute (xmlSecXkmsServerRequestId id,
+ xmlSecXkmsServerCtxPtr ctx);
+
+static xmlSecXkmsServerRequestKlass xmlSecXkmsServerRequestValidateKlass = {
+ xmlSecXkmsServerRequestValidateName, /* const xmlChar* name; */
+ xmlSecNodeValidateRequest, /* const xmlChar* requestNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* requestNodeNs; */
+ xmlSecNodeValidateResult, /* const xmlChar* responseNodeName; */
+ xmlSecXkmsNs, /* const xmlChar* responseNodeNs; */
+ XMLSEC_XKMS_SERVER_REQUEST_KLASS_ALLOWED_IN_COUMPOUND, /* xmlSecBitMask flags; */
+ xmlSecXkmsServerRequestValidateNodeRead, /* xmlSecXkmsServerRequestNodeReadMethod readNode; */
+ xmlSecXkmsServerRequestValidateNodeWrite, /* xmlSecXkmsServerRequestNodeWriteMethod writeNode; */
+ xmlSecXkmsServerRequestValidateExecute, /* xmlSecXkmsServerRequestExecuteMethod execute; */
+ NULL, /* void* reserved1; */
+ NULL /* void* reserved2; */
+};
+
+/**
+ * xmlSecXkmsServerRequestValidateGetKlass:
+ *
+ * The ValidateRequest klass.
+ *
+ * Returns: ValidateRequest klass.
+ */
+xmlSecXkmsServerRequestId
+xmlSecXkmsServerRequestValidateGetKlass(void) {
+ return(&xmlSecXkmsServerRequestValidateKlass);
+}
+
+/**
+ * <xkms:ValidateRequest Id Service Nonce? OriginalRequestId? ResponseLimit?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:ResponseMechanism>*
+ * <xkms:RespondWith>*
+ * <xkms:PendingNotification Mechanism Identifier>?
+ * <xkms:QueryKeyBinding Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:TimeInstant Time>?
+ *
+ * XML Schema:
+ *
+ * <!-- ValidateRequest -->
+ * <element name="ValidateRequest" type="xkms:ValidateRequestType"/>
+ * <complexType name="ValidateRequestType">
+ * <complexContent>
+ * <extension base="xkms:RequestAbstractType">
+ * <sequence>
+ * <element ref="xkms:QueryKeyBinding"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /ValidateRequest -->
+ */
+static int
+xmlSecXkmsServerRequestValidateNodeRead(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestValidateId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = node;
+
+ /* first read "parent" type */
+ ret = xmlSecXkmsServerCtxRequestAbstractTypeNodeRead(ctx, &cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxRequestAbstractTypeNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* now read required <xkms:QueryKeyBinding/> node */
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeQueryKeyBinding, xmlSecXkmsNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeQueryKeyBinding));
+ return(-1);
+ }
+
+ /* read <xkms:QueryKeyBinding/> node */
+ ret = xmlSecXkmsServerCtxQueryKeyBindingNodeRead(ctx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxQueryKeyBindingNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* check that there is nothing after the last node */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * <xkms:ValidateResult Id Service Nonce? ResultMajor ResultMinor? RequestId?>
+ * <ds:Signature>?
+ * <xkms:MessageExtension>*
+ * (<xkms:OpaqueClientData>
+ * <xkms:OpaqueData>?
+ * )?
+ * <xkms:RequestSignatureValue>*
+ * (<xkms:KeyBinding Id?>
+ * <ds:KeyInfo>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:KeyUsage>?
+ * <xkms:UseKeyWith Application Identifier>*
+ * <xkms:ValidityInterval NotBefore NotOnOrAfter>?
+ * <xkms:Status StatusValue>
+ * (<xkms:ValidReason>?
+ * <xkms:IndeterminateReason>?
+ * <xkms:InvalidReason>?
+ * )*
+ * )*
+ *
+ * XML Schema:
+ *
+ * <!-- ValidateResult -->
+ * <element name="ValidateResult" type="xkms:ValidateResultType"/>
+ * <complexType name="ValidateResultType">
+ * <complexContent>
+ * <extension base="xkms:ResultType">
+ * <sequence>
+ * <element ref="xkms:KeyBinding" minOccurs="0"
+ * maxOccurs="unbounded"/>
+ * </sequence>
+ * </extension>
+ * </complexContent>
+ * </complexType>
+ * <!-- /ValidateResult -->
+ */
+static int
+xmlSecXkmsServerRequestValidateNodeWrite(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx, xmlNodePtr node) {
+ xmlSecSize pos, size;
+ xmlSecKeyPtr key;
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestValidateId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first write the "parent" type */
+ ret = xmlSecXkmsServerCtxResultTypeNodeWrite(ctx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxResultTypeNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* write keys in <xkms:UnverifiedKeyBinding> nodes */
+ size = xmlSecPtrListGetSize(&(ctx->keys));
+ for(pos = 0; pos < size; ++pos) {
+ key = (xmlSecKeyPtr)xmlSecPtrListGetItem(&(ctx->keys), pos);
+ if(key == NULL) {
+ continue;
+ }
+
+ cur = xmlSecAddChild(node, xmlSecNodeUnverifiedKeyBinding, xmlSecXkmsNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeUnverifiedKeyBinding));
+ return(-1);
+ }
+
+ ret = xmlSecXkmsServerCtxKeyBindingNodeWrite(ctx, cur, key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecXkmsServerCtxKeyBindingNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+static int
+xmlSecXkmsServerRequestValidateExecute(xmlSecXkmsServerRequestId id, xmlSecXkmsServerCtxPtr ctx) {
+ xmlSecKeyPtr key = NULL;
+ int ret;
+
+ xmlSecAssert2(id == xmlSecXkmsServerRequestValidateId, -1);
+ xmlSecAssert2(ctx != NULL, -1);
+
+ /* now we are ready to search for key */
+ if((ctx->keyInfoReadCtx.keysMngr != NULL) && (ctx->keyInfoReadCtx.keysMngr->getKey != NULL)) {
+ key = (ctx->keyInfoReadCtx.keysMngr->getKey)(ctx->keyInfoNode, &(ctx->keyInfoReadCtx));
+ }
+
+ /* check that we got what we needed */
+ if((key == NULL) || (!xmlSecKeyMatch(key, NULL, &(ctx->keyInfoReadCtx.keyReq)))) {
+ if(key != NULL) {
+ xmlSecKeyDestroy(key);
+ }
+ xmlSecXkmsServerCtxSetResult(ctx, xmlSecXkmsResultMajorSender, xmlSecXkmsResultMinorNoMatch);
+ return(-1);
+ }
+
+ xmlSecAssert2(key != NULL, -1);
+ ret = xmlSecPtrListAdd(&(ctx->keys), key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecKeyDestroy(key);
+ return(-1);
+ }
+
+ return(0);
+}
+
+#endif /* XMLSEC_NO_XKMS */
+