summaryrefslogtreecommitdiff
path: root/src/templates.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/templates.c')
-rw-r--r--src/templates.c2091
1 files changed, 2091 insertions, 0 deletions
diff --git a/src/templates.c b/src/templates.c
new file mode 100644
index 00000000..2270db67
--- /dev/null
+++ b/src/templates.c
@@ -0,0 +1,2091 @@
+/**
+ * XML Security Library (http://www.aleksey.com/xmlsec).
+ *
+ * Creating signature and encryption templates.
+ *
+ * This is free software; see Copyright file in the source
+ * distribution for preciese wording.
+ *
+ * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
+ */
+#include "globals.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxml/tree.h>
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/transforms.h>
+#include <xmlsec/strings.h>
+#include <xmlsec/base64.h>
+#include <xmlsec/templates.h>
+#include <xmlsec/errors.h>
+
+
+static xmlNodePtr xmlSecTmplAddReference (xmlNodePtr parentNode,
+ xmlSecTransformId digestMethodId,
+ const xmlChar *id,
+ const xmlChar *uri,
+ const xmlChar *type);
+static int xmlSecTmplPrepareEncData (xmlNodePtr parentNode,
+ xmlSecTransformId encMethodId);
+static int xmlSecTmplNodeWriteNsList (xmlNodePtr parentNode,
+ const xmlChar** namespaces);
+/**************************************************************************
+ *
+ * <dsig:Signature/> node
+ *
+ **************************************************************************/
+/**
+ * xmlSecTmplSignatureCreate:
+ * @doc: the pointer to signature document or NULL; in the
+ * second case, application must later call @xmlSetTreeDoc
+ * to ensure that all the children nodes have correct
+ * pointer to XML document.
+ * @c14nMethodId: the signature canonicalization method.
+ * @signMethodId: the signature method.
+ * @id: the node id (may be NULL).
+ *
+ * Creates new <dsig:Signature/> node with the mandatory <dsig:SignedInfo/>,
+ * <dsig:CanonicalizationMethod/>, <dsig:SignatureMethod/> and
+ * <dsig:SignatureValue/> children and sub-children.
+ * The application is responsible for inserting the returned node
+ * in the XML document.
+ *
+ * Returns: the pointer to newly created <dsig:Signature/> node or NULL if an
+ * error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureCreate(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
+ xmlSecTransformId signMethodId, const xmlChar *id) {
+ return xmlSecTmplSignatureCreateNsPref(doc, c14nMethodId, signMethodId, id, NULL);
+}
+
+/**
+ * xmlSecTmplSignatureCreateNsPref:
+ * @doc: the pointer to signature document or NULL; in the
+ * second case, application must later call @xmlSetTreeDoc
+ * to ensure that all the children nodes have correct
+ * pointer to XML document.
+ * @c14nMethodId: the signature canonicalization method.
+ * @signMethodId: the signature method.
+ * @id: the node id (may be NULL).
+ * @nsPrefix: the namespace prefix for the signature element (e.g. "dsig"), or NULL
+ *
+ * Creates new <dsig:Signature/> node with the mandatory
+ * <dsig:SignedInfo/>, <dsig:CanonicalizationMethod/>,
+ * <dsig:SignatureMethod/> and <dsig:SignatureValue/> children and
+ * sub-children. This method differs from xmlSecTmplSignatureCreate in
+ * that it will define the http://www.w3.org/2000/09/xmldsig#
+ * namespace with the given prefix that will be used for all of the
+ * appropriate child nodes. The application is responsible for
+ * inserting the returned node in the XML document.
+ *
+ * Returns: the pointer to newly created <dsig:Signature/> node or NULL if an
+ * error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureCreateNsPref(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
+ xmlSecTransformId signMethodId, const xmlChar *id,
+ const xmlChar* nsPrefix) {
+ xmlNodePtr signNode;
+ xmlNodePtr signedInfoNode;
+ xmlNodePtr cur;
+ xmlNsPtr ns;
+
+ xmlSecAssert2(c14nMethodId != NULL, NULL);
+ xmlSecAssert2(c14nMethodId->href != NULL, NULL);
+ xmlSecAssert2(signMethodId != NULL, NULL);
+ xmlSecAssert2(signMethodId->href != NULL, NULL);
+
+ /* create Signature node itself */
+ signNode = xmlNewDocNode(doc, NULL, xmlSecNodeSignature, NULL);
+ if(signNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewDocNode",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignature));
+ return(NULL);
+ }
+
+ ns = xmlNewNs(signNode, xmlSecDSigNs, nsPrefix);
+ if(ns == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewNs",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "ns=%s",
+ xmlSecErrorsSafeString(xmlSecDSigNs));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+ xmlSetNs(signNode, ns);
+
+ if(id != NULL) {
+ xmlSetProp(signNode, BAD_CAST "Id", id);
+ }
+
+ /* add SignedInfo node */
+ signedInfoNode = xmlSecAddChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
+ if(signedInfoNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignedInfo));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+
+ /* add SignatureValue node */
+ cur = xmlSecAddChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignatureValue));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+
+ /* add CanonicaizationMethod node to SignedInfo */
+ cur = xmlSecAddChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCanonicalizationMethod));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+ if(xmlSetProp(cur, xmlSecAttrAlgorithm, c14nMethodId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(c14nMethodId->href));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+
+ /* add SignatureMethod node to SignedInfo */
+ cur = xmlSecAddChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignatureMethod));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+ if(xmlSetProp(cur, xmlSecAttrAlgorithm, signMethodId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(signMethodId->href));
+ xmlFreeNode(signNode);
+ return(NULL);
+ }
+
+ return(signNode);
+}
+
+/**
+ * xmlSecTmplSignatureEnsureKeyInfo:
+ * @signNode: the pointer to <dsig:Signature/> node.
+ * @id: the node id (may be NULL).
+ *
+ * Adds (if necessary) <dsig:KeyInfo/> node to the <dsig:Signature/>
+ * node @signNode.
+ *
+ * Returns: the pointer to newly created <dsig:KeyInfo/> node or NULL if an
+ * error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureEnsureKeyInfo(xmlNodePtr signNode, const xmlChar *id) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(signNode != NULL, NULL);
+
+ res = xmlSecFindChild(signNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlNodePtr signValueNode;
+
+ signValueNode = xmlSecFindChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
+ if(signValueNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeSignatureValue),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecAddNextSibling(signValueNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddNextSibling",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
+ return(NULL);
+ }
+ }
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplSignatureAddReference:
+ * @signNode: the pointer to <dsig:Signature/> node.
+ * @digestMethodId: the reference digest method.
+ * @id: the node id (may be NULL).
+ * @uri: the reference node uri (may be NULL).
+ * @type: the reference node type (may be NULL).
+ *
+ * Adds <dsig:Reference/> node with given URI (@uri), Id (@id) and
+ * Type (@type) attributes and the required children <dsig:DigestMethod/> and
+ * <dsig:DigestValue/> to the <dsig:SignedInfo/> child of @signNode.
+ *
+ * Returns: the pointer to newly created <dsig:Reference/> node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureAddReference(xmlNodePtr signNode, xmlSecTransformId digestMethodId,
+ const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
+ xmlNodePtr signedInfoNode;
+
+ xmlSecAssert2(signNode != NULL, NULL);
+ xmlSecAssert2(digestMethodId != NULL, NULL);
+ xmlSecAssert2(digestMethodId->href != NULL, NULL);
+
+ signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
+ if(signedInfoNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ return(xmlSecTmplAddReference(signedInfoNode, digestMethodId, id, uri, type));
+}
+
+static xmlNodePtr
+xmlSecTmplAddReference(xmlNodePtr parentNode, xmlSecTransformId digestMethodId,
+ const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
+ xmlNodePtr res;
+ xmlNodePtr cur;
+
+ xmlSecAssert2(parentNode != NULL, NULL);
+ xmlSecAssert2(digestMethodId != NULL, NULL);
+ xmlSecAssert2(digestMethodId->href != NULL, NULL);
+
+ /* add Reference node */
+ res = xmlSecAddChild(parentNode, xmlSecNodeReference, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeReference));
+ return(NULL);
+ }
+
+ /* set Reference node attributes */
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ if(type != NULL) {
+ xmlSetProp(res, xmlSecAttrType, type);
+ }
+ if(uri != NULL) {
+ xmlSetProp(res, xmlSecAttrURI, uri);
+ }
+
+ /* add DigestMethod node and set algorithm */
+ cur = xmlSecAddChild(res, xmlSecNodeDigestMethod, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDigestMethod));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+ if(xmlSetProp(cur, xmlSecAttrAlgorithm, digestMethodId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(digestMethodId->href));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+
+ /* add DigestValue node */
+ cur = xmlSecAddChild(res, xmlSecNodeDigestValue, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDigestValue));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplSignatureAddObject:
+ * @signNode: the pointer to <dsig:Signature/> node.
+ * @id: the node id (may be NULL).
+ * @mimeType: the object mime type (may be NULL).
+ * @encoding: the object encoding (may be NULL).
+ *
+ * Adds <dsig:Object/> node to the <dsig:Signature/> node @signNode.
+ *
+ * Returns: the pointer to newly created <dsig:Object/> node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureAddObject(xmlNodePtr signNode, const xmlChar *id,
+ const xmlChar *mimeType, const xmlChar *encoding) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(signNode != NULL, NULL);
+
+ res = xmlSecAddChild(signNode, xmlSecNodeObject, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeObject));
+ return(NULL);
+ }
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ if(mimeType != NULL) {
+ xmlSetProp(res, xmlSecAttrMimeType, mimeType);
+ }
+ if(encoding != NULL) {
+ xmlSetProp(res, xmlSecAttrEncoding, encoding);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplSignatureGetSignMethodNode:
+ * @signNode: the pointer to <dsig:Signature /> node.
+ *
+ * Gets pointer to <dsig:SignatureMethod/> child of <dsig:KeyInfo/> node.
+ *
+ * Returns: pointer to <dsig:SignatureMethod /> node or NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureGetSignMethodNode(xmlNodePtr signNode) {
+ xmlNodePtr signedInfoNode;
+
+ xmlSecAssert2(signNode != NULL, NULL);
+
+ signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
+ if(signedInfoNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ return(xmlSecFindChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs));
+}
+
+/**
+ * xmlSecTmplSignatureGetC14NMethodNode:
+ * @signNode: the pointer to <dsig:Signature /> node.
+ *
+ * Gets pointer to <dsig:CanonicalizationMethod/> child of <dsig:KeyInfo/> node.
+ *
+ * Returns: pointer to <dsig:CanonicalizationMethod /> node or NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplSignatureGetC14NMethodNode(xmlNodePtr signNode) {
+ xmlNodePtr signedInfoNode;
+
+ xmlSecAssert2(signNode != NULL, NULL);
+
+ signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
+ if(signedInfoNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+ return(xmlSecFindChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs));
+}
+
+/**
+ * xmlSecTmplReferenceAddTransform:
+ * @referenceNode: the pointer to <dsig:Reference/> node.
+ * @transformId: the transform method id.
+ *
+ * Adds <dsig:Transform/> node to the <dsig:Reference/> node @referenceNode.
+ *
+ * Returns: the pointer to newly created <dsig:Transform/> node or NULL if an
+ * error occurs.
+ */
+xmlNodePtr
+xmlSecTmplReferenceAddTransform(xmlNodePtr referenceNode, xmlSecTransformId transformId) {
+ xmlNodePtr transformsNode;
+ xmlNodePtr res;
+
+ xmlSecAssert2(referenceNode != NULL, NULL);
+ xmlSecAssert2(transformId != NULL, NULL);
+ xmlSecAssert2(transformId->href != NULL, NULL);
+
+ /* do we need to create Transforms node first */
+ transformsNode = xmlSecFindChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
+ if(transformsNode == NULL) {
+ xmlNodePtr tmp;
+
+ tmp = xmlSecGetNextElementNode(referenceNode->children);
+ if(tmp == NULL) {
+ transformsNode = xmlSecAddChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
+ } else {
+ transformsNode = xmlSecAddPrevSibling(tmp, xmlSecNodeTransforms, xmlSecDSigNs);
+ }
+ if(transformsNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild or xmlSecAddPrevSibling",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeTransforms));
+ return(NULL);
+ }
+ }
+
+ res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeTransform));
+ return(NULL);
+ }
+
+ if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(transformId->href));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplObjectAddSignProperties:
+ * @objectNode: the pointer to <dsig:Object/> node.
+ * @id: the node id (may be NULL).
+ * @target: the Target (may be NULL).
+ *
+ * Adds <dsig:SignatureProperties/> node to the <dsig:Object/> node @objectNode.
+ *
+ * Returns: the pointer to newly created <dsig:SignatureProperties/> node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplObjectAddSignProperties(xmlNodePtr objectNode, const xmlChar *id, const xmlChar *target) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(objectNode != NULL, NULL);
+
+ res = xmlSecAddChild(objectNode, xmlSecNodeSignatureProperties, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignatureProperties));
+ return(NULL);
+ }
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ if(target != NULL) {
+ xmlSetProp(res, xmlSecAttrTarget, target);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplObjectAddManifest:
+ * @objectNode: the pointer to <dsig:Object/> node.
+ * @id: the node id (may be NULL).
+ *
+ * Adds <dsig:Manifest/> node to the <dsig:Object/> node @objectNode.
+ *
+ * Returns: the pointer to newly created <dsig:Manifest/> node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplObjectAddManifest(xmlNodePtr objectNode, const xmlChar *id) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(objectNode != NULL, NULL);
+
+ res = xmlSecAddChild(objectNode, xmlSecNodeManifest, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeManifest));
+ return(NULL);
+ }
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplManifestAddReference:
+ * @manifestNode: the pointer to <dsig:Manifest/> node.
+ * @digestMethodId: the reference digest method.
+ * @id: the node id (may be NULL).
+ * @uri: the reference node uri (may be NULL).
+ * @type: the reference node type (may be NULL).
+ *
+ * Adds <dsig:Reference/> node with specified URI (@uri), Id (@id) and
+ * Type (@type) attributes and the required children <dsig:DigestMethod/> and
+ * <dsig:DigestValue/> to the <dsig:Manifest/> node @manifestNode.
+ *
+ * Returns: the pointer to newly created <dsig:Reference/> node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplManifestAddReference(xmlNodePtr manifestNode, xmlSecTransformId digestMethodId,
+ const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
+ return(xmlSecTmplAddReference(manifestNode, digestMethodId, id, uri, type));
+}
+
+/**************************************************************************
+ *
+ * <enc:EncryptedData/> node
+ *
+ **************************************************************************/
+/**
+ * xmlSecTmplEncDataCreate:
+ * @doc: the pointer to signature document or NULL; in the later
+ * case, application must later call @xmlSetTreeDoc to ensure
+ * that all the children nodes have correct pointer to XML document.
+ * @encMethodId: the encryption method (may be NULL).
+ * @id: the Id attribute (optional).
+ * @type: the Type attribute (optional)
+ * @mimeType: the MimeType attribute (optional)
+ * @encoding: the Encoding attribute (optional)
+ *
+ * Creates new <enc:EncryptedData /> node for encryption template.
+ *
+ * Returns: the pointer newly created <enc:EncryptedData/> node or NULL
+ * if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataCreate(xmlDocPtr doc, xmlSecTransformId encMethodId,
+ const xmlChar *id, const xmlChar *type,
+ const xmlChar *mimeType, const xmlChar *encoding) {
+ xmlNodePtr encNode;
+ xmlNsPtr ns;
+
+ encNode = xmlNewDocNode(doc, NULL, xmlSecNodeEncryptedData, NULL);
+ if(encNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewDocNode",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptedData));
+ return(NULL);
+ }
+
+ ns = xmlNewNs(encNode, xmlSecEncNs, NULL);
+ if(ns == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewNs",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "ns=%s",
+ xmlSecErrorsSafeString(xmlSecEncNs));
+ return(NULL);
+ }
+ xmlSetNs(encNode, ns);
+
+ if(id != NULL) {
+ xmlSetProp(encNode, xmlSecAttrId, id);
+ }
+ if(type != NULL) {
+ xmlSetProp(encNode, xmlSecAttrType, type);
+ }
+ if(mimeType != NULL) {
+ xmlSetProp(encNode, xmlSecAttrMimeType, mimeType);
+ }
+ if(encoding != NULL) {
+ xmlSetProp(encNode, xmlSecAttrEncoding, encoding);
+ }
+
+ if(xmlSecTmplPrepareEncData(encNode, encMethodId) < 0) {
+ xmlFreeNode(encNode);
+ return(NULL);
+ }
+ return(encNode);
+}
+
+static int
+xmlSecTmplPrepareEncData(xmlNodePtr parentNode, xmlSecTransformId encMethodId) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(parentNode != NULL, -1);
+ xmlSecAssert2((encMethodId == NULL) || (encMethodId->href != NULL), -1);
+
+ /* add EncryptionMethod node if requested */
+ if(encMethodId != NULL) {
+ cur = xmlSecAddChild(parentNode, xmlSecNodeEncryptionMethod, xmlSecEncNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptionMethod));
+ return(-1);
+ }
+ if(xmlSetProp(cur, xmlSecAttrAlgorithm, encMethodId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(encMethodId->href));
+ return(-1);
+ }
+ }
+
+ /* and CipherData node */
+ cur = xmlSecAddChild(parentNode, xmlSecNodeCipherData, xmlSecEncNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCipherData));
+ return(-1);
+ }
+
+ return(0);
+}
+
+
+/**
+ * xmlSecTmplEncDataEnsureKeyInfo:
+ * @encNode: the pointer to <enc:EncryptedData/> node.
+ * @id: the Id attrbibute (optional).
+ *
+ * Adds <dsig:KeyInfo/> to the <enc:EncryptedData/> node @encNode.
+ *
+ * Returns: the pointer to newly created <dsig:KeyInfo/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataEnsureKeyInfo(xmlNodePtr encNode, const xmlChar* id) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ res = xmlSecFindChild(encNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlNodePtr cipherDataNode;
+
+ cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
+ if(cipherDataNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeCipherData),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecAddPrevSibling(cipherDataNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddPrevSibling",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
+ return(NULL);
+ }
+ }
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplEncDataEnsureEncProperties:
+ * @encNode: the pointer to <enc:EncryptedData/> node.
+ * @id: the Id attribute (optional).
+ *
+ * Adds <enc:EncryptionProperties/> node to the <enc:EncryptedData/>
+ * node @encNode.
+ *
+ * Returns: the pointer to newly created <enc:EncryptionProperties/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataEnsureEncProperties(xmlNodePtr encNode, const xmlChar *id) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ res = xmlSecFindChild(encNode, xmlSecNodeEncryptionProperties, xmlSecEncNs);
+ if(res == NULL) {
+ res = xmlSecAddChild(encNode, xmlSecNodeEncryptionProperties, xmlSecEncNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptionProperties));
+ return(NULL);
+ }
+ }
+
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplEncDataAddEncProperty:
+ * @encNode: the pointer to <enc:EncryptedData/> node.
+ * @id: the Id attribute (optional).
+ * @target: the Target attribute (optional).
+ *
+ * Adds <enc:EncryptionProperty/> node (and the parent
+ * <enc:EncryptionProperties/> node if required) to the
+ * <enc:EncryptedData/> node @encNode.
+ *
+ * Returns: the pointer to newly created <enc:EncryptionProperty/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataAddEncProperty(xmlNodePtr encNode, const xmlChar *id, const xmlChar *target) {
+ xmlNodePtr encProps;
+ xmlNodePtr res;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ encProps = xmlSecTmplEncDataEnsureEncProperties(encNode, NULL);
+ if(encProps == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTmplEncDataEnsureEncProperties",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecAddChild(encProps, xmlSecNodeEncryptionProperty, xmlSecEncNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptionProperty));
+ return(NULL);
+ }
+ if(id != NULL) {
+ xmlSetProp(res, xmlSecAttrId, id);
+ }
+ if(target != NULL) {
+ xmlSetProp(res, xmlSecAttrTarget, target);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplEncDataEnsureCipherValue:
+ * @encNode: the pointer to <enc:EncryptedData/> node.
+ *
+ * Adds <enc:CipherValue/> to the <enc:EncryptedData/> node @encNode.
+ *
+ * Returns: the pointer to newly created <enc:CipherValue/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataEnsureCipherValue(xmlNodePtr encNode) {
+ xmlNodePtr cipherDataNode;
+ xmlNodePtr res, tmp;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
+ if(cipherDataNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeCipherData),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ /* check that we don;t have CipherReference node */
+ tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
+ if(tmp != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeCipherReference),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
+ if(res == NULL) {
+ res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCipherValue));
+ return(NULL);
+ }
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplEncDataEnsureCipherReference:
+ * @encNode: the pointer to <enc:EncryptedData/> node.
+ * @uri: the URI attribute (may be NULL).
+ *
+ * Adds <enc:CipherReference/> node with specified URI attribute @uri
+ * to the <enc:EncryptedData/> node @encNode.
+ *
+ * Returns: the pointer to newly created <enc:CipherReference/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataEnsureCipherReference(xmlNodePtr encNode, const xmlChar *uri) {
+ xmlNodePtr cipherDataNode;
+ xmlNodePtr res, tmp;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
+ if(cipherDataNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeCipherData),
+ XMLSEC_ERRORS_R_NODE_NOT_FOUND,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ /* check that we don;t have CipherValue node */
+ tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
+ if(tmp != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeCipherValue),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
+ if(res == NULL) {
+ res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCipherReference));
+ return(NULL);
+ }
+ }
+
+ if(uri != NULL) {
+ xmlSetProp(res, xmlSecAttrURI, uri);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplEncDataGetEncMethodNode:
+ * @encNode: the pointer to <enc:EcnryptedData /> node.
+ *
+ * Gets pointer to <enc:EncrytpionMethod/> node.
+ *
+ * Returns: pointer to <enc:EncryptionMethod /> node or NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplEncDataGetEncMethodNode(xmlNodePtr encNode) {
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ return(xmlSecFindChild(encNode, xmlSecNodeEncryptionMethod, xmlSecEncNs));
+}
+
+/**
+ * xmlSecTmplCipherReferenceAddTransform:
+ * @cipherReferenceNode: the pointer to <enc:CipherReference/> node.
+ * @transformId: the transform id.
+ *
+ * Adds <dsig:Transform/> node (and the parent <dsig:Transforms/> node)
+ * with specified transform methods @transform to the <enc:CipherReference/>
+ * child node of the <enc:EncryptedData/> node @encNode.
+ *
+ * Returns: the pointer to newly created <dsig:Transform/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplCipherReferenceAddTransform(xmlNodePtr cipherReferenceNode,
+ xmlSecTransformId transformId) {
+ xmlNodePtr transformsNode;
+ xmlNodePtr res;
+
+ xmlSecAssert2(cipherReferenceNode != NULL, NULL);
+ xmlSecAssert2(transformId != NULL, NULL);
+ xmlSecAssert2(transformId->href != NULL, NULL);
+
+ transformsNode = xmlSecFindChild(cipherReferenceNode, xmlSecNodeTransforms, xmlSecEncNs);
+ if(transformsNode == NULL) {
+ transformsNode = xmlSecAddChild(cipherReferenceNode, xmlSecNodeTransforms, xmlSecEncNs);
+ if(transformsNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeTransforms));
+ return(NULL);
+ }
+ }
+
+ res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeTransform));
+ return(NULL);
+ }
+
+ if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(transformId->href));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+
+ return(res);
+}
+
+
+/***********************************************************************
+ *
+ * <enc:EncryptedKey> node
+ *
+ **********************************************************************/
+
+/**
+ * xmlSecTmplReferenceListAddDataReference:
+ * @encNode: the pointer to <enc:EncryptedKey/> node.
+ * @uri: uri to reference (optional)
+ *
+ * Adds <enc:DataReference/> and the parent <enc:ReferenceList/> node (if needed).
+ *
+ * Returns: the pointer to newly created <enc:DataReference/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplReferenceListAddDataReference(xmlNodePtr encNode, const xmlChar *uri) {
+ xmlNodePtr refListNode, res;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ refListNode = xmlSecFindChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
+ if(refListNode == NULL) {
+ refListNode = xmlSecAddChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
+ if(refListNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeReferenceList));
+ return(NULL);
+ }
+ }
+
+ res = xmlSecAddChild(refListNode, xmlSecNodeDataReference, xmlSecEncNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDataReference));
+ return(NULL);
+ }
+
+ if(uri != NULL) {
+ if(xmlSetProp(res, xmlSecAttrURI, uri) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrURI),
+ xmlSecErrorsSafeString(uri));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplReferenceListAddKeyReference:
+ * @encNode: the pointer to <enc:EncryptedKey/> node.
+ * @uri: uri to reference (optional)
+ *
+ * Adds <enc:KeyReference/> and the parent <enc:ReferenceList/> node (if needed).
+ *
+ * Returns: the pointer to newly created <enc:KeyReference/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplReferenceListAddKeyReference(xmlNodePtr encNode, const xmlChar *uri) {
+ xmlNodePtr refListNode, res;
+
+ xmlSecAssert2(encNode != NULL, NULL);
+
+ refListNode = xmlSecFindChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
+ if(refListNode == NULL) {
+ refListNode = xmlSecAddChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
+ if(refListNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeReferenceList));
+ return(NULL);
+ }
+ }
+
+ res = xmlSecAddChild(refListNode, xmlSecNodeKeyReference, xmlSecEncNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyReference));
+ return(NULL);
+ }
+
+ if(uri != NULL) {
+ if(xmlSetProp(res, xmlSecAttrURI, uri) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrURI),
+ xmlSecErrorsSafeString(uri));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+ }
+
+ return(res);
+}
+
+
+/**************************************************************************
+ *
+ * <dsig:KeyInfo/> node
+ *
+ **************************************************************************/
+
+/**
+ * xmlSecTmplKeyInfoAddKeyName:
+ * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
+ * @name: the key name (optional).
+ *
+ * Adds <dsig:KeyName/> node to the <dsig:KeyInfo/> node @keyInfoNode.
+ *
+ * Returns: the pointer to the newly created <dsig:KeyName/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplKeyInfoAddKeyName(xmlNodePtr keyInfoNode, const xmlChar* name) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(keyInfoNode != NULL, NULL);
+
+ res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyName, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyName));
+ return(NULL);
+ }
+ if(name != NULL) {
+ xmlSecNodeEncodeAndSetContent(res, name);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplKeyInfoAddKeyValue:
+ * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
+ *
+ * Adds <dsig:KeyValue/> node to the <dsig:KeyInfo/> node @keyInfoNode.
+ *
+ * Returns: the pointer to the newly created <dsig:KeyValue/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplKeyInfoAddKeyValue(xmlNodePtr keyInfoNode) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(keyInfoNode != NULL, NULL);
+
+ res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyValue, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeKeyValue));
+ return(NULL);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplKeyInfoAddX509Data:
+ * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
+ *
+ * Adds <dsig:X509Data/> node to the <dsig:KeyInfo/> node @keyInfoNode.
+ *
+ * Returns: the pointer to the newly created <dsig:X509Data/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplKeyInfoAddX509Data(xmlNodePtr keyInfoNode) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(keyInfoNode != NULL, NULL);
+
+ res = xmlSecAddChild(keyInfoNode, xmlSecNodeX509Data, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509Data));
+ return(NULL);
+ }
+
+ return(res);
+}
+
+/**
+ * xmlSecTmplKeyInfoAddRetrievalMethod:
+ * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
+ * @uri: the URI attribute (optional).
+ * @type: the Type attribute(optional).
+ *
+ * Adds <dsig:RetrievalMethod/> node to the <dsig:KeyInfo/> node @keyInfoNode.
+ *
+ * Returns: the pointer to the newly created <dsig:RetrievalMethod/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplKeyInfoAddRetrievalMethod(xmlNodePtr keyInfoNode, const xmlChar *uri,
+ const xmlChar *type) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(keyInfoNode != NULL, NULL);
+
+ res = xmlSecAddChild(keyInfoNode, xmlSecNodeRetrievalMethod, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRetrievalMethod));
+ return(NULL);
+ }
+
+ if(uri != NULL) {
+ xmlSetProp(res, xmlSecAttrURI, uri);
+ }
+ if(type != NULL) {
+ xmlSetProp(res, xmlSecAttrType, type);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplRetrievalMethodAddTransform:
+ * @retrMethodNode: the pointer to <dsig:RetrievalMethod/> node.
+ * @transformId: the transform id.
+ *
+ * Adds <dsig:Transform/> node (and the parent <dsig:Transforms/> node
+ * if required) to the <dsig:RetrievalMethod/> node @retrMethod.
+ *
+ * Returns: the pointer to the newly created <dsig:Transforms/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplRetrievalMethodAddTransform(xmlNodePtr retrMethodNode, xmlSecTransformId transformId) {
+ xmlNodePtr transformsNode;
+ xmlNodePtr res;
+
+ xmlSecAssert2(retrMethodNode != NULL, NULL);
+ xmlSecAssert2(transformId != NULL, NULL);
+ xmlSecAssert2(transformId->href != NULL, NULL);
+
+ transformsNode = xmlSecFindChild(retrMethodNode, xmlSecNodeTransforms, xmlSecDSigNs);
+ if(transformsNode == NULL) {
+ transformsNode = xmlSecAddChild(retrMethodNode, xmlSecNodeTransforms, xmlSecDSigNs);
+ if(transformsNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeTransforms));
+ return(NULL);
+ }
+ }
+
+ res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeTransform));
+ return(NULL);
+ }
+
+ if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSetProp",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "name=%s,value=%s",
+ xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
+ xmlSecErrorsSafeString(transformId->href));
+ xmlUnlinkNode(res);
+ xmlFreeNode(res);
+ return(NULL);
+ }
+
+ return(res);
+}
+
+
+/**
+ * xmlSecTmplKeyInfoAddEncryptedKey:
+ * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
+ * @encMethodId: the encryption method (optional).
+ * @id: the Id attribute (optional).
+ * @type: the Type attribute (optional).
+ * @recipient: the Recipient attribute (optional).
+ *
+ * Adds <enc:EncryptedKey/> node with given attributes to
+ * the <dsig:KeyInfo/> node @keyInfoNode.
+ *
+ * Returns: the pointer to the newly created <enc:EncryptedKey/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplKeyInfoAddEncryptedKey(xmlNodePtr keyInfoNode, xmlSecTransformId encMethodId,
+ const xmlChar* id, const xmlChar* type, const xmlChar* recipient) {
+ xmlNodePtr encKeyNode;
+
+ xmlSecAssert2(keyInfoNode != NULL, NULL);
+
+ /* we allow multiple encrypted key elements */
+ encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, xmlSecEncNs);
+ if(encKeyNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeEncryptedKey));
+ return(NULL);
+ }
+
+ if(id != NULL) {
+ xmlSetProp(encKeyNode, xmlSecAttrId, id);
+ }
+ if(type != NULL) {
+ xmlSetProp(encKeyNode, xmlSecAttrType, type);
+ }
+ if(recipient != NULL) {
+ xmlSetProp(encKeyNode, xmlSecAttrRecipient, recipient);
+ }
+
+ if(xmlSecTmplPrepareEncData(encKeyNode, encMethodId) < 0) {
+ xmlUnlinkNode(encKeyNode);
+ xmlFreeNode(encKeyNode);
+ return(NULL);
+ }
+ return(encKeyNode);
+}
+
+/***********************************************************************
+ *
+ * <dsig:X509Data> node
+ *
+ **********************************************************************/
+/**
+ * xmlSecTmplX509DataAddIssuerSerial:
+ * @x509DataNode: the pointer to <dsig:X509Data/> node.
+ *
+ * Adds <dsig:X509IssuerSerial/> node to the given <dsig:X509Data/> node.
+ *
+ * Returns: the pointer to the newly created <dsig:X509IssuerSerial/> node or
+ * NULL if an error occurs.
+ */
+
+xmlNodePtr
+xmlSecTmplX509DataAddIssuerSerial(xmlNodePtr x509DataNode) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(x509DataNode != NULL, NULL);
+
+ cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
+ return(NULL);
+ }
+
+ return (cur);
+}
+
+/**
+ * xmlSecTmplX509IssuerSerialAddIssuerName:
+ * @x509IssuerSerialNode: the pointer to <dsig:X509IssuerSerial/> node.
+ * @issuerName: the issuer name (optional).
+ *
+ * Adds <dsig:X509IssuerName/> node to the <dsig:X509IssuerSerial/> node @x509IssuerSerialNode.
+ *
+ * Returns: the pointer to the newly created <dsig:X509IssuerName/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplX509IssuerSerialAddIssuerName(xmlNodePtr x509IssuerSerialNode, const xmlChar* issuerName) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(x509IssuerSerialNode != NULL, NULL);
+
+ if(xmlSecFindChild(x509IssuerSerialNode, xmlSecNodeX509IssuerName,
+ xmlSecDSigNs) != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerName),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecAddChild(x509IssuerSerialNode, xmlSecNodeX509IssuerName, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509IssuerName));
+ return(NULL);
+ }
+
+ if (issuerName != NULL) {
+ xmlSecNodeEncodeAndSetContent(res, issuerName);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplX509IssuerSerialAddSerialNumber:
+ * @x509IssuerSerialNode: the pointer to <dsig:X509IssuerSerial/> node.
+ * @serial: the serial number (optional).
+ *
+ * Adds <dsig:X509SerialNumber/> node to the <dsig:X509IssuerSerial/> node @x509IssuerSerialNode.
+ *
+ * Returns: the pointer to the newly created <dsig:X509SerialNumber/> node or
+ * NULL if an error occurs.
+ */
+xmlNodePtr
+xmlSecTmplX509IssuerSerialAddSerialNumber(xmlNodePtr x509IssuerSerialNode, const xmlChar* serial) {
+ xmlNodePtr res;
+
+ xmlSecAssert2(x509IssuerSerialNode != NULL, NULL);
+
+ if(xmlSecFindChild(x509IssuerSerialNode, xmlSecNodeX509SerialNumber,
+ xmlSecDSigNs) != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ res = xmlSecAddChild(x509IssuerSerialNode, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SerialNumber));
+ return(NULL);
+ }
+
+ if (serial != NULL) {
+ xmlSecNodeEncodeAndSetContent(res, serial);
+ }
+ return(res);
+}
+
+/**
+ * xmlSecTmplX509DataAddSubjectName:
+ * @x509DataNode: the pointer to <dsig:X509Data/> node.
+ *
+ * Adds <dsig:X509SubjectName/> node to the given <dsig:X509Data/> node.
+ *
+ * Returns: the pointer to the newly created <dsig:X509SubjectName/> node or
+ * NULL if an error occurs.
+ */
+
+xmlNodePtr
+xmlSecTmplX509DataAddSubjectName(xmlNodePtr x509DataNode) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(x509DataNode != NULL, NULL);
+
+ cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509SubjectName, xmlSecDSigNs);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509SubjectName),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509SubjectName, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
+ return(NULL);
+ }
+
+ return (cur);
+}
+
+/**
+ * xmlSecTmplX509DataAddSKI:
+ * @x509DataNode: the pointer to <dsig:X509Data/> node.
+ *
+ * Adds <dsig:X509SKI/> node to the given <dsig:X509Data/> node.
+ *
+ * Returns: the pointer to the newly created <dsig:X509SKI/> node or
+ * NULL if an error occurs.
+ */
+
+xmlNodePtr
+xmlSecTmplX509DataAddSKI(xmlNodePtr x509DataNode) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(x509DataNode != NULL, NULL);
+
+ cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509SKI, xmlSecDSigNs);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509SKI),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509SKI, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509SKI));
+ return(NULL);
+ }
+
+ return (cur);
+}
+
+
+/**
+ * xmlSecTmplX509DataAddCertificate:
+ * @x509DataNode: the pointer to <dsig:X509Data/> node.
+ *
+ * Adds <dsig:X509Certificate/> node to the given <dsig:X509Data/> node.
+ *
+ * Returns: the pointer to the newly created <dsig:X509Certificate/> node or
+ * NULL if an error occurs.
+ */
+
+xmlNodePtr
+xmlSecTmplX509DataAddCertificate(xmlNodePtr x509DataNode) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(x509DataNode != NULL, NULL);
+
+ cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509Certificate),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
+ return(NULL);
+ }
+
+ return (cur);
+}
+
+/**
+ * xmlSecTmplX509DataAddCRL:
+ * @x509DataNode: the pointer to <dsig:X509Data/> node.
+ *
+ * Adds <dsig:X509CRL/> node to the given <dsig:X509Data/> node.
+ *
+ * Returns: the pointer to the newly created <dsig:X509CRL/> node or
+ * NULL if an error occurs.
+ */
+
+xmlNodePtr
+xmlSecTmplX509DataAddCRL(xmlNodePtr x509DataNode) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(x509DataNode != NULL, NULL);
+
+ cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509CRL, xmlSecDSigNs);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeX509CRL),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509CRL, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeX509CRL));
+ return(NULL);
+ }
+
+ return (cur);
+}
+
+/*************************************************************************
+ *
+ * <dsig:Transform/> node
+ *
+ ************************************************************************/
+
+/**
+ * xmlSecTmplTransformAddHmacOutputLength:
+ * @transformNode: the pointer to <dsig:Transform/> node
+ * @bitsLen: the required length in bits
+ *
+ * Creates <dsig:HMACOutputLength/> child for the HMAC transform
+ * node @node.
+ *
+ * Returns: 0 on success and a negatie value otherwise.
+ */
+int
+xmlSecTmplTransformAddHmacOutputLength(xmlNodePtr transformNode, xmlSecSize bitsLen) {
+ xmlNodePtr cur;
+ char buf[32];
+
+ xmlSecAssert2(transformNode != NULL, -1);
+ xmlSecAssert2(bitsLen > 0, -1);
+
+ cur = xmlSecFindChild(transformNode, xmlSecNodeHMACOutputLength, xmlSecDSigNs);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeHMACOutputLength),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cur = xmlSecAddChild(transformNode, xmlSecNodeHMACOutputLength, xmlSecDSigNs);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeHMACOutputLength));
+ return(-1);
+ }
+
+ sprintf(buf, "%u", bitsLen);
+ xmlNodeSetContent(cur, BAD_CAST buf);
+ return(0);
+}
+
+/**
+ * xmlSecTmplTransformAddRsaOaepParam:
+ * @transformNode: the pointer to <dsig:Transform/> node.
+ * @buf: the OAEP param buffer.
+ * @size: the OAEP param buffer size.
+ *
+ * Creates <enc:OAEPParam/> child node in the @node.
+ *
+ * Returns: 0 on success or a negative value if an error occurs.
+ */
+int
+xmlSecTmplTransformAddRsaOaepParam(xmlNodePtr transformNode,
+ const xmlSecByte *buf, xmlSecSize size) {
+ xmlNodePtr oaepParamNode;
+ xmlChar *base64;
+
+ xmlSecAssert2(transformNode != NULL, -1);
+ xmlSecAssert2(buf != NULL, -1);
+ xmlSecAssert2(size > 0, -1);
+
+ oaepParamNode = xmlSecFindChild(transformNode, xmlSecNodeRsaOAEPparams, xmlSecEncNs);
+ if(oaepParamNode != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeRsaOAEPparams),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ oaepParamNode = xmlSecAddChild(transformNode, xmlSecNodeRsaOAEPparams, xmlSecEncNs);
+ if(oaepParamNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeRsaOAEPparams));
+ return(-1);
+ }
+
+ base64 = xmlSecBase64Encode(buf, size, 0);
+ if(base64 == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecBase64Encode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "size=%d", size);
+ return(-1);
+ }
+
+ xmlNodeSetContent(oaepParamNode, base64);
+ xmlFree(base64);
+ return(0);
+}
+
+/**
+ * xmlSecTmplTransformAddXsltStylesheet:
+ * @transformNode: the pointer to <dsig:Transform/> node.
+ * @xslt: the XSLT transform exspression.
+ *
+ * Writes the XSLT transform expression to the @node.
+ *
+ * Returns: 0 on success or a negative value otherwise.
+ */
+int
+xmlSecTmplTransformAddXsltStylesheet(xmlNodePtr transformNode, const xmlChar *xslt) {
+ xmlDocPtr xsltDoc;
+ int ret;
+
+ xmlSecAssert2(transformNode != NULL, -1);
+ xmlSecAssert2(xslt != NULL, -1);
+
+ xsltDoc = xmlParseMemory((const char*)xslt, xmlStrlen(xslt));
+ if(xsltDoc == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlParseMemory",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecReplaceContent(transformNode, xmlDocGetRootElement(xsltDoc));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecReplaceContent",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFreeDoc(xsltDoc);
+ return(-1);
+ }
+
+ xmlFreeDoc(xsltDoc);
+ return(0);
+}
+
+/**
+ * xmlSecTmplTransformAddC14NInclNamespaces:
+ * @transformNode: the pointer to <dsig:Transform/> node.
+ * @prefixList: the white space delimited list of namespace prefixes,
+ * where "#default" indicates the default namespace
+ * (optional).
+ *
+ * Adds "inclusive" namespaces to the ExcC14N transform node @node.
+ *
+ * Returns: 0 if success or a negative value otherwise.
+ */
+int
+xmlSecTmplTransformAddC14NInclNamespaces(xmlNodePtr transformNode,
+ const xmlChar *prefixList) {
+ xmlNodePtr cur;
+
+ xmlSecAssert2(transformNode != NULL, -1);
+ xmlSecAssert2(prefixList != NULL, -1);
+
+ cur = xmlSecFindChild(transformNode, xmlSecNodeInclusiveNamespaces, xmlSecNsExcC14N);
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeInclusiveNamespaces),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cur = xmlSecAddChild(transformNode, xmlSecNodeInclusiveNamespaces, xmlSecNsExcC14N);
+ if(cur == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(transformNode)),
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeInclusiveNamespaces));
+ return(-1);
+ }
+
+ xmlSetProp(cur, xmlSecAttrPrefixList, prefixList);
+ return(0);
+}
+
+/**
+ * xmlSecTmplTransformAddXPath:
+ * @transformNode: the pointer to the <dsig:Transform/> node.
+ * @expression: the XPath expression.
+ * @nsList: the NULL terminated list of namespace prefix/href pairs
+ * (optional).
+ *
+ * Writes XPath transform infromation to the <dsig:Transform/> node
+ * @node.
+ *
+ * Returns: 0 for success or a negative value otherwise.
+ */
+int
+xmlSecTmplTransformAddXPath(xmlNodePtr transformNode, const xmlChar *expression,
+ const xmlChar **nsList) {
+ xmlNodePtr xpathNode;
+
+ xmlSecAssert2(transformNode != NULL, -1);
+ xmlSecAssert2(expression != NULL, -1);
+
+ xpathNode = xmlSecFindChild(transformNode, xmlSecNodeXPath, xmlSecDSigNs);
+ if(xpathNode != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeXPath),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ xpathNode = xmlSecAddChild(transformNode, xmlSecNodeXPath, xmlSecDSigNs);
+ if(xpathNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeXPath));
+ return(-1);
+ }
+
+ xmlSecNodeEncodeAndSetContent(xpathNode, expression);
+ return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpathNode, nsList) : 0);
+}
+
+/**
+ * xmlSecTmplTransformAddXPath2:
+ * @transformNode: the pointer to the <dsig:Transform/> node.
+ * @type: the XPath2 transform type ("union", "intersect" or "subtract").
+ * @expression: the XPath expression.
+ * @nsList: the NULL terminated list of namespace prefix/href pairs.
+ * (optional).
+ *
+ * Writes XPath2 transform infromation to the <dsig:Transform/> node
+ * @node.
+ *
+ * Returns: 0 for success or a negative value otherwise.
+ */
+int
+xmlSecTmplTransformAddXPath2(xmlNodePtr transformNode, const xmlChar* type,
+ const xmlChar *expression, const xmlChar **nsList) {
+ xmlNodePtr xpathNode;
+
+ xmlSecAssert2(transformNode != NULL, -1);
+ xmlSecAssert2(type != NULL, -1);
+ xmlSecAssert2(expression != NULL, -1);
+
+ xpathNode = xmlSecAddChild(transformNode, xmlSecNodeXPath, xmlSecXPath2Ns);
+ if(xpathNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeXPath));
+ return(-1);
+ }
+ xmlSetProp(xpathNode, xmlSecAttrFilter, type);
+
+ xmlSecNodeEncodeAndSetContent(xpathNode, expression);
+ return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpathNode, nsList) : 0);
+}
+
+/**
+ * xmlSecTmplTransformAddXPointer:
+ * @transformNode: the pointer to the <dsig:Transform/> node.
+ * @expression: the XPath expression.
+ * @nsList: the NULL terminated list of namespace prefix/href pairs.
+ * (optional).
+ *
+ * Writes XPoniter transform infromation to the <dsig:Transform/> node
+ * @node.
+ *
+ * Returns: 0 for success or a negative value otherwise.
+ */
+int
+xmlSecTmplTransformAddXPointer(xmlNodePtr transformNode, const xmlChar *expression,
+ const xmlChar **nsList) {
+ xmlNodePtr xpointerNode;
+
+ xmlSecAssert2(expression != NULL, -1);
+ xmlSecAssert2(transformNode != NULL, -1);
+
+ xpointerNode = xmlSecFindChild(transformNode, xmlSecNodeXPointer, xmlSecXPointerNs);
+ if(xpointerNode != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeXPointer),
+ XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ xpointerNode = xmlSecAddChild(transformNode, xmlSecNodeXPointer, xmlSecXPointerNs);
+ if(xpointerNode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecAddChild",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeXPointer));
+ return(-1);
+ }
+
+
+ xmlSecNodeEncodeAndSetContent(xpointerNode, expression);
+ return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpointerNode, nsList) : 0);
+}
+
+static int
+xmlSecTmplNodeWriteNsList(xmlNodePtr parentNode, const xmlChar** nsList) {
+ xmlNsPtr ns;
+ const xmlChar *prefix;
+ const xmlChar *href;
+ const xmlChar **ptr;
+
+ xmlSecAssert2(parentNode != NULL, -1);
+ xmlSecAssert2(nsList != NULL, -1);
+
+ ptr = nsList;
+ while((*ptr) != NULL) {
+ if(xmlStrEqual(BAD_CAST "#default", (*ptr))) {
+ prefix = NULL;
+ } else {
+ prefix = (*ptr);
+ }
+ if((++ptr) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_DATA,
+ "unexpected end of ns list");
+ return(-1);
+ }
+ href = *(ptr++);
+
+ ns = xmlNewNs(parentNode, href, prefix);
+ if(ns == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlNewNs",
+ XMLSEC_ERRORS_R_XML_FAILED,
+ "href=%s;prefix=%s",
+ xmlSecErrorsSafeString(href),
+ xmlSecErrorsSafeString(prefix));
+ return(-1);
+ }
+ }
+ return(0);
+}