summaryrefslogtreecommitdiff
path: root/src/xmlenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmlenc.c')
-rw-r--r--src/xmlenc.c1339
1 files changed, 1339 insertions, 0 deletions
diff --git a/src/xmlenc.c b/src/xmlenc.c
new file mode 100644
index 00000000..44c98779
--- /dev/null
+++ b/src/xmlenc.c
@@ -0,0 +1,1339 @@
+/**
+ * XML Security Library (http://www.aleksey.com/xmlsec).
+ *
+ * "XML Encryption" implementation
+ * http://www.w3.org/TR/xmlenc-core
+ *
+ * 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_XMLENC
+
+#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/xmlenc.h>
+#include <xmlsec/errors.h>
+
+static int xmlSecEncCtxEncDataNodeRead (xmlSecEncCtxPtr encCtx,
+ xmlNodePtr node);
+static int xmlSecEncCtxEncDataNodeWrite (xmlSecEncCtxPtr encCtx);
+static int xmlSecEncCtxCipherDataNodeRead (xmlSecEncCtxPtr encCtx,
+ xmlNodePtr node);
+static int xmlSecEncCtxCipherReferenceNodeRead (xmlSecEncCtxPtr encCtx,
+ xmlNodePtr node);
+
+/* The ID attribute in XMLEnc is 'Id' */
+static const xmlChar* xmlSecEncIds[] = { BAD_CAST "Id", NULL };
+
+
+/**
+ * xmlSecEncCtxCreate:
+ * @keysMngr: the pointer to keys manager.
+ *
+ * Creates <enc:EncryptedData/> element processing context.
+ * The caller is responsible for destroying returned object by calling
+ * #xmlSecEncCtxDestroy function.
+ *
+ * Returns: pointer to newly allocated context object or NULL if an error
+ * occurs.
+ */
+xmlSecEncCtxPtr
+xmlSecEncCtxCreate(xmlSecKeysMngrPtr keysMngr) {
+ xmlSecEncCtxPtr encCtx;
+ int ret;
+
+ encCtx = (xmlSecEncCtxPtr) xmlMalloc(sizeof(xmlSecEncCtx));
+ if(encCtx == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "sizeof(xmlSecEncCtx)=%d",
+ sizeof(xmlSecEncCtx));
+ return(NULL);
+ }
+
+ ret = xmlSecEncCtxInitialize(encCtx, keysMngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecEncCtxDestroy(encCtx);
+ return(NULL);
+ }
+ return(encCtx);
+}
+
+/**
+ * xmlSecEncCtxDestroy:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ *
+ * Destroy context object created with #xmlSecEncCtxCreate function.
+ */
+void
+xmlSecEncCtxDestroy(xmlSecEncCtxPtr encCtx) {
+ xmlSecAssert(encCtx != NULL);
+
+ xmlSecEncCtxFinalize(encCtx);
+ xmlFree(encCtx);
+}
+
+/**
+ * xmlSecEncCtxInitialize:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @keysMngr: the pointer to keys manager.
+ *
+ * Initializes <enc:EncryptedData/> element processing context.
+ * The caller is responsible for cleaning up returned object by calling
+ * #xmlSecEncCtxFinalize function.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecEncCtxInitialize(xmlSecEncCtxPtr encCtx, xmlSecKeysMngrPtr keysMngr) {
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+
+ memset(encCtx, 0, sizeof(xmlSecEncCtx));
+
+ /* initialize key info */
+ ret = xmlSecKeyInfoCtxInitialize(&(encCtx->keyInfoReadCtx), keysMngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ encCtx->keyInfoReadCtx.mode = xmlSecKeyInfoModeRead;
+
+ ret = xmlSecKeyInfoCtxInitialize(&(encCtx->keyInfoWriteCtx), keysMngr);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ encCtx->keyInfoWriteCtx.mode = xmlSecKeyInfoModeWrite;
+ /* it's not wise to write private key :) */
+ encCtx->keyInfoWriteCtx.keyReq.keyType = xmlSecKeyDataTypePublic;
+
+ /* initializes transforms encCtx */
+ ret = xmlSecTransformCtxInitialize(&(encCtx->transformCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxFinalize:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ *
+ * Cleans up @encCtx object.
+ */
+void
+xmlSecEncCtxFinalize(xmlSecEncCtxPtr encCtx) {
+ xmlSecAssert(encCtx != NULL);
+
+ xmlSecEncCtxReset(encCtx);
+
+ xmlSecTransformCtxFinalize(&(encCtx->transformCtx));
+ xmlSecKeyInfoCtxFinalize(&(encCtx->keyInfoReadCtx));
+ xmlSecKeyInfoCtxFinalize(&(encCtx->keyInfoWriteCtx));
+
+ memset(encCtx, 0, sizeof(xmlSecEncCtx));
+}
+
+/**
+ * xmlSecEncCtxReset:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ *
+ * Resets @encCtx object, user settings are not touched.
+ */
+void
+xmlSecEncCtxReset(xmlSecEncCtxPtr encCtx) {
+ xmlSecAssert(encCtx != NULL);
+
+ xmlSecTransformCtxReset(&(encCtx->transformCtx));
+ xmlSecKeyInfoCtxReset(&(encCtx->keyInfoReadCtx));
+ xmlSecKeyInfoCtxReset(&(encCtx->keyInfoWriteCtx));
+
+ encCtx->operation = xmlSecTransformOperationNone;
+ encCtx->result = NULL;
+ encCtx->resultBase64Encoded = 0;
+ encCtx->resultReplaced = 0;
+ encCtx->encMethod = NULL;
+
+ if (encCtx->replacedNodeList != NULL) {
+ xmlFreeNodeList(encCtx->replacedNodeList);
+ encCtx->replacedNodeList = NULL;
+ }
+
+ if(encCtx->encKey != NULL) {
+ xmlSecKeyDestroy(encCtx->encKey);
+ encCtx->encKey = NULL;
+ }
+
+ if(encCtx->id != NULL) {
+ xmlFree(encCtx->id);
+ encCtx->id = NULL;
+ }
+
+ if(encCtx->type != NULL) {
+ xmlFree(encCtx->type);
+ encCtx->type = NULL;
+ }
+
+ if(encCtx->mimeType != NULL) {
+ xmlFree(encCtx->mimeType);
+ encCtx->mimeType = NULL;
+ }
+
+ if(encCtx->encoding != NULL) {
+ xmlFree(encCtx->encoding);
+ encCtx->encoding = NULL;
+ }
+
+ if(encCtx->recipient != NULL) {
+ xmlFree(encCtx->recipient);
+ encCtx->recipient = NULL;
+ }
+
+ if(encCtx->carriedKeyName != NULL) {
+ xmlFree(encCtx->carriedKeyName);
+ encCtx->carriedKeyName = NULL;
+ }
+
+ encCtx->encDataNode = encCtx->encMethodNode =
+ encCtx->keyInfoNode = encCtx->cipherValueNode = NULL;
+}
+
+/**
+ * xmlSecEncCtxCopyUserPref:
+ * @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
+xmlSecEncCtxCopyUserPref(xmlSecEncCtxPtr dst, xmlSecEncCtxPtr src) {
+ int ret;
+
+ xmlSecAssert2(dst != NULL, -1);
+ xmlSecAssert2(src != NULL, -1);
+
+ dst->userData = src->userData;
+ dst->flags = src->flags;
+ dst->flags2 = src->flags2;
+ dst->defEncMethodId = src->defEncMethodId;
+ dst->mode = src->mode;
+
+ ret = xmlSecTransformCtxCopyUserPref(&(dst->transformCtx), &(src->transformCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCopyUserPref",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ 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);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxBinaryEncrypt:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @tmpl: the pointer to <enc:EncryptedData/> template node.
+ * @data: the pointer for binary buffer.
+ * @dataSize: the @data buffer size.
+ *
+ * Encrypts @data according to template @tmpl.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecEncCtxBinaryEncrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr tmpl,
+ const xmlSecByte* data, xmlSecSize dataSize) {
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(encCtx->result == NULL, -1);
+ xmlSecAssert2(tmpl != NULL, -1);
+ xmlSecAssert2(data != NULL, -1);
+
+ /* initialize context and add ID atributes to the list of known ids */
+ encCtx->operation = xmlSecTransformOperationEncrypt;
+ xmlSecAddIDs(tmpl->doc, tmpl, xmlSecEncIds);
+
+ /* read the template and set encryption method, key, etc. */
+ ret = xmlSecEncCtxEncDataNodeRead(encCtx, tmpl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecTransformCtxBinaryExecute(&(encCtx->transformCtx), data, dataSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxBinaryExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "dataSize=%d",
+ dataSize);
+ return(-1);
+ }
+
+ encCtx->result = encCtx->transformCtx.result;
+ xmlSecAssert2(encCtx->result != NULL, -1);
+
+ ret = xmlSecEncCtxEncDataNodeWrite(encCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxXmlEncrypt:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @tmpl: the pointer to <enc:EncryptedData/> template node.
+ * @node: the pointer to node for encryption.
+ *
+ * Encrypts @node according to template @tmpl. If requested, @node is replaced
+ * with result <enc:EncryptedData/> node.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecEncCtxXmlEncrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr tmpl, xmlNodePtr node) {
+ xmlOutputBufferPtr output;
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(encCtx->result == NULL, -1);
+ xmlSecAssert2(tmpl != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(node->doc != NULL, -1);
+
+ /* initialize context and add ID atributes to the list of known ids */
+ encCtx->operation = xmlSecTransformOperationEncrypt;
+ xmlSecAddIDs(tmpl->doc, tmpl, xmlSecEncIds);
+
+ /* read the template and set encryption method, key, etc. */
+ ret = xmlSecEncCtxEncDataNodeRead(encCtx, tmpl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecTransformCtxPrepare(&(encCtx->transformCtx), xmlSecTransformDataTypeBin);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxPrepare",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "type=bin");
+ return(-1);
+ }
+
+ xmlSecAssert2(encCtx->transformCtx.first != NULL, -1);
+ output = xmlSecTransformCreateOutputBuffer(encCtx->transformCtx.first,
+ &(encCtx->transformCtx));
+ if(output == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecTransformGetName(encCtx->transformCtx.first)),
+ "xmlSecTransformCreateOutputBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* push data thru */
+ if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
+ /* get the content of the node */
+ xmlNodeDumpOutput(output, node->doc, node, 0, 0, NULL);
+ } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
+ xmlNodePtr cur;
+
+ /* get the content of the nodes childs */
+ for(cur = node->children; cur != NULL; cur = cur->next) {
+ xmlNodeDumpOutput(output, node->doc, cur, 0, 0, NULL);
+ }
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_TYPE,
+ "type=%s",
+ xmlSecErrorsSafeString(encCtx->type));
+ xmlOutputBufferClose(output);
+ return(-1);
+ }
+
+ /* close the buffer and flush everything */
+ ret = xmlOutputBufferClose(output);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlOutputBufferClose",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ encCtx->result = encCtx->transformCtx.result;
+ xmlSecAssert2(encCtx->result != NULL, -1);
+
+ ret = xmlSecEncCtxEncDataNodeWrite(encCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* now we need to update our original document */
+ if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
+ /* check if we need to return the replaced node */
+ if((encCtx->flags & XMLSEC_ENC_RETURN_REPLACED_NODE) != 0) {
+ ret = xmlSecReplaceNodeAndReturn(node, tmpl, &(encCtx->replacedNodeList));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ } else {
+ ret = xmlSecReplaceNode(node, tmpl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ }
+
+ encCtx->resultReplaced = 1;
+ } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
+ /* check if we need to return the replaced node */
+ if((encCtx->flags & XMLSEC_ENC_RETURN_REPLACED_NODE) != 0) {
+ ret = xmlSecReplaceContentAndReturn(node, tmpl, &(encCtx->replacedNodeList));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceContentAndReturn",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ } else {
+ ret = xmlSecReplaceContent(node, tmpl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceContent",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ }
+
+ encCtx->resultReplaced = 1;
+ } else {
+ /* we should've catached this error before */
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_TYPE,
+ "type=%s",
+ xmlSecErrorsSafeString(encCtx->type));
+ return(-1);
+ }
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxUriEncrypt:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @tmpl: the pointer to <enc:EncryptedData/> template node.
+ * @uri: the URI.
+ *
+ * Encrypts data from @uri according to template @tmpl.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecEncCtxUriEncrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr tmpl, const xmlChar *uri) {
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(encCtx->result == NULL, -1);
+ xmlSecAssert2(tmpl != NULL, -1);
+ xmlSecAssert2(uri != NULL, -1);
+
+ /* initialize context and add ID atributes to the list of known ids */
+ encCtx->operation = xmlSecTransformOperationEncrypt;
+ xmlSecAddIDs(tmpl->doc, tmpl, xmlSecEncIds);
+
+ /* we need to add input uri transform first */
+ ret = xmlSecTransformCtxSetUri(&(encCtx->transformCtx), uri, tmpl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxSetUri",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "uri=%s",
+ xmlSecErrorsSafeString(uri));
+ return(-1);
+ }
+
+ /* read the template and set encryption method, key, etc. */
+ ret = xmlSecEncCtxEncDataNodeRead(encCtx, tmpl);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* encrypt the data */
+ ret = xmlSecTransformCtxExecute(&(encCtx->transformCtx), tmpl->doc);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ encCtx->result = encCtx->transformCtx.result;
+ xmlSecAssert2(encCtx->result != NULL, -1);
+
+ ret = xmlSecEncCtxEncDataNodeWrite(encCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxDecrypt:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @node: the pointer to <enc:EncryptedData/> node.
+ *
+ * Decrypts @node and if necessary replaces @node with decrypted data.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecEncCtxDecrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
+ xmlSecBufferPtr buffer;
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* decrypt */
+ buffer = xmlSecEncCtxDecryptToBuffer(encCtx, node);
+ if(buffer == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxDecryptToBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* replace original node if requested */
+ if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
+ /* check if we need to return the replaced node */
+ if((encCtx->flags & XMLSEC_ENC_RETURN_REPLACED_NODE) != 0) {
+ ret = xmlSecReplaceNodeBufferAndReturn(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), &(encCtx->replacedNodeList));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceNodeBufferAndReturn",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ } else {
+ ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceNodeBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ }
+
+ encCtx->resultReplaced = 1;
+ } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
+ /* replace the node with the buffer */
+
+ /* check if we need to return the replaced node */
+ if((encCtx->flags & XMLSEC_ENC_RETURN_REPLACED_NODE) != 0) {
+ ret = xmlSecReplaceNodeBufferAndReturn(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), &(encCtx->replacedNodeList));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceNodeBufferAndReturn",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ } else {
+ ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceNodeBuffer",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
+ return(-1);
+ }
+ }
+ encCtx->resultReplaced = 1;
+ }
+
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxDecryptToBuffer:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @node: the pointer to <enc:EncryptedData/> node.
+ *
+ * Decrypts @node data to the @encCtx buffer.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+xmlSecBufferPtr
+xmlSecEncCtxDecryptToBuffer(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, NULL);
+ xmlSecAssert2(encCtx->result == NULL, NULL);
+ xmlSecAssert2(node != NULL, NULL);
+
+ /* initialize context and add ID atributes to the list of known ids */
+ encCtx->operation = xmlSecTransformOperationDecrypt;
+ xmlSecAddIDs(node->doc, node, xmlSecEncIds);
+
+ ret = xmlSecEncCtxEncDataNodeRead(encCtx, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxEncDataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ /* decrypt the data */
+ if(encCtx->cipherValueNode != NULL) {
+ xmlChar* data = NULL;
+ xmlSecSize dataSize = 0;
+
+ data = xmlNodeGetContent(encCtx->cipherValueNode);
+ if(data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(encCtx->cipherValueNode)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ dataSize = xmlStrlen(data);
+
+ ret = xmlSecTransformCtxBinaryExecute(&(encCtx->transformCtx), data, dataSize);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxBinaryExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ if(data != NULL) {
+ xmlFree(data);
+ }
+ return(NULL);
+ }
+ if(data != NULL) {
+ xmlFree(data);
+ }
+ } else {
+ ret = xmlSecTransformCtxExecute(&(encCtx->transformCtx), node->doc);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxBinaryExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ }
+
+ encCtx->result = encCtx->transformCtx.result;
+ xmlSecAssert2(encCtx->result != NULL, NULL);
+
+ return(encCtx->result);
+}
+
+static int
+xmlSecEncCtxEncDataNodeRead(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2((encCtx->operation == xmlSecTransformOperationEncrypt) || (encCtx->operation == xmlSecTransformOperationDecrypt), -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ switch(encCtx->mode) {
+ case xmlEncCtxModeEncryptedData:
+ if(!xmlSecCheckNodeName(node, xmlSecNodeEncryptedData, xmlSecEncNs)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptedData));
+ return(-1);
+ }
+ break;
+ case xmlEncCtxModeEncryptedKey:
+ if(!xmlSecCheckNodeName(node, xmlSecNodeEncryptedKey, xmlSecEncNs)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptedKey));
+ return(-1);
+ }
+ break;
+ }
+
+ /* first read node data */
+ xmlSecAssert2(encCtx->id == NULL, -1);
+ xmlSecAssert2(encCtx->type == NULL, -1);
+ xmlSecAssert2(encCtx->mimeType == NULL, -1);
+ xmlSecAssert2(encCtx->encoding == NULL, -1);
+ xmlSecAssert2(encCtx->recipient == NULL, -1);
+ xmlSecAssert2(encCtx->carriedKeyName == NULL, -1);
+
+ encCtx->id = xmlGetProp(node, xmlSecAttrId);
+ encCtx->type = xmlGetProp(node, xmlSecAttrType);
+ encCtx->mimeType = xmlGetProp(node, xmlSecAttrMimeType);
+ encCtx->encoding = xmlGetProp(node, xmlSecAttrEncoding);
+ if(encCtx->mode == xmlEncCtxModeEncryptedKey) {
+ encCtx->recipient = xmlGetProp(node, xmlSecAttrRecipient);
+ /* todo: check recipient? */
+ }
+ cur = xmlSecGetNextElementNode(node->children);
+
+ /* first node is optional EncryptionMethod, we'll read it later */
+ xmlSecAssert2(encCtx->encMethodNode == NULL, -1);
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeEncryptionMethod, xmlSecEncNs))) {
+ encCtx->encMethodNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next node is optional KeyInfo, we'll process it later */
+ xmlSecAssert2(encCtx->keyInfoNode == NULL, -1);
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs))) {
+ encCtx->keyInfoNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next is required CipherData node */
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeCipherData, xmlSecEncNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCipherData));
+ return(-1);
+ }
+
+ ret = xmlSecEncCtxCipherDataNodeRead(encCtx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxCipherDataNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next is optional EncryptionProperties node (we simply ignore it) */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeEncryptionProperties, xmlSecEncNs))) {
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* there are more possible nodes for the <EncryptedKey> node */
+ if(encCtx->mode == xmlEncCtxModeEncryptedKey) {
+ /* next is optional ReferenceList node (we simply ignore it) */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeReferenceList, xmlSecEncNs))) {
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* next is optional CarriedKeyName node (we simply ignore it) */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCarriedKeyName, xmlSecEncNs))) {
+ encCtx->carriedKeyName = xmlNodeGetContent(cur);
+ if(encCtx->carriedKeyName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCipherData));
+ return(-1);
+ }
+ /* TODO: decode the name? */
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+ }
+
+ /* if there is something left than it's an error */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* now read the encryption method node */
+ xmlSecAssert2(encCtx->encMethod == NULL, -1);
+ if(encCtx->encMethodNode != NULL) {
+ encCtx->encMethod = xmlSecTransformCtxNodeRead(&(encCtx->transformCtx), encCtx->encMethodNode,
+ xmlSecTransformUsageEncryptionMethod);
+ if(encCtx->encMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(encCtx->encMethodNode)));
+ return(-1);
+ }
+ } else if(encCtx->defEncMethodId != xmlSecTransformIdUnknown) {
+ encCtx->encMethod = xmlSecTransformCtxCreateAndAppend(&(encCtx->transformCtx),
+ encCtx->defEncMethodId);
+ if(encCtx->encMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "encryption method not specified");
+ return(-1);
+ }
+ encCtx->encMethod->operation = encCtx->operation;
+
+ /* we have encryption method, find key */
+ ret = xmlSecTransformSetKeyReq(encCtx->encMethod, &(encCtx->keyInfoReadCtx.keyReq));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformSetKeyReq",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "transform=%s",
+ xmlSecErrorsSafeString(xmlSecTransformGetName(encCtx->encMethod)));
+ return(-1);
+ }
+
+ /* TODO: KeyInfo node != NULL and encKey != NULL */
+ if((encCtx->encKey == NULL) && (encCtx->keyInfoReadCtx.keysMngr != NULL)
+ && (encCtx->keyInfoReadCtx.keysMngr->getKey != NULL)) {
+ encCtx->encKey = (encCtx->keyInfoReadCtx.keysMngr->getKey)(encCtx->keyInfoNode,
+ &(encCtx->keyInfoReadCtx));
+ }
+
+ /* check that we have exactly what we want */
+ if((encCtx->encKey == NULL) ||
+ (!xmlSecKeyMatch(encCtx->encKey, NULL, &(encCtx->keyInfoReadCtx.keyReq)))) {
+
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_KEY_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* set the key to the transform */
+ ret = xmlSecTransformSetKey(encCtx->encMethod, encCtx->encKey);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformSetKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "transform=%s",
+ xmlSecErrorsSafeString(xmlSecTransformGetName(encCtx->encMethod)));
+ return(-1);
+ }
+
+ /* if we need to write result to xml node then we need base64 encode it */
+ if((encCtx->operation == xmlSecTransformOperationEncrypt) && (encCtx->cipherValueNode != NULL)) {
+ xmlSecTransformPtr base64Encode;
+
+ /* we need to add base64 encode transform */
+ base64Encode = xmlSecTransformCtxCreateAndAppend(&(encCtx->transformCtx), xmlSecTransformBase64Id);
+ if(base64Encode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCreateAndAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ base64Encode->operation = xmlSecTransformOperationEncode;
+ encCtx->resultBase64Encoded = 1;
+ }
+
+ return(0);
+}
+
+static int
+xmlSecEncCtxEncDataNodeWrite(xmlSecEncCtxPtr encCtx) {
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(encCtx->result != NULL, -1);
+ xmlSecAssert2(encCtx->encKey != NULL, -1);
+
+ /* write encrypted data to xml (if requested) */
+ if(encCtx->cipherValueNode != NULL) {
+ xmlSecAssert2(xmlSecBufferGetData(encCtx->result) != NULL, -1);
+
+ xmlNodeSetContentLen(encCtx->cipherValueNode,
+ xmlSecBufferGetData(encCtx->result),
+ xmlSecBufferGetSize(encCtx->result));
+ encCtx->resultReplaced = 1;
+ }
+
+ /* update <enc:KeyInfo/> node */
+ if(encCtx->keyInfoNode != NULL) {
+ ret = xmlSecKeyInfoNodeWrite(encCtx->keyInfoNode, encCtx->encKey, &(encCtx->keyInfoWriteCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyInfoNodeWrite",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+
+ return(0);
+}
+
+static int
+xmlSecEncCtxCipherDataNodeRead(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ cur = xmlSecGetNextElementNode(node->children);
+
+ /* we either have CipherValue or CipherReference node */
+ xmlSecAssert2(encCtx->cipherValueNode == NULL, -1);
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCipherValue, xmlSecEncNs))) {
+ /* don't need data from CipherData node when we are encrypting */
+ if(encCtx->operation == xmlSecTransformOperationDecrypt) {
+ xmlSecTransformPtr base64Decode;
+
+ /* we need to add base64 decode transform */
+ base64Decode = xmlSecTransformCtxCreateAndPrepend(&(encCtx->transformCtx), xmlSecTransformBase64Id);
+ if(base64Decode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCreateAndPrepend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ encCtx->cipherValueNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+ } else if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCipherReference, xmlSecEncNs))) {
+ /* don't need data from CipherReference node when we are encrypting */
+ if(encCtx->operation == xmlSecTransformOperationDecrypt) {
+ ret = xmlSecEncCtxCipherReferenceNodeRead(encCtx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecEncCtxCipherReferenceNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ return(-1);
+ }
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+}
+
+static int
+xmlSecEncCtxCipherReferenceNodeRead(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
+ xmlNodePtr cur;
+ xmlChar* uri;
+ int ret;
+
+ xmlSecAssert2(encCtx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first read the optional uri attr and check that we can process it */
+ uri = xmlGetProp(node, xmlSecAttrURI);
+ ret = xmlSecTransformCtxSetUri(&(encCtx->transformCtx), uri, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxSetUri",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "uri=%s",
+ xmlSecErrorsSafeString(uri));
+ xmlFree(uri);
+ return(-1);
+ }
+ xmlFree(uri);
+
+ cur = xmlSecGetNextElementNode(node->children);
+
+ /* the only one node is optional Transforms node */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeTransforms, xmlSecEncNs))) {
+ ret = xmlSecTransformCtxNodesListRead(&(encCtx->transformCtx), cur,
+ xmlSecTransformUsageDSigTransform);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxNodesListRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(encCtx->encMethodNode)));
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* if there is something left than it's an error */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ return(0);
+}
+
+/**
+ * xmlSecEncCtxDebugDump:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @output: the pointer to output FILE.
+ *
+ * Prints the debug information about @encCtx to @output.
+ */
+void
+xmlSecEncCtxDebugDump(xmlSecEncCtxPtr encCtx, FILE* output) {
+ xmlSecAssert(encCtx != NULL);
+ xmlSecAssert(output != NULL);
+
+ switch(encCtx->mode) {
+ case xmlEncCtxModeEncryptedData:
+ if(encCtx->operation == xmlSecTransformOperationEncrypt) {
+ fprintf(output, "= DATA ENCRYPTION CONTEXT\n");
+ } else {
+ fprintf(output, "= DATA DECRYPTION CONTEXT\n");
+ }
+ break;
+ case xmlEncCtxModeEncryptedKey:
+ if(encCtx->operation == xmlSecTransformOperationEncrypt) {
+ fprintf(output, "= KEY ENCRYPTION CONTEXT\n");
+ } else {
+ fprintf(output, "= KEY DECRYPTION CONTEXT\n");
+ }
+ break;
+ }
+ fprintf(output, "== Status: %s\n",
+ (encCtx->resultReplaced) ? "replaced" : "not-replaced" );
+
+ fprintf(output, "== flags: 0x%08x\n", encCtx->flags);
+ fprintf(output, "== flags2: 0x%08x\n", encCtx->flags2);
+
+ if(encCtx->id != NULL) {
+ fprintf(output, "== Id: \"%s\"\n", encCtx->id);
+ }
+ if(encCtx->type != NULL) {
+ fprintf(output, "== Type: \"%s\"\n", encCtx->type);
+ }
+ if(encCtx->mimeType != NULL) {
+ fprintf(output, "== MimeType: \"%s\"\n", encCtx->mimeType);
+ }
+ if(encCtx->encoding != NULL) {
+ fprintf(output, "== Encoding: \"%s\"\n", encCtx->encoding);
+ }
+ if(encCtx->recipient != NULL) {
+ fprintf(output, "== Recipient: \"%s\"\n", encCtx->recipient);
+ }
+ if(encCtx->carriedKeyName != NULL) {
+ fprintf(output, "== CarriedKeyName: \"%s\"\n", encCtx->carriedKeyName);
+ }
+
+ fprintf(output, "== Key Info Read Ctx:\n");
+ xmlSecKeyInfoCtxDebugDump(&(encCtx->keyInfoReadCtx), output);
+
+ fprintf(output, "== Key Info Write Ctx:\n");
+ xmlSecKeyInfoCtxDebugDump(&(encCtx->keyInfoWriteCtx), output);
+
+ fprintf(output, "== Encryption Transform Ctx:\n");
+ xmlSecTransformCtxDebugDump(&(encCtx->transformCtx), output);
+
+ if(encCtx->encMethod != NULL) {
+ fprintf(output, "== Encryption Method:\n");
+ xmlSecTransformDebugDump(encCtx->encMethod, output);
+ }
+
+ if(encCtx->encKey != NULL) {
+ fprintf(output, "== Encryption Key:\n");
+ xmlSecKeyDebugDump(encCtx->encKey, output);
+ }
+
+ if((encCtx->result != NULL) &&
+ (xmlSecBufferGetData(encCtx->result) != NULL) &&
+ (encCtx->resultBase64Encoded != 0)) {
+
+ fprintf(output, "== Result - start buffer:\n");
+ fwrite(xmlSecBufferGetData(encCtx->result),
+ xmlSecBufferGetSize(encCtx->result), 1,
+ output);
+ fprintf(output, "\n== Result - end buffer\n");
+ }
+}
+
+/**
+ * xmlSecEncCtxDebugXmlDump:
+ * @encCtx: the pointer to <enc:EncryptedData/> processing context.
+ * @output: the pointer to output FILE.
+ *
+ * Prints the debug information about @encCtx to @output in XML format.
+ */
+void
+xmlSecEncCtxDebugXmlDump(xmlSecEncCtxPtr encCtx, FILE* output) {
+ xmlSecAssert(encCtx != NULL);
+ xmlSecAssert(output != NULL);
+
+ switch(encCtx->mode) {
+ case xmlEncCtxModeEncryptedData:
+ if(encCtx->operation == xmlSecTransformOperationEncrypt) {
+ fprintf(output, "<DataEncryptionContext ");
+ } else {
+ fprintf(output, "<DataDecryptionContext ");
+ }
+ break;
+ case xmlEncCtxModeEncryptedKey:
+ if(encCtx->operation == xmlSecTransformOperationEncrypt) {
+ fprintf(output, "<KeyEncryptionContext ");
+ } else {
+ fprintf(output, "<KeyDecryptionContext ");
+ }
+ break;
+ }
+ fprintf(output, "status=\"%s\" >\n", (encCtx->resultReplaced) ? "replaced" : "not-replaced" );
+
+ fprintf(output, "<Flags>%08x</Flags>\n", encCtx->flags);
+ fprintf(output, "<Flags2>%08x</Flags2>\n", encCtx->flags2);
+
+ fprintf(output, "<Id>");
+ xmlSecPrintXmlString(output, encCtx->id);
+ fprintf(output, "</Id>");
+
+ fprintf(output, "<Type>");
+ xmlSecPrintXmlString(output, encCtx->type);
+ fprintf(output, "</Type>");
+
+ fprintf(output, "<MimeType>");
+ xmlSecPrintXmlString(output, encCtx->mimeType);
+ fprintf(output, "</MimeType>");
+
+ fprintf(output, "<Encoding>");
+ xmlSecPrintXmlString(output, encCtx->encoding);
+ fprintf(output, "</Encoding>");
+
+ fprintf(output, "<Recipient>");
+ xmlSecPrintXmlString(output, encCtx->recipient);
+ fprintf(output, "</Recipient>");
+
+ fprintf(output, "<CarriedKeyName>");
+ xmlSecPrintXmlString(output, encCtx->carriedKeyName);
+ fprintf(output, "</CarriedKeyName>");
+
+ fprintf(output, "<KeyInfoReadCtx>\n");
+ xmlSecKeyInfoCtxDebugXmlDump(&(encCtx->keyInfoReadCtx), output);
+ fprintf(output, "</KeyInfoReadCtx>\n");
+
+ fprintf(output, "<KeyInfoWriteCtx>\n");
+ xmlSecKeyInfoCtxDebugXmlDump(&(encCtx->keyInfoWriteCtx), output);
+ fprintf(output, "</KeyInfoWriteCtx>\n");
+
+ fprintf(output, "<EncryptionTransformCtx>\n");
+ xmlSecTransformCtxDebugXmlDump(&(encCtx->transformCtx), output);
+ fprintf(output, "</EncryptionTransformCtx>\n");
+
+ if(encCtx->encMethod != NULL) {
+ fprintf(output, "<EncryptionMethod>\n");
+ xmlSecTransformDebugXmlDump(encCtx->encMethod, output);
+ fprintf(output, "</EncryptionMethod>\n");
+ }
+
+ if(encCtx->encKey != NULL) {
+ fprintf(output, "<EncryptionKey>\n");
+ xmlSecKeyDebugXmlDump(encCtx->encKey, output);
+ fprintf(output, "</EncryptionKey>\n");
+ }
+
+ if((encCtx->result != NULL) &&
+ (xmlSecBufferGetData(encCtx->result) != NULL) &&
+ (encCtx->resultBase64Encoded != 0)) {
+
+ fprintf(output, "<Result>");
+ fwrite(xmlSecBufferGetData(encCtx->result),
+ xmlSecBufferGetSize(encCtx->result), 1,
+ output);
+ fprintf(output, "</Result>\n");
+ }
+
+ switch(encCtx->mode) {
+ case xmlEncCtxModeEncryptedData:
+ if(encCtx->operation == xmlSecTransformOperationEncrypt) {
+ fprintf(output, "</DataEncryptionContext>\n");
+ } else {
+ fprintf(output, "</DataDecryptionContext>\n");
+ }
+ break;
+ case xmlEncCtxModeEncryptedKey:
+ if(encCtx->operation == xmlSecTransformOperationEncrypt) {
+ fprintf(output, "</KeyEncryptionContext>\n");
+ } else {
+ fprintf(output, "</KeyDecryptionContext>\n");
+ }
+ break;
+ }
+}
+
+#endif /* XMLSEC_NO_XMLENC */
+