/**
* 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>
* Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
*/
#include "xmlsec_globals.h"
#include <stdlib.h>
#include <string.h>
#include <libxml2_tree.h>
#include <libxml2_globals.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"
//added for symbian port
#include <libxml2_parser.h>
static int useNewLine = 1;
static unsigned char* dsPref = NULL;
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);
EXPORT_C
void xmlSetNewLineFlag(int aNewLine)
{
useNewLine = aNewLine;
}
int xmlGetNewLineFlag()
{
return useNewLine;
}
EXPORT_C
void xmlSetPrefix(unsigned char* aPref)
{
dsPref = aPref;
}
unsigned char* xmlGetPrefix()
{
return dsPref;
}
/**************************************************************************
*
* <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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplSignatureCreate(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
xmlSecTransformId signMethodId, const xmlChar *id) {
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, dsPref);
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) {
xmlAttrPtr ptr = xmlSetProp(signNode, BAD_CAST "Id", id);
if ( !ptr && OOM_FLAG )
{
xmlFreeNode(signNode);
return(NULL);
}
}
/* 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(xmlSetNsProp(cur, ns, 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(xmlSetNsProp(cur, ns, 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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplSignatureEnsureKeyInfo(xmlNodePtr signNode, const xmlChar *id) {
xmlNodePtr res;
int created = 0;
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);
}
created = 1;
}
if(id != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
if (!ptr && OOM_FLAG)
{
if (created)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
}
return(NULL);
}
}
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.
*/
EXPORT_C
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;
int error = 0;
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) {
xmlAttrPtr ptr = xmlSetNsProp(res, res->ns, xmlSecAttrId, id);
error = error || !ptr;
}
if(type != NULL) {
xmlAttrPtr ptr = xmlSetNsProp(res, res->ns, xmlSecAttrType, type);
error = error || !ptr;
}
if(uri != NULL) {
xmlAttrPtr ptr = xmlSetNsProp(res, res->ns, xmlSecAttrURI, uri);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
/* 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(xmlSetNsProp(cur, cur->ns, 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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplSignatureAddObject(xmlNodePtr signNode, const xmlChar *id,
const xmlChar *mimeType, const xmlChar *encoding) {
xmlNodePtr res;
int error = 0;
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) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
error = error || !ptr;
}
if(mimeType != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrMimeType, mimeType);
error = error || !ptr;
}
if(encoding != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrEncoding, encoding);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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(xmlSetNsProp(res, res->ns, 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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplObjectAddSignProperties(xmlNodePtr objectNode, const xmlChar *id, const xmlChar *target) {
xmlNodePtr res;
int error = 0;
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) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
error = error || !ptr;
}
if(target != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrTarget, target);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
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.
*/
EXPORT_C
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) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
if (!ptr && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
}
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.
*/
EXPORT_C
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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplEncDataCreate(xmlDocPtr doc, xmlSecTransformId encMethodId,
const xmlChar *id, const xmlChar *type,
const xmlChar *mimeType, const xmlChar *encoding) {
xmlNodePtr encNode;
xmlNsPtr ns;
int error = 0;
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) {
xmlFreeNode(encNode);
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
"xmlNewNs",
XMLSEC_ERRORS_R_XML_FAILED,
"ns=%s",
xmlSecErrorsSafeString(xmlSecEncNs));
return(NULL);
}
xmlSetNs(encNode, ns);
if(id != NULL) {
xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrId, id);
error = error || !ptr;
}
if(type != NULL) {
xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrType, type);
error = error || !ptr;
}
if(mimeType != NULL) {
xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrMimeType, mimeType);
error = error || !ptr;
}
if(encoding != NULL) {
xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrEncoding, encoding);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlFreeNode(encNode);
return(NULL);
}
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.
*/
EXPORT_C
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) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
if (!ptr && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
}
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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplEncDataEnsureEncProperties(xmlNodePtr encNode, const xmlChar *id) {
xmlNodePtr res;
int created = 0;
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);
}
created = 1;
}
if(id != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
if (!ptr && OOM_FLAG)
{
if (created)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
}
return(NULL);
}
}
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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplEncDataAddEncProperty(xmlNodePtr encNode, const xmlChar *id, const xmlChar *target) {
xmlNodePtr encProps;
xmlNodePtr res;
int error = 0;
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) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
error = error || !ptr;
}
if(target != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrTarget, target);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
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.
*/
EXPORT_C
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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplEncDataEnsureCipherReference(xmlNodePtr encNode, const xmlChar *uri) {
xmlNodePtr cipherDataNode;
xmlNodePtr res, tmp;
int created = 1;
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);
}
created = 1;
}
if(uri != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrURI, uri);
if (!ptr && OOM_FLAG)
{
if (created)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
}
return(NULL);
}
}
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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) {
xmlNodeSetContent(res, name);
if ( OOM_FLAG )
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
}
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplKeyInfoAddRetrievalMethod(xmlNodePtr keyInfoNode, const xmlChar *uri,
const xmlChar *type) {
xmlNodePtr res;
int error = 0;
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) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrURI, uri);
error = error || !ptr;
}
if(type != NULL) {
xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrType, type);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlUnlinkNode(res);
xmlFreeNode(res);
return(NULL);
}
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.
*/
EXPORT_C
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.
*/
EXPORT_C
xmlNodePtr
xmlSecTmplKeyInfoAddEncryptedKey(xmlNodePtr keyInfoNode, xmlSecTransformId encMethodId,
const xmlChar* id, const xmlChar* type, const xmlChar* recipient) {
xmlNodePtr encKeyNode;
int error = 0;
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) {
xmlAttrPtr ptr = xmlSetProp(encKeyNode, xmlSecAttrId, id);
error = error || !ptr;
}
if(type != NULL) {
xmlAttrPtr ptr = xmlSetProp(encKeyNode, xmlSecAttrType, type);
error = error || !ptr;
}
if(recipient != NULL) {
xmlAttrPtr ptr = xmlSetProp(encKeyNode, xmlSecAttrRecipient, recipient);
error = error || !ptr;
}
if (error && OOM_FLAG)
{
xmlUnlinkNode(encKeyNode);
xmlFreeNode(encKeyNode);
return(NULL);
}
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.
*/
EXPORT_C
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);
}
/**
* 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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
int
xmlSecTmplTransformAddC14NInclNamespaces(xmlNodePtr transformNode,
const xmlChar *prefixList) {
xmlNodePtr cur;
xmlAttrPtr ptr;
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);
}
ptr = xmlSetProp(cur, xmlSecAttrPrefixList, prefixList);
if (!ptr && OOM_FLAG)
{
xmlUnlinkNode(cur);
xmlFreeNode(cur);
return(-1);
}
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.
*/
EXPORT_C
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);
}
xmlNodeSetContent(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.
*/
EXPORT_C
int
xmlSecTmplTransformAddXPath2(xmlNodePtr transformNode, const xmlChar* type,
const xmlChar *expression, const xmlChar **nsList) {
xmlNodePtr xpathNode;
xmlAttrPtr ptr;
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);
}
ptr = xmlSetProp(xpathNode, xmlSecAttrFilter, type);
if (!ptr && OOM_FLAG)
{
xmlUnlinkNode(xpathNode);
xmlFreeNode(xpathNode);
return(-1);
}
xmlNodeSetContent(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.
*/
EXPORT_C
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);
}
xmlNodeSetContent(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);
}