xmlsecurityengine/xmlsec/src/xmlsec_templates.c
changeset 0 e35f40988205
child 24 74f0b3eb154c
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /** 
       
     2  * XML Security Library (http://www.aleksey.com/xmlsec).
       
     3  *
       
     4  * Creating signature and encryption templates.
       
     5  *
       
     6  * This is free software; see Copyright file in the source
       
     7  * distribution for preciese wording.
       
     8  * 
       
     9  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
       
    10  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    11  */
       
    12 #include "xmlsec_globals.h"
       
    13 
       
    14 #include <stdlib.h>
       
    15 #include <string.h>
       
    16  
       
    17 #include <libxml2_tree.h>
       
    18 #include <libxml2_globals.h>
       
    19 
       
    20 #include "xmlsec_xmlsec.h"
       
    21 #include "xmlsec_xmltree.h"
       
    22 #include "xmlsec_transforms.h"
       
    23 #include "xmlsec_strings.h"
       
    24 #include "xmlsec_base64.h"
       
    25 #include "xmlsec_templates.h"
       
    26 #include "xmlsec_errors.h"
       
    27 
       
    28 //added for symbian port
       
    29 #include <libxml2_parser.h>
       
    30 
       
    31 static int useNewLine = 1;
       
    32 
       
    33 static unsigned char* dsPref = NULL;
       
    34 
       
    35 static xmlNodePtr 	xmlSecTmplAddReference		(xmlNodePtr parentNode, 
       
    36 							 xmlSecTransformId digestMethodId,
       
    37 							 const xmlChar *id, 
       
    38 							 const xmlChar *uri, 
       
    39 							 const xmlChar *type);
       
    40 static int	 	xmlSecTmplPrepareEncData	(xmlNodePtr parentNode, 
       
    41 							 xmlSecTransformId encMethodId);
       
    42 static int 		xmlSecTmplNodeWriteNsList	(xmlNodePtr parentNode, 
       
    43 							 const xmlChar** namespaces);
       
    44 EXPORT_C
       
    45 							 
       
    46 							 
       
    47 void xmlSetNewLineFlag(int aNewLine)
       
    48     {
       
    49     useNewLine = aNewLine;
       
    50     }
       
    51 
       
    52 int xmlGetNewLineFlag()
       
    53     {
       
    54     return useNewLine;
       
    55     }
       
    56 EXPORT_C
       
    57 
       
    58 void xmlSetPrefix(unsigned char* aPref)
       
    59     {
       
    60     dsPref = aPref;
       
    61     }
       
    62 
       
    63 unsigned char* xmlGetPrefix()
       
    64     {
       
    65     return dsPref;
       
    66     }
       
    67 
       
    68 /**************************************************************************
       
    69  *
       
    70  * <dsig:Signature/> node
       
    71  *
       
    72  **************************************************************************/
       
    73 /**
       
    74  * xmlSecTmplSignatureCreate:
       
    75  * @doc: 		the pointer to signature document or NULL; in the 
       
    76  *			second case, application must later call @xmlSetTreeDoc
       
    77  *			to ensure that all the children nodes have correct 
       
    78  *			pointer to XML document.
       
    79  * @c14nMethodId: 	the signature canonicalization method.
       
    80  * @signMethodId: 	the signature  method.
       
    81  * @id: 		the node id (may be NULL).
       
    82  *
       
    83  * Creates new <dsig:Signature/> node with the mandatory <dsig:SignedInfo/>, 
       
    84  * <dsig:CanonicalizationMethod/>, <dsig:SignatureMethod/> and 
       
    85  * <dsig:SignatureValue/> children and sub-children. 
       
    86  * The application is responsible for inserting the returned node
       
    87  * in the XML document. 
       
    88  *
       
    89  * Returns the pointer to newly created <dsig:Signature/> node or NULL if an 
       
    90  * error occurs.
       
    91  */
       
    92 EXPORT_C
       
    93 xmlNodePtr
       
    94 xmlSecTmplSignatureCreate(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
       
    95 		      xmlSecTransformId signMethodId, const xmlChar *id) {
       
    96     xmlNodePtr signNode;
       
    97     xmlNodePtr signedInfoNode;
       
    98     xmlNodePtr cur;
       
    99     xmlNsPtr ns;
       
   100     
       
   101     xmlSecAssert2(c14nMethodId != NULL, NULL);
       
   102     xmlSecAssert2(c14nMethodId->href != NULL, NULL);
       
   103     xmlSecAssert2(signMethodId != NULL, NULL);
       
   104     xmlSecAssert2(signMethodId->href != NULL, NULL);
       
   105     
       
   106     /* create Signature node itself */
       
   107     signNode = xmlNewDocNode(doc, NULL, xmlSecNodeSignature, NULL);
       
   108     if(signNode == NULL) {
       
   109 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   110 		    NULL,
       
   111 		    "xmlNewDocNode",
       
   112 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   113 		    "node=%s",
       
   114 		    xmlSecErrorsSafeString(xmlSecNodeSignature));
       
   115 	return(NULL);	            
       
   116     }
       
   117     
       
   118     ns = xmlNewNs(signNode, xmlSecDSigNs, dsPref);
       
   119     if(ns == NULL) {
       
   120 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   121 		    NULL,
       
   122 		    "xmlNewNs",
       
   123 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   124 		    "ns=%s",
       
   125 		    xmlSecErrorsSafeString(xmlSecDSigNs));
       
   126 	xmlFreeNode(signNode);
       
   127 	return(NULL);	        	
       
   128     }
       
   129     xmlSetNs(signNode, ns);
       
   130     
       
   131     if(id != NULL) {
       
   132 	    xmlAttrPtr ptr = xmlSetProp(signNode, BAD_CAST "Id", id);
       
   133 	    if ( !ptr && OOM_FLAG ) 
       
   134 	        {
       
   135 	        xmlFreeNode(signNode);
       
   136 	        return(NULL);
       
   137 	        }
       
   138     }
       
   139 
       
   140     /* add SignedInfo node */    
       
   141     signedInfoNode = xmlSecAddChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
       
   142     if(signedInfoNode == NULL) {
       
   143 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   144 		    NULL,
       
   145 		    "xmlSecAddChild",
       
   146 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   147 		    "node=%s",
       
   148 		    xmlSecErrorsSafeString(xmlSecNodeSignedInfo));
       
   149 	xmlFreeNode(signNode);
       
   150 	return(NULL);	        	
       
   151     }
       
   152 
       
   153     /* add SignatureValue node */    
       
   154     cur = xmlSecAddChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
       
   155     if(cur == NULL) {
       
   156 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   157 		    NULL,
       
   158 		    "xmlSecAddChild",
       
   159 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   160 		    "node=%s",
       
   161 		    xmlSecErrorsSafeString(xmlSecNodeSignatureValue));
       
   162 	xmlFreeNode(signNode);
       
   163 	return(NULL);	        	
       
   164     }
       
   165 
       
   166     /* add CanonicaizationMethod node to SignedInfo */
       
   167     cur = xmlSecAddChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs);
       
   168     if(cur == NULL) {
       
   169 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   170 		    NULL,
       
   171 		    "xmlSecAddChild",
       
   172 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   173 		    "node=%s",
       
   174 		    xmlSecErrorsSafeString(xmlSecNodeCanonicalizationMethod));
       
   175 	xmlFreeNode(signNode);
       
   176 	return(NULL);	        	
       
   177     }
       
   178     if(xmlSetNsProp(cur, ns, xmlSecAttrAlgorithm, c14nMethodId->href) == NULL) {
       
   179 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   180 		    NULL,
       
   181 		    "xmlSetProp",
       
   182 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   183 		    "name=%s,value=%s",
       
   184 		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
   185 		    xmlSecErrorsSafeString(c14nMethodId->href));
       
   186 	xmlFreeNode(signNode);
       
   187 	return(NULL);	        	
       
   188     }
       
   189 
       
   190     /* add SignatureMethod node to SignedInfo */
       
   191     cur = xmlSecAddChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs);
       
   192     if(cur == NULL) {
       
   193 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   194 		    NULL,
       
   195 		    "xmlSecAddChild",
       
   196 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   197 		    "node=%s",
       
   198 		    xmlSecErrorsSafeString(xmlSecNodeSignatureMethod));
       
   199 	xmlFreeNode(signNode);
       
   200 	return(NULL);	        	
       
   201     }
       
   202     if(xmlSetNsProp(cur, ns, xmlSecAttrAlgorithm, signMethodId->href) == NULL) {
       
   203 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   204 		    NULL,
       
   205 		    "xmlSetProp",
       
   206 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   207 		    "name=%s,value=%s",
       
   208 		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
   209 		    xmlSecErrorsSafeString(signMethodId->href));
       
   210 	xmlFreeNode(signNode);
       
   211 	return(NULL);	        	
       
   212     }
       
   213         
       
   214     return(signNode);
       
   215 }
       
   216 
       
   217 /**
       
   218  * xmlSecTmplSignatureEnsureKeyInfo:
       
   219  * @signNode: 		the  pointer to <dsig:Signature/> node.
       
   220  * @id: 		the node id (may be NULL).
       
   221  *
       
   222  * Adds (if necessary) <dsig:KeyInfo/> node to the <dsig:Signature/> 
       
   223  * node @signNode. 
       
   224  *
       
   225  * Returns the pointer to newly created <dsig:KeyInfo/> node or NULL if an 
       
   226  * error occurs.
       
   227  */
       
   228 EXPORT_C
       
   229 xmlNodePtr
       
   230 xmlSecTmplSignatureEnsureKeyInfo(xmlNodePtr signNode, const xmlChar *id) {
       
   231     xmlNodePtr res;
       
   232     int created = 0;
       
   233     
       
   234     xmlSecAssert2(signNode != NULL, NULL);
       
   235 
       
   236     res = xmlSecFindChild(signNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
       
   237     if(res == NULL) {
       
   238 	xmlNodePtr signValueNode;
       
   239     
       
   240         signValueNode = xmlSecFindChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
       
   241 	if(signValueNode == NULL) {
       
   242 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   243 		        NULL,
       
   244 			xmlSecErrorsSafeString(xmlSecNodeSignatureValue),
       
   245 		        XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
   246 			XMLSEC_ERRORS_NO_MESSAGE);
       
   247 	    return(NULL);	
       
   248 	}
       
   249 
       
   250 	res = xmlSecAddNextSibling(signValueNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
       
   251 	if(res == NULL) {
       
   252 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   253 		        NULL,
       
   254 			"xmlSecAddNextSibling",
       
   255 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   256 			"node=%s",
       
   257 			xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
       
   258 	    return(NULL);	        	
       
   259 	}
       
   260 	created = 1;
       
   261     }
       
   262     if(id != NULL) {
       
   263 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   264         if (!ptr && OOM_FLAG) 
       
   265             {
       
   266             if (created) 
       
   267                 {
       
   268                 xmlUnlinkNode(res);
       
   269     	        xmlFreeNode(res);
       
   270                 }
       
   271             return(NULL);
       
   272             }
       
   273     }
       
   274     return(res);        
       
   275 }         
       
   276 
       
   277 /**
       
   278  * xmlSecTmplSignatureAddReference:
       
   279  * @signNode: 		the pointer to <dsig:Signature/> node.
       
   280  * @digestMethodId:	the reference digest method.
       
   281  * @id: 		the node id (may be NULL).
       
   282  * @uri: 		the reference node uri (may be NULL).
       
   283  * @type: 		the reference node type (may be NULL).
       
   284  *
       
   285  * Adds <dsig:Reference/> node with given URI (@uri), Id (@id) and 
       
   286  * Type (@type) attributes and the required children <dsig:DigestMethod/> and
       
   287  * <dsig:DigestValue/> to the <dsig:SignedInfo/> child of @signNode. 
       
   288  *
       
   289  * Returns the pointer to newly created <dsig:Reference/> node or NULL 
       
   290  * if an error occurs.
       
   291  */
       
   292 EXPORT_C
       
   293 xmlNodePtr	
       
   294 xmlSecTmplSignatureAddReference(xmlNodePtr signNode, xmlSecTransformId digestMethodId,
       
   295 		    const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
       
   296     xmlNodePtr signedInfoNode;
       
   297     
       
   298     xmlSecAssert2(signNode != NULL, NULL);
       
   299     xmlSecAssert2(digestMethodId != NULL, NULL);
       
   300     xmlSecAssert2(digestMethodId->href != NULL, NULL);
       
   301 
       
   302     signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
       
   303     if(signedInfoNode == NULL) {
       
   304 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   305 		    NULL,
       
   306 		    xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
       
   307 		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
   308 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   309 	return(NULL);	
       
   310     }
       
   311     
       
   312     return(xmlSecTmplAddReference(signedInfoNode, digestMethodId, id, uri, type));
       
   313 }
       
   314 
       
   315 static xmlNodePtr 
       
   316 xmlSecTmplAddReference(xmlNodePtr parentNode, xmlSecTransformId digestMethodId,
       
   317 		    const xmlChar *id, const xmlChar *uri, const xmlChar *type) {    
       
   318     xmlNodePtr res;
       
   319     xmlNodePtr cur;
       
   320     int error = 0;
       
   321     
       
   322     xmlSecAssert2(parentNode != NULL, NULL);
       
   323     xmlSecAssert2(digestMethodId != NULL, NULL);
       
   324     xmlSecAssert2(digestMethodId->href != NULL, NULL);
       
   325 
       
   326     /* add Reference node */
       
   327     res = xmlSecAddChild(parentNode, xmlSecNodeReference, xmlSecDSigNs);
       
   328     if(res == NULL) {
       
   329 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   330 		    NULL,
       
   331 		    "xmlSecAddChild",
       
   332 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   333 		    "node=%s",
       
   334 		    xmlSecErrorsSafeString(xmlSecNodeReference));
       
   335 	return(NULL);
       
   336     }
       
   337 
       
   338     /* set Reference node attributes */
       
   339     if(id != NULL) {
       
   340 	xmlAttrPtr ptr = xmlSetNsProp(res, res->ns, xmlSecAttrId, id);
       
   341     error = error || !ptr;
       
   342     }
       
   343     if(type != NULL) {
       
   344 	xmlAttrPtr ptr = xmlSetNsProp(res, res->ns, xmlSecAttrType, type);
       
   345     error = error || !ptr;
       
   346     }
       
   347     if(uri != NULL) {
       
   348 	xmlAttrPtr ptr = xmlSetNsProp(res, res->ns, xmlSecAttrURI, uri);
       
   349     error = error || !ptr;
       
   350     }
       
   351     if (error && OOM_FLAG) 
       
   352         {
       
   353  	    xmlUnlinkNode(res);
       
   354 	    xmlFreeNode(res); 
       
   355 	    return(NULL);      
       
   356         }
       
   357 
       
   358     /* add DigestMethod node and set algorithm */    
       
   359     cur = xmlSecAddChild(res, xmlSecNodeDigestMethod, xmlSecDSigNs);
       
   360     if(cur == NULL) {
       
   361 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   362 		    NULL,
       
   363 		    "xmlSecAddChild",
       
   364 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   365 		    "node=%s",
       
   366 		    xmlSecErrorsSafeString(xmlSecNodeDigestMethod));
       
   367 	xmlUnlinkNode(res);
       
   368 	xmlFreeNode(res);
       
   369 	return(NULL);	        	
       
   370     }
       
   371     if(xmlSetNsProp(cur, cur->ns, xmlSecAttrAlgorithm, digestMethodId->href) == NULL) {
       
   372 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   373 		    NULL,
       
   374 		    "xmlSetProp",
       
   375 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   376 		    "name=%s,value=%s",
       
   377 		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
   378 		    xmlSecErrorsSafeString(digestMethodId->href));
       
   379 	xmlUnlinkNode(res);
       
   380 	xmlFreeNode(res);
       
   381 	return(NULL);	        	
       
   382     }
       
   383 
       
   384     /* add DigestValue node */    
       
   385     cur = xmlSecAddChild(res, xmlSecNodeDigestValue, xmlSecDSigNs);
       
   386     if(cur == NULL) {
       
   387 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   388 		    NULL,
       
   389 		    "xmlSecAddChild",
       
   390 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   391 		    "node=%s",
       
   392 		    xmlSecErrorsSafeString(xmlSecNodeDigestValue));
       
   393 	xmlUnlinkNode(res);
       
   394 	xmlFreeNode(res);
       
   395 	return(NULL);	        	
       
   396     }
       
   397     
       
   398     return(res);    
       
   399 }
       
   400 
       
   401 /**
       
   402  * xmlSecTmplSignatureAddObject:
       
   403  * @signNode: 		the pointer to <dsig:Signature/> node.
       
   404  * @id: 		the node id (may be NULL).
       
   405  * @mimeType: 		the object mime type (may be NULL).
       
   406  * @encoding: 		the object encoding (may be NULL).
       
   407  *
       
   408  * Adds <dsig:Object/> node to the <dsig:Signature/> node @signNode. 
       
   409  *
       
   410  * Returns the pointer to newly created <dsig:Object/> node or NULL 
       
   411  * if an error occurs.
       
   412  */
       
   413 EXPORT_C
       
   414 xmlNodePtr
       
   415 xmlSecTmplSignatureAddObject(xmlNodePtr signNode, const xmlChar *id, 
       
   416 			 const xmlChar *mimeType, const xmlChar *encoding) {
       
   417     xmlNodePtr res;
       
   418     int error = 0;
       
   419 
       
   420     xmlSecAssert2(signNode != NULL, NULL);
       
   421     
       
   422     res = xmlSecAddChild(signNode, xmlSecNodeObject, xmlSecDSigNs);
       
   423     if(res == NULL) {
       
   424 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   425 		    NULL,
       
   426 		    "xmlSecAddChild",
       
   427 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   428 		    "node=%s",
       
   429 		    xmlSecErrorsSafeString(xmlSecNodeObject));
       
   430 	return(NULL);	        	
       
   431     }
       
   432     if(id != NULL) {
       
   433 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   434     error = error || !ptr;
       
   435     }
       
   436     if(mimeType != NULL) {
       
   437 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrMimeType, mimeType);
       
   438     error = error || !ptr;
       
   439     }
       
   440     if(encoding != NULL) {
       
   441 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrEncoding, encoding);
       
   442     error = error || !ptr;
       
   443     }
       
   444     if (error && OOM_FLAG) 
       
   445         {
       
   446         xmlUnlinkNode(res);
       
   447 	    xmlFreeNode(res);
       
   448 	    return(NULL);
       
   449         }
       
   450     
       
   451     return(res);        
       
   452 }
       
   453 
       
   454 /** 
       
   455  * xmlSecTmplSignatureGetSignMethodNode:
       
   456  * @signNode:		the pointer to <dsig:Signature /> node.
       
   457  *
       
   458  * Gets pointer to <dsig:SignatureMethod/> child of <dsig:KeyInfo/> node.
       
   459  *
       
   460  * Returns pointer to <dsig:SignatureMethod /> node or NULL if an error occurs.
       
   461  */
       
   462 EXPORT_C
       
   463 xmlNodePtr 
       
   464 xmlSecTmplSignatureGetSignMethodNode(xmlNodePtr signNode) {
       
   465     xmlNodePtr signedInfoNode;
       
   466     
       
   467     xmlSecAssert2(signNode != NULL, NULL);
       
   468     
       
   469     signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
       
   470     if(signedInfoNode == NULL) {
       
   471 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   472 		    NULL,
       
   473 		    xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
       
   474 		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
   475 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   476 	return(NULL);	
       
   477     }
       
   478     return(xmlSecFindChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs));
       
   479 }
       
   480 
       
   481 /** 
       
   482  * xmlSecTmplSignatureGetC14NMethodNode:
       
   483  * @signNode:		the pointer to <dsig:Signature /> node.
       
   484  *
       
   485  * Gets pointer to <dsig:CanonicalizationMethod/> child of <dsig:KeyInfo/> node.
       
   486  *
       
   487  * Returns pointer to <dsig:CanonicalizationMethod /> node or NULL if an error occurs.
       
   488  */
       
   489 EXPORT_C
       
   490 xmlNodePtr 
       
   491 xmlSecTmplSignatureGetC14NMethodNode(xmlNodePtr signNode) {
       
   492     xmlNodePtr signedInfoNode;
       
   493     
       
   494     xmlSecAssert2(signNode != NULL, NULL);
       
   495     
       
   496     signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
       
   497     if(signedInfoNode == NULL) {
       
   498 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   499 		    NULL,
       
   500 		    xmlSecErrorsSafeString(xmlSecNodeSignedInfo),
       
   501 		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
   502 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   503 	return(NULL);	
       
   504     }
       
   505     return(xmlSecFindChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs));
       
   506 }
       
   507 
       
   508 /**
       
   509  * xmlSecTmplReferenceAddTransform:
       
   510  * @referenceNode: 		the pointer to <dsig:Reference/> node.
       
   511  * @transformId: 		the transform method id.
       
   512  *
       
   513  * Adds <dsig:Transform/> node to the <dsig:Reference/> node @referenceNode.
       
   514  * 
       
   515  * Returns the pointer to newly created <dsig:Transform/> node or NULL if an 
       
   516  * error occurs.
       
   517  */
       
   518 EXPORT_C
       
   519 xmlNodePtr
       
   520 xmlSecTmplReferenceAddTransform(xmlNodePtr referenceNode, xmlSecTransformId transformId) {
       
   521     xmlNodePtr transformsNode;
       
   522     xmlNodePtr res;
       
   523     
       
   524     xmlSecAssert2(referenceNode != NULL, NULL);
       
   525     xmlSecAssert2(transformId != NULL, NULL);
       
   526     xmlSecAssert2(transformId->href != NULL, NULL);
       
   527 
       
   528     /* do we need to create Transforms node first */
       
   529     transformsNode = xmlSecFindChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
       
   530     if(transformsNode == NULL) {
       
   531 	xmlNodePtr tmp;
       
   532 	
       
   533 	tmp = xmlSecGetNextElementNode(referenceNode->children);
       
   534 	if(tmp == NULL) {
       
   535 	    transformsNode = xmlSecAddChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
       
   536 	} else {
       
   537 	    transformsNode = xmlSecAddPrevSibling(tmp, xmlSecNodeTransforms, xmlSecDSigNs);
       
   538 	}   
       
   539 	if(transformsNode == NULL) {
       
   540 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   541 			NULL,
       
   542 			"xmlSecAddChild or xmlSecAddPrevSibling",
       
   543 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   544 			"node=%s",
       
   545 			xmlSecErrorsSafeString(xmlSecNodeTransforms));
       
   546 	    return(NULL);	        	
       
   547 	}
       
   548     }
       
   549 
       
   550     res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
       
   551     if(res == NULL) {
       
   552 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   553 		    NULL,
       
   554 		    "xmlSecAddChild",
       
   555 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   556 		    "node=%s",
       
   557 		    xmlSecErrorsSafeString(xmlSecNodeTransform));
       
   558 	return(NULL);	        	
       
   559     }
       
   560 
       
   561     if(xmlSetNsProp(res, res->ns, xmlSecAttrAlgorithm, transformId->href) == NULL) {
       
   562 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   563 		    NULL,
       
   564 		    "xmlSetProp",
       
   565 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   566 		    "name=%s,value=%s",
       
   567 		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
   568 		    xmlSecErrorsSafeString(transformId->href));
       
   569 	xmlUnlinkNode(res);
       
   570 	xmlFreeNode(res);
       
   571 	return(NULL);	        	
       
   572     }
       
   573 
       
   574     return(res);    
       
   575 }
       
   576 
       
   577 /**
       
   578  * xmlSecTmplObjectAddSignProperties:
       
   579  * @objectNode: 	the  pointer to <dsig:Object/> node.
       
   580  * @id: 		the node id (may be NULL).
       
   581  * @target: 		the Target  (may be NULL).
       
   582  *
       
   583  * Adds <dsig:SignatureProperties/> node to the <dsig:Object/> node @objectNode.
       
   584  *
       
   585  * Returns the pointer to newly created <dsig:SignatureProperties/> node or NULL 
       
   586  * if an error occurs.
       
   587  */
       
   588 EXPORT_C
       
   589 xmlNodePtr		
       
   590 xmlSecTmplObjectAddSignProperties(xmlNodePtr objectNode, const xmlChar *id, const xmlChar *target) {
       
   591     xmlNodePtr res;
       
   592     int error = 0;
       
   593 
       
   594     xmlSecAssert2(objectNode != NULL, NULL);
       
   595 
       
   596     res = xmlSecAddChild(objectNode, xmlSecNodeSignatureProperties, xmlSecDSigNs);
       
   597     if(res == NULL) {
       
   598 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   599 		    NULL,
       
   600 		    "xmlSecAddChild",
       
   601 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   602 		    "node=%s",
       
   603 		    xmlSecErrorsSafeString(xmlSecNodeSignatureProperties));
       
   604 	return(NULL);	        	
       
   605     }
       
   606     if(id != NULL) {
       
   607 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   608     error = error || !ptr;
       
   609     }
       
   610     if(target != NULL) {
       
   611 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrTarget, target);
       
   612     error = error || !ptr;
       
   613     }
       
   614     if (error && OOM_FLAG) 
       
   615         {
       
   616         xmlUnlinkNode(res);
       
   617 	    xmlFreeNode(res);
       
   618 	    return(NULL);
       
   619         }
       
   620     return(res);
       
   621 }
       
   622 
       
   623 /**
       
   624  * xmlSecTmplObjectAddManifest:
       
   625  * @objectNode: 	the  pointer to <dsig:Object/> node.
       
   626  * @id: 		the node id (may be NULL).
       
   627  *
       
   628  * Adds <dsig:Manifest/> node to the <dsig:Object/> node @objectNode.
       
   629  *
       
   630  * Returns the pointer to newly created <dsig:Manifest/> node or NULL 
       
   631  * if an error occurs.
       
   632  */
       
   633 EXPORT_C
       
   634 xmlNodePtr
       
   635 xmlSecTmplObjectAddManifest(xmlNodePtr objectNode,  const xmlChar *id) {
       
   636     xmlNodePtr res;
       
   637 
       
   638     xmlSecAssert2(objectNode != NULL, NULL);
       
   639 
       
   640     res = xmlSecAddChild(objectNode, xmlSecNodeManifest, xmlSecDSigNs);
       
   641     if(res == NULL) {
       
   642 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   643 		    NULL,
       
   644 		    "xmlSecAddChild",
       
   645 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   646 		    "node=%s",
       
   647 		    xmlSecErrorsSafeString(xmlSecNodeManifest));
       
   648 	return(NULL);	        	
       
   649     }
       
   650     if(id != NULL) {
       
   651 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   652         if (!ptr && OOM_FLAG) 
       
   653             {
       
   654             xmlUnlinkNode(res);
       
   655 	        xmlFreeNode(res);
       
   656 	        return(NULL);
       
   657             }
       
   658     }
       
   659     return(res);
       
   660 }
       
   661 
       
   662 /**
       
   663  * xmlSecTmplManifestAddReference:
       
   664  * @manifestNode: 	the pointer to <dsig:Manifest/> node.
       
   665  * @digestMethodId:	the reference digest method.
       
   666  * @id: 		the node id (may be NULL).
       
   667  * @uri: 		the reference node uri (may be NULL).
       
   668  * @type: 		the reference node type (may be NULL).
       
   669  *
       
   670  * Adds <dsig:Reference/> node with specified URI (@uri), Id (@id) and 
       
   671  * Type (@type) attributes and the required children <dsig:DigestMethod/> and
       
   672  * <dsig:DigestValue/> to the <dsig:Manifest/> node @manifestNode.
       
   673  *
       
   674  * Returns the pointer to newly created <dsig:Reference/> node or NULL 
       
   675  * if an error occurs.
       
   676  */
       
   677 EXPORT_C
       
   678 xmlNodePtr 
       
   679 xmlSecTmplManifestAddReference(xmlNodePtr manifestNode, xmlSecTransformId digestMethodId,
       
   680 			      const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
       
   681     return(xmlSecTmplAddReference(manifestNode, digestMethodId, id, uri, type));
       
   682 }
       
   683 
       
   684 /**************************************************************************
       
   685  *
       
   686  * <enc:EncryptedData/> node
       
   687  *
       
   688  **************************************************************************/
       
   689 /** 
       
   690  * xmlSecTmplEncDataCreate:
       
   691  * @doc: 		the pointer to signature document or NULL; in the later
       
   692  *			case, application must later call @xmlSetTreeDoc to ensure 
       
   693  *			that all the children nodes have correct pointer to XML document.
       
   694  * @encMethodId:	the encryption method (may be NULL).
       
   695  * @id: 		the Id attribute (optional).
       
   696  * @type: 		the Type attribute (optional)
       
   697  * @mimeType: 		the MimeType attribute (optional)
       
   698  * @encoding: 		the Encoding attribute (optional)
       
   699  *
       
   700  * Creates new <enc:EncryptedData /> node for encryption template. 
       
   701  *
       
   702  * Returns the pointer newly created  <enc:EncryptedData/> node or NULL 
       
   703  * if an error occurs.
       
   704  */
       
   705 EXPORT_C
       
   706 xmlNodePtr		
       
   707 xmlSecTmplEncDataCreate(xmlDocPtr doc, xmlSecTransformId encMethodId,
       
   708 			    const xmlChar *id, const xmlChar *type,
       
   709 			    const xmlChar *mimeType, const xmlChar *encoding) {
       
   710     xmlNodePtr encNode;
       
   711     xmlNsPtr ns;
       
   712     int error = 0;
       
   713     
       
   714     encNode = xmlNewDocNode(doc, NULL, xmlSecNodeEncryptedData, NULL);
       
   715     if(encNode == NULL) {
       
   716 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   717 		    NULL,
       
   718 		    "xmlNewDocNode",
       
   719 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   720 		    "node=%s",
       
   721 		    xmlSecErrorsSafeString(xmlSecNodeEncryptedData));
       
   722 	return(NULL);	        
       
   723     }
       
   724     
       
   725     ns = xmlNewNs(encNode, xmlSecEncNs, NULL);
       
   726     if(ns == NULL) {
       
   727         xmlFreeNode(encNode);
       
   728 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   729 		    NULL,
       
   730 		    "xmlNewNs",
       
   731 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   732 		    "ns=%s",
       
   733 		    xmlSecErrorsSafeString(xmlSecEncNs));
       
   734 	return(NULL);	        	
       
   735     }
       
   736     xmlSetNs(encNode, ns);
       
   737     
       
   738     if(id != NULL) {
       
   739 	xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrId, id);
       
   740     error = error || !ptr;
       
   741     }
       
   742     if(type != NULL) {
       
   743 	xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrType, type);
       
   744     error = error || !ptr;
       
   745     }
       
   746     if(mimeType != NULL) {
       
   747 	xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrMimeType, mimeType);
       
   748     error = error || !ptr;
       
   749     }
       
   750     if(encoding != NULL) {
       
   751 	xmlAttrPtr ptr = xmlSetProp(encNode, xmlSecAttrEncoding, encoding);
       
   752     error = error || !ptr;
       
   753     }
       
   754     if (error && OOM_FLAG) 
       
   755         {
       
   756 	    xmlFreeNode(encNode);
       
   757 	    return(NULL);
       
   758         }
       
   759     
       
   760     if(xmlSecTmplPrepareEncData(encNode, encMethodId) < 0) {
       
   761 	xmlFreeNode(encNode);
       
   762 	return(NULL);
       
   763     }
       
   764     return(encNode);
       
   765 }
       
   766 
       
   767 static int  
       
   768 xmlSecTmplPrepareEncData(xmlNodePtr parentNode, xmlSecTransformId encMethodId) {
       
   769     xmlNodePtr cur;
       
   770     
       
   771     xmlSecAssert2(parentNode != NULL, -1);
       
   772     xmlSecAssert2((encMethodId == NULL) || (encMethodId->href != NULL), -1);
       
   773     
       
   774     /* add EncryptionMethod node if requested */
       
   775     if(encMethodId != NULL) {
       
   776 	cur = xmlSecAddChild(parentNode, xmlSecNodeEncryptionMethod, xmlSecEncNs);
       
   777 	if(cur == NULL) {
       
   778 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   779 			NULL,
       
   780 			"xmlSecAddChild",
       
   781 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   782 			"node=%s",
       
   783 			xmlSecErrorsSafeString(xmlSecNodeEncryptionMethod));
       
   784 	    return(-1);        	
       
   785 	}
       
   786 	if(xmlSetProp(cur, xmlSecAttrAlgorithm, encMethodId->href) == NULL) {
       
   787 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   788 		        NULL,
       
   789 			"xmlSetProp",
       
   790 		        XMLSEC_ERRORS_R_XML_FAILED,
       
   791 			"name=%s,value=%s",
       
   792 		        xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
   793 			xmlSecErrorsSafeString(encMethodId->href));
       
   794 	    return(-1); 	
       
   795 	}	
       
   796     }
       
   797         
       
   798     /* and CipherData node */
       
   799     cur = xmlSecAddChild(parentNode, xmlSecNodeCipherData, xmlSecEncNs);
       
   800     if(cur == NULL) {
       
   801 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   802 		    NULL,
       
   803 		    "xmlSecAddChild",
       
   804 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   805 		    "node=%s",
       
   806 		    xmlSecErrorsSafeString(xmlSecNodeCipherData));
       
   807 	return(-1);	        	
       
   808     }
       
   809     
       
   810     return(0);
       
   811 }
       
   812 
       
   813 
       
   814 /** 
       
   815  * xmlSecTmplEncDataEnsureKeyInfo:
       
   816  * @encNode: 		the pointer to <enc:EncryptedData/> node.
       
   817  * @id:			the Id attrbibute (optional).
       
   818  *
       
   819  * Adds <dsig:KeyInfo/> to the  <enc:EncryptedData/> node @encNode.
       
   820  *
       
   821  * Returns the pointer to newly created <dsig:KeyInfo/> node or 
       
   822  * NULL if an error occurs.
       
   823  */
       
   824 EXPORT_C
       
   825 xmlNodePtr
       
   826 xmlSecTmplEncDataEnsureKeyInfo(xmlNodePtr encNode, const xmlChar* id) {
       
   827     xmlNodePtr res;
       
   828     
       
   829     xmlSecAssert2(encNode != NULL, NULL);
       
   830 
       
   831     res = xmlSecFindChild(encNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
       
   832     if(res == NULL) {
       
   833 	xmlNodePtr cipherDataNode;
       
   834     
       
   835         cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
       
   836 	if(cipherDataNode == NULL) {
       
   837 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   838 		        NULL,
       
   839 			xmlSecErrorsSafeString(xmlSecNodeCipherData),
       
   840 		        XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
   841 			XMLSEC_ERRORS_NO_MESSAGE);
       
   842 	    return(NULL);	
       
   843 	}
       
   844 
       
   845 	res = xmlSecAddPrevSibling(cipherDataNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
       
   846 	if(res == NULL) {
       
   847 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   848 		        NULL,
       
   849 			"xmlSecAddPrevSibling",
       
   850 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   851 			"node=%s",
       
   852 			xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
       
   853 	    return(NULL);	        	
       
   854 	}
       
   855     }
       
   856     if(id != NULL) {
       
   857 	    xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   858         if (!ptr && OOM_FLAG) 
       
   859             {
       
   860             xmlUnlinkNode(res);
       
   861     	    xmlFreeNode(res);
       
   862     	    return(NULL);
       
   863             }
       
   864     }
       
   865     return(res);        
       
   866 }
       
   867 
       
   868 /** 
       
   869  * xmlSecTmplEncDataEnsureEncProperties:
       
   870  * @encNode: 		the pointer to <enc:EncryptedData/> node.
       
   871  * @id: 		the Id attribute (optional).
       
   872  *
       
   873  * Adds <enc:EncryptionProperties/> node to the <enc:EncryptedData/> 
       
   874  * node @encNode.
       
   875  *
       
   876  * Returns the pointer to newly created <enc:EncryptionProperties/> node or 
       
   877  * NULL if an error occurs.
       
   878  */
       
   879 EXPORT_C
       
   880 xmlNodePtr
       
   881 xmlSecTmplEncDataEnsureEncProperties(xmlNodePtr encNode, const xmlChar *id) {
       
   882     xmlNodePtr res;
       
   883     int created = 0;
       
   884 
       
   885     xmlSecAssert2(encNode != NULL, NULL);
       
   886 
       
   887     res = xmlSecFindChild(encNode, xmlSecNodeEncryptionProperties, xmlSecEncNs);
       
   888     if(res == NULL) {
       
   889 	res = xmlSecAddChild(encNode, xmlSecNodeEncryptionProperties, xmlSecEncNs);
       
   890 	if(res == NULL) {
       
   891 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   892 			NULL,
       
   893 			"xmlSecAddChild",
       
   894 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   895 			"node=%s",
       
   896 			xmlSecErrorsSafeString(xmlSecNodeEncryptionProperties));
       
   897 	    return(NULL);	        	
       
   898 	}
       
   899 	created = 1;
       
   900     }
       
   901 
       
   902     if(id != NULL) {
       
   903 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   904         if (!ptr && OOM_FLAG) 
       
   905             {
       
   906             if (created) 
       
   907                 {
       
   908                 xmlUnlinkNode(res);
       
   909         	    xmlFreeNode(res);
       
   910                 }
       
   911             return(NULL);
       
   912             }
       
   913     }
       
   914     
       
   915     return(res);
       
   916 }
       
   917 
       
   918 /** 
       
   919  * xmlSecTmplEncDataAddEncProperty:
       
   920  * @encNode: 		the pointer to <enc:EncryptedData/> node.
       
   921  * @id: 		the Id attribute (optional).
       
   922  * @target: 		the Target attribute (optional).
       
   923  *
       
   924  * Adds <enc:EncryptionProperty/> node (and the parent 
       
   925  * <enc:EncryptionProperties/> node if required) to the 
       
   926  * <enc:EncryptedData/> node @encNode.
       
   927  *
       
   928  * Returns the pointer to newly created <enc:EncryptionProperty/> node or 
       
   929  * NULL if an error occurs.
       
   930  */
       
   931 EXPORT_C
       
   932 xmlNodePtr	
       
   933 xmlSecTmplEncDataAddEncProperty(xmlNodePtr encNode, const xmlChar *id, const xmlChar *target) {
       
   934     xmlNodePtr encProps;
       
   935     xmlNodePtr res;
       
   936     int error = 0;
       
   937         
       
   938     xmlSecAssert2(encNode != NULL, NULL);
       
   939 
       
   940     encProps = xmlSecTmplEncDataEnsureEncProperties(encNode, NULL);
       
   941     if(encProps == NULL) {
       
   942 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   943 		    NULL,
       
   944 		    "xmlSecTmplEncDataEnsureEncProperties",
       
   945 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   946 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   947 	return(NULL);	
       
   948     }
       
   949 
       
   950     res = xmlSecAddChild(encProps, xmlSecNodeEncryptionProperty, xmlSecEncNs);
       
   951     if(res == NULL) {
       
   952 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   953 		    NULL,
       
   954 		    "xmlSecAddChild",
       
   955 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   956 		    "node=%s",
       
   957 		    xmlSecErrorsSafeString(xmlSecNodeEncryptionProperty));
       
   958 	return(NULL);	
       
   959     }
       
   960     if(id != NULL) {
       
   961 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrId, id);
       
   962     error = error || !ptr;
       
   963     }
       
   964     if(target != NULL) {
       
   965 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrTarget, target);
       
   966     error = error || !ptr;
       
   967     }
       
   968     if (error && OOM_FLAG) 
       
   969         {
       
   970         xmlUnlinkNode(res);
       
   971 	    xmlFreeNode(res);
       
   972 	    return(NULL);
       
   973         }
       
   974     
       
   975     return(res);
       
   976 }
       
   977 
       
   978 /** 
       
   979  * xmlSecTmplEncDataEnsureCipherValue:
       
   980  * @encNode: 		the pointer to <enc:EncryptedData/> node.
       
   981  *
       
   982  * Adds <enc:CipherValue/> to the <enc:EncryptedData/> node @encNode.
       
   983  *
       
   984  * Returns the pointer to newly created <enc:CipherValue/> node or 
       
   985  * NULL if an error occurs.
       
   986  */
       
   987 EXPORT_C
       
   988 xmlNodePtr
       
   989 xmlSecTmplEncDataEnsureCipherValue(xmlNodePtr encNode) {
       
   990     xmlNodePtr cipherDataNode;
       
   991     xmlNodePtr res, tmp;
       
   992         
       
   993     xmlSecAssert2(encNode != NULL, NULL);
       
   994 
       
   995     cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
       
   996     if(cipherDataNode == NULL) {
       
   997 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   998 		    NULL,
       
   999 		    xmlSecErrorsSafeString(xmlSecNodeCipherData),
       
  1000 		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
  1001 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1002 	return(NULL);	
       
  1003     }
       
  1004 
       
  1005     /* check that we don;t have CipherReference node */
       
  1006     tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
       
  1007     if(tmp != NULL) {
       
  1008 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1009 		    NULL,
       
  1010 		    xmlSecErrorsSafeString(xmlSecNodeCipherReference),
       
  1011 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1012 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1013 	return(NULL);	
       
  1014     }
       
  1015 
       
  1016     res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
       
  1017     if(res == NULL) {
       
  1018 	res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
       
  1019 	if(res == NULL) {
       
  1020 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1021 			NULL,
       
  1022 			"xmlSecAddChild",
       
  1023 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1024 			"node=%s",
       
  1025 			xmlSecErrorsSafeString(xmlSecNodeCipherValue));
       
  1026 	    return(NULL);	        	
       
  1027 	}
       
  1028     }
       
  1029         
       
  1030     return(res);
       
  1031 }
       
  1032 
       
  1033 /** 
       
  1034  * xmlSecTmplEncDataEnsureCipherReference:
       
  1035  * @encNode: 		the pointer to <enc:EncryptedData/> node.
       
  1036  * @uri: 		the URI attribute (may be NULL).
       
  1037  *
       
  1038  * Adds <enc:CipherReference/> node with specified URI attribute @uri
       
  1039  * to the <enc:EncryptedData/> node @encNode.
       
  1040  *
       
  1041  * Returns the pointer to newly created <enc:CipherReference/> node or 
       
  1042  * NULL if an error occurs.
       
  1043  */
       
  1044 EXPORT_C
       
  1045 xmlNodePtr
       
  1046 xmlSecTmplEncDataEnsureCipherReference(xmlNodePtr encNode, const xmlChar *uri) {
       
  1047     xmlNodePtr cipherDataNode;
       
  1048     xmlNodePtr res, tmp;
       
  1049     int created = 1;
       
  1050         
       
  1051     xmlSecAssert2(encNode != NULL, NULL);
       
  1052 
       
  1053     cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
       
  1054     if(cipherDataNode == NULL) {
       
  1055 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1056 		    NULL,
       
  1057 		    xmlSecErrorsSafeString(xmlSecNodeCipherData),
       
  1058 		    XMLSEC_ERRORS_R_NODE_NOT_FOUND,
       
  1059 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1060 	return(NULL);	
       
  1061     }
       
  1062 
       
  1063     /* check that we don;t have CipherValue node */
       
  1064     tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
       
  1065     if(tmp != NULL) {
       
  1066 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1067 		    NULL,
       
  1068 		    xmlSecErrorsSafeString(xmlSecNodeCipherValue),
       
  1069 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1070 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1071 	return(NULL);	
       
  1072     }
       
  1073 
       
  1074     res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
       
  1075     if(res == NULL) {
       
  1076 	res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
       
  1077 	if(res == NULL) {
       
  1078 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1079 			NULL,
       
  1080 			"xmlSecAddChild",
       
  1081 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1082 			"node=%s",
       
  1083 			xmlSecErrorsSafeString(xmlSecNodeCipherReference));
       
  1084 	    return(NULL);	        	
       
  1085 	}
       
  1086 	created = 1;
       
  1087     }
       
  1088     
       
  1089     if(uri != NULL) {
       
  1090 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrURI, uri);
       
  1091         if (!ptr && OOM_FLAG) 
       
  1092             {
       
  1093             if (created) 
       
  1094                 {
       
  1095                 xmlUnlinkNode(res);
       
  1096         	    xmlFreeNode(res);
       
  1097                 }
       
  1098             return(NULL);
       
  1099             }
       
  1100     }
       
  1101     
       
  1102     return(res);
       
  1103 }
       
  1104 
       
  1105 /** 
       
  1106  * xmlSecTmplEncDataGetEncMethodNode:
       
  1107  * @encNode:		the pointer to <enc:EcnryptedData /> node.
       
  1108  *
       
  1109  * Gets pointer to <enc:EncrytpionMethod/> node.
       
  1110  *
       
  1111  * Returns pointer to <enc:EncryptionMethod /> node or NULL if an error occurs.
       
  1112  */
       
  1113 EXPORT_C
       
  1114 xmlNodePtr 
       
  1115 xmlSecTmplEncDataGetEncMethodNode(xmlNodePtr encNode) {
       
  1116     xmlSecAssert2(encNode != NULL, NULL);
       
  1117 
       
  1118     return(xmlSecFindChild(encNode, xmlSecNodeEncryptionMethod, xmlSecEncNs));
       
  1119 }
       
  1120 
       
  1121 /** 
       
  1122  * xmlSecTmplCipherReferenceAddTransform:
       
  1123  * @cipherReferenceNode: 	the pointer to <enc:CipherReference/> node.
       
  1124  * @transformId: 		the transform id.
       
  1125  *
       
  1126  * Adds <dsig:Transform/> node (and the parent <dsig:Transforms/> node)
       
  1127  * with specified transform methods @transform to the <enc:CipherReference/>
       
  1128  * child node of the <enc:EncryptedData/> node @encNode.
       
  1129  *
       
  1130  * Returns the pointer to newly created <dsig:Transform/> node or 
       
  1131  * NULL if an error occurs.
       
  1132  */
       
  1133 EXPORT_C
       
  1134 xmlNodePtr
       
  1135 xmlSecTmplCipherReferenceAddTransform(xmlNodePtr cipherReferenceNode, 
       
  1136 				  xmlSecTransformId transformId) {
       
  1137     xmlNodePtr transformsNode;
       
  1138     xmlNodePtr res;
       
  1139 
       
  1140     xmlSecAssert2(cipherReferenceNode != NULL, NULL);
       
  1141     xmlSecAssert2(transformId != NULL, NULL);    
       
  1142     xmlSecAssert2(transformId->href != NULL, NULL);    
       
  1143 
       
  1144     transformsNode = xmlSecFindChild(cipherReferenceNode, xmlSecNodeTransforms, xmlSecEncNs);
       
  1145     if(transformsNode == NULL) {
       
  1146 	transformsNode = xmlSecAddChild(cipherReferenceNode, xmlSecNodeTransforms, xmlSecEncNs);
       
  1147 	if(transformsNode == NULL) {
       
  1148 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1149 			NULL,
       
  1150 			"xmlSecAddChild",
       
  1151 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1152 			"node=%s",
       
  1153 			xmlSecErrorsSafeString(xmlSecNodeTransforms));
       
  1154 	    return(NULL);	
       
  1155 	}
       
  1156     }
       
  1157     
       
  1158     res = xmlSecAddChild(transformsNode,  xmlSecNodeTransform, xmlSecDSigNs);
       
  1159     if(res == NULL) {
       
  1160 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1161 		    NULL,
       
  1162 		    "xmlSecAddChild",
       
  1163 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1164 		    "node=%s",
       
  1165 		    xmlSecErrorsSafeString(xmlSecNodeTransform));
       
  1166 	return(NULL);	
       
  1167     }
       
  1168     
       
  1169     if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
       
  1170 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1171 		    NULL,
       
  1172 		    "xmlSetProp",
       
  1173 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1174 		    "name=%s,value=%s",
       
  1175 		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
  1176 		    xmlSecErrorsSafeString(transformId->href));
       
  1177 	xmlUnlinkNode(res);
       
  1178 	xmlFreeNode(res);
       
  1179 	return(NULL);	        	
       
  1180     }
       
  1181     
       
  1182     return(res);
       
  1183 }
       
  1184 
       
  1185 
       
  1186 /***********************************************************************
       
  1187  *
       
  1188  * <enc:EncryptedKey> node
       
  1189  *
       
  1190  **********************************************************************/ 
       
  1191 
       
  1192 /** 
       
  1193  * xmlSecTmplReferenceListAddDataReference:
       
  1194  * @encNode: 	                the pointer to <enc:EncryptedKey/> node.
       
  1195  * @uri:                        uri to reference (optional)
       
  1196  *
       
  1197  * Adds <enc:DataReference/> and the parent <enc:ReferenceList/> node (if needed).
       
  1198  *
       
  1199  * Returns the pointer to newly created <enc:DataReference/> node or 
       
  1200  * NULL if an error occurs.
       
  1201  */
       
  1202 EXPORT_C
       
  1203 xmlNodePtr
       
  1204 xmlSecTmplReferenceListAddDataReference(xmlNodePtr encNode, const xmlChar *uri) {
       
  1205     xmlNodePtr refListNode, res;
       
  1206 
       
  1207     xmlSecAssert2(encNode != NULL, NULL);
       
  1208     
       
  1209     refListNode = xmlSecFindChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
       
  1210     if(refListNode == NULL) {
       
  1211 	refListNode = xmlSecAddChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
       
  1212 	if(refListNode == NULL) {
       
  1213 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1214 			NULL,
       
  1215 			"xmlSecAddChild",
       
  1216 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1217 			"node=%s",
       
  1218 			xmlSecErrorsSafeString(xmlSecNodeReferenceList));
       
  1219 	    return(NULL);	
       
  1220 	}
       
  1221     }
       
  1222     
       
  1223     res = xmlSecAddChild(refListNode,  xmlSecNodeDataReference, xmlSecEncNs);
       
  1224     if(res == NULL) {
       
  1225 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1226 		    NULL,
       
  1227 		    "xmlSecAddChild",
       
  1228 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1229 		    "node=%s",
       
  1230 		    xmlSecErrorsSafeString(xmlSecNodeDataReference));
       
  1231 	return(NULL);	
       
  1232     }
       
  1233  
       
  1234     if(uri != NULL) {
       
  1235         if(xmlSetProp(res, xmlSecAttrURI, uri) == NULL) {
       
  1236 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1237 		        NULL,
       
  1238 		        "xmlSetProp",
       
  1239 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1240 		        "name=%s,value=%s",
       
  1241 		        xmlSecErrorsSafeString(xmlSecAttrURI),
       
  1242 		        xmlSecErrorsSafeString(uri));
       
  1243 	    xmlUnlinkNode(res);
       
  1244 	    xmlFreeNode(res);
       
  1245 	    return(NULL);	        	
       
  1246         }
       
  1247     }
       
  1248 
       
  1249     return(res);
       
  1250 }
       
  1251 
       
  1252 /** 
       
  1253  * xmlSecTmplReferenceListAddKeyReference:
       
  1254  * @encNode: 	                the pointer to <enc:EncryptedKey/> node.
       
  1255  * @uri:                        uri to reference (optional)
       
  1256  *
       
  1257  * Adds <enc:KeyReference/> and the parent <enc:ReferenceList/> node (if needed).
       
  1258  *
       
  1259  * Returns the pointer to newly created <enc:KeyReference/> node or 
       
  1260  * NULL if an error occurs.
       
  1261  */
       
  1262 EXPORT_C
       
  1263 xmlNodePtr
       
  1264 xmlSecTmplReferenceListAddKeyReference(xmlNodePtr encNode, const xmlChar *uri) {
       
  1265     xmlNodePtr refListNode, res;
       
  1266 
       
  1267     xmlSecAssert2(encNode != NULL, NULL);
       
  1268     
       
  1269     refListNode = xmlSecFindChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
       
  1270     if(refListNode == NULL) {
       
  1271 	refListNode = xmlSecAddChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
       
  1272 	if(refListNode == NULL) {
       
  1273 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1274 			NULL,
       
  1275 			"xmlSecAddChild",
       
  1276 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1277 			"node=%s",
       
  1278 			xmlSecErrorsSafeString(xmlSecNodeReferenceList));
       
  1279 	    return(NULL);	
       
  1280 	}
       
  1281     }
       
  1282     
       
  1283     res = xmlSecAddChild(refListNode,  xmlSecNodeKeyReference, xmlSecEncNs);
       
  1284     if(res == NULL) {
       
  1285 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1286 		    NULL,
       
  1287 		    "xmlSecAddChild",
       
  1288 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1289 		    "node=%s",
       
  1290 		    xmlSecErrorsSafeString(xmlSecNodeKeyReference));
       
  1291 	return(NULL);	
       
  1292     }
       
  1293  
       
  1294     if(uri != NULL) {
       
  1295         if(xmlSetProp(res, xmlSecAttrURI, uri) == NULL) {
       
  1296 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1297 		        NULL,
       
  1298 		        "xmlSetProp",
       
  1299 		        XMLSEC_ERRORS_R_XML_FAILED,
       
  1300 		        "name=%s,value=%s",
       
  1301 		        xmlSecErrorsSafeString(xmlSecAttrURI),
       
  1302 		        xmlSecErrorsSafeString(uri));
       
  1303 	    xmlUnlinkNode(res);
       
  1304 	    xmlFreeNode(res);
       
  1305 	    return(NULL);	        	
       
  1306         }
       
  1307     }
       
  1308 
       
  1309     return(res);
       
  1310 }
       
  1311 
       
  1312 
       
  1313 /**************************************************************************
       
  1314  *
       
  1315  * <dsig:KeyInfo/> node
       
  1316  *
       
  1317  **************************************************************************/
       
  1318 
       
  1319 /**
       
  1320  * xmlSecTmplKeyInfoAddKeyName:
       
  1321  * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
       
  1322  * @name:		the key name (optional).	
       
  1323  *
       
  1324  * Adds <dsig:KeyName/> node to the <dsig:KeyInfo/> node @keyInfoNode.
       
  1325  *
       
  1326  * Returns the pointer to the newly created <dsig:KeyName/> node or
       
  1327  * NULL if an error occurs.
       
  1328  */
       
  1329 EXPORT_C
       
  1330 xmlNodePtr	
       
  1331 xmlSecTmplKeyInfoAddKeyName(xmlNodePtr keyInfoNode, const xmlChar* name) {
       
  1332     xmlNodePtr res;
       
  1333 
       
  1334     xmlSecAssert2(keyInfoNode != NULL, NULL);
       
  1335         
       
  1336     res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyName, xmlSecDSigNs); 
       
  1337     if(res == NULL) {
       
  1338 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1339 		    NULL,
       
  1340 		    "xmlSecAddChild",
       
  1341 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1342 		    "node=%s",
       
  1343 		    xmlSecErrorsSafeString(xmlSecNodeKeyName));
       
  1344 	return(NULL);	
       
  1345     }
       
  1346     if(name != NULL) {
       
  1347 	xmlNodeSetContent(res, name);
       
  1348     if ( OOM_FLAG ) 
       
  1349         {
       
  1350         xmlUnlinkNode(res);
       
  1351 	    xmlFreeNode(res);        
       
  1352         return(NULL);
       
  1353         }
       
  1354     }
       
  1355     return(res);
       
  1356 }
       
  1357 
       
  1358 /**
       
  1359  * xmlSecTmplKeyInfoAddKeyValue:
       
  1360  * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
       
  1361  *
       
  1362  * Adds <dsig:KeyValue/> node to the <dsig:KeyInfo/> node @keyInfoNode.
       
  1363  *
       
  1364  * Returns the pointer to the newly created <dsig:KeyValue/> node or
       
  1365  * NULL if an error occurs.
       
  1366  */
       
  1367 EXPORT_C
       
  1368 xmlNodePtr
       
  1369 xmlSecTmplKeyInfoAddKeyValue(xmlNodePtr keyInfoNode) {
       
  1370     xmlNodePtr res;
       
  1371 
       
  1372     xmlSecAssert2(keyInfoNode != NULL, NULL);
       
  1373         
       
  1374     res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyValue, xmlSecDSigNs); 
       
  1375     if(res == NULL) {
       
  1376 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1377 		    NULL,
       
  1378 		    "xmlSecAddChild",
       
  1379 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1380 		    "node=%s",
       
  1381 		    xmlSecErrorsSafeString(xmlSecNodeKeyValue));
       
  1382 	return(NULL);	
       
  1383     }
       
  1384     
       
  1385     return(res);
       
  1386 }
       
  1387 
       
  1388 /**
       
  1389  * xmlSecTmplKeyInfoAddX509Data:
       
  1390  * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
       
  1391  *
       
  1392  * Adds <dsig:X509Data/> node to the <dsig:KeyInfo/> node @keyInfoNode.
       
  1393  *
       
  1394  * Returns the pointer to the newly created <dsig:X509Data/> node or
       
  1395  * NULL if an error occurs.
       
  1396  */
       
  1397 EXPORT_C
       
  1398 xmlNodePtr
       
  1399 xmlSecTmplKeyInfoAddX509Data(xmlNodePtr keyInfoNode) {
       
  1400     xmlNodePtr res;
       
  1401 
       
  1402     xmlSecAssert2(keyInfoNode != NULL, NULL);
       
  1403         
       
  1404     res = xmlSecAddChild(keyInfoNode, xmlSecNodeX509Data, xmlSecDSigNs); 
       
  1405     if(res == NULL) {
       
  1406 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1407 		    NULL,
       
  1408 		    "xmlSecAddChild",
       
  1409 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1410 		    "node=%s",
       
  1411 		    xmlSecErrorsSafeString(xmlSecNodeX509Data));
       
  1412 	return(NULL);	
       
  1413     }
       
  1414     
       
  1415     return(res);
       
  1416 }
       
  1417 
       
  1418 /**
       
  1419  * xmlSecTmplKeyInfoAddRetrievalMethod:
       
  1420  * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
       
  1421  * @uri: 		the URI attribute (optional).
       
  1422  * @type: 		the Type attribute(optional).
       
  1423  *
       
  1424  * Adds <dsig:RetrievalMethod/> node to the <dsig:KeyInfo/> node @keyInfoNode.
       
  1425  *
       
  1426  * Returns the pointer to the newly created <dsig:RetrievalMethod/> node or
       
  1427  * NULL if an error occurs.
       
  1428  */
       
  1429 EXPORT_C
       
  1430 xmlNodePtr
       
  1431 xmlSecTmplKeyInfoAddRetrievalMethod(xmlNodePtr keyInfoNode, const xmlChar *uri,
       
  1432 			     const xmlChar *type) {
       
  1433     xmlNodePtr res;
       
  1434     int error = 0;
       
  1435 
       
  1436     xmlSecAssert2(keyInfoNode != NULL, NULL);
       
  1437         
       
  1438     res = xmlSecAddChild(keyInfoNode, xmlSecNodeRetrievalMethod, xmlSecDSigNs); 
       
  1439     if(res == NULL) {
       
  1440 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1441 		    NULL,
       
  1442 		    "xmlSecAddChild",
       
  1443 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1444 		    "node=%s",
       
  1445 		    xmlSecErrorsSafeString(xmlSecNodeRetrievalMethod));
       
  1446 	return(NULL);	
       
  1447     }
       
  1448     
       
  1449     if(uri != NULL) {
       
  1450 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrURI, uri);
       
  1451     error = error || !ptr;
       
  1452     }
       
  1453     if(type != NULL) {
       
  1454 	xmlAttrPtr ptr = xmlSetProp(res, xmlSecAttrType, type);
       
  1455     error = error || !ptr;
       
  1456     }
       
  1457     if (error && OOM_FLAG) 
       
  1458         {
       
  1459         xmlUnlinkNode(res);
       
  1460 	    xmlFreeNode(res);
       
  1461 	    return(NULL);
       
  1462         }
       
  1463     return(res);
       
  1464 }
       
  1465 
       
  1466 /**
       
  1467  * xmlSecTmplRetrievalMethodAddTransform:
       
  1468  * @retrMethodNode: 	the pointer to <dsig:RetrievalMethod/> node.
       
  1469  * @transformId: 	the transform id.
       
  1470  * 
       
  1471  * Adds <dsig:Transform/> node (and the parent <dsig:Transforms/> node
       
  1472  * if required) to the <dsig:RetrievalMethod/> node @retrMethod.
       
  1473  *
       
  1474  * Returns the pointer to the newly created <dsig:Transforms/> node or
       
  1475  * NULL if an error occurs.
       
  1476  */
       
  1477 EXPORT_C
       
  1478 xmlNodePtr
       
  1479 xmlSecTmplRetrievalMethodAddTransform(xmlNodePtr retrMethodNode, xmlSecTransformId transformId) {
       
  1480     xmlNodePtr transformsNode;
       
  1481     xmlNodePtr res;
       
  1482 
       
  1483     xmlSecAssert2(retrMethodNode != NULL, NULL);
       
  1484     xmlSecAssert2(transformId != NULL, NULL);    
       
  1485     xmlSecAssert2(transformId->href != NULL, NULL);    
       
  1486 
       
  1487     transformsNode = xmlSecFindChild(retrMethodNode, xmlSecNodeTransforms, xmlSecDSigNs);
       
  1488     if(transformsNode == NULL) {
       
  1489 	transformsNode = xmlSecAddChild(retrMethodNode, xmlSecNodeTransforms, xmlSecDSigNs);
       
  1490 	if(transformsNode == NULL) {
       
  1491 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1492 			NULL,
       
  1493 			"xmlSecAddChild",
       
  1494 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1495 			"node=%s",
       
  1496 			xmlSecErrorsSafeString(xmlSecNodeTransforms));
       
  1497 	    return(NULL);	
       
  1498 	}
       
  1499     }
       
  1500     
       
  1501     res = xmlSecAddChild(transformsNode,  xmlSecNodeTransform, xmlSecDSigNs);
       
  1502     if(res == NULL) {
       
  1503 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1504 		    NULL,
       
  1505 		    "xmlSecAddChild",
       
  1506 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1507 		    "node=%s",
       
  1508 		    xmlSecErrorsSafeString(xmlSecNodeTransform));
       
  1509 	return(NULL);	
       
  1510     }
       
  1511     
       
  1512     if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
       
  1513 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1514 		    NULL,
       
  1515 		    "xmlSetProp",
       
  1516 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1517 		    "name=%s,value=%s",
       
  1518 		    xmlSecErrorsSafeString(xmlSecAttrAlgorithm),
       
  1519 		    xmlSecErrorsSafeString(transformId->href));
       
  1520 	xmlUnlinkNode(res);
       
  1521 	xmlFreeNode(res);
       
  1522 	return(NULL);	        	
       
  1523     }
       
  1524     
       
  1525     return(res);
       
  1526 }
       
  1527 
       
  1528 
       
  1529 /**
       
  1530  * xmlSecTmplKeyInfoAddEncryptedKey:
       
  1531  * @keyInfoNode: 	the pointer to <dsig:KeyInfo/> node.
       
  1532  * @encMethodId:	the encryption method (optional).
       
  1533  * @id: 		the Id attribute (optional).
       
  1534  * @type: 		the Type attribute (optional). 
       
  1535  * @recipient: 		the Recipient attribute (optional). 
       
  1536  *
       
  1537  * Adds <enc:EncryptedKey/> node with given attributes to 
       
  1538  * the <dsig:KeyInfo/> node @keyInfoNode.
       
  1539  *
       
  1540  * Returns the pointer to the newly created <enc:EncryptedKey/> node or
       
  1541  * NULL if an error occurs.
       
  1542  */
       
  1543 EXPORT_C
       
  1544 xmlNodePtr 
       
  1545 xmlSecTmplKeyInfoAddEncryptedKey(xmlNodePtr keyInfoNode, xmlSecTransformId encMethodId,
       
  1546 			 const xmlChar* id, const xmlChar* type, const xmlChar* recipient) {
       
  1547     xmlNodePtr encKeyNode;
       
  1548     int error = 0;
       
  1549 
       
  1550     xmlSecAssert2(keyInfoNode != NULL, NULL);
       
  1551 
       
  1552     /* we allow multiple encrypted key elements */
       
  1553     encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, xmlSecEncNs); 
       
  1554     if(encKeyNode == NULL) {
       
  1555 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1556 		    NULL,
       
  1557 		    "xmlSecAddChild",
       
  1558 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1559 		    "node=%s", 
       
  1560 		    xmlSecErrorsSafeString(xmlSecNodeEncryptedKey));
       
  1561 	return(NULL);	
       
  1562     }
       
  1563     
       
  1564     if(id != NULL) {
       
  1565 	xmlAttrPtr ptr = xmlSetProp(encKeyNode, xmlSecAttrId, id);
       
  1566     error = error || !ptr;
       
  1567     }
       
  1568     if(type != NULL) {
       
  1569 	xmlAttrPtr ptr = xmlSetProp(encKeyNode, xmlSecAttrType, type);
       
  1570     error = error || !ptr;
       
  1571     }
       
  1572     if(recipient != NULL) {
       
  1573 	xmlAttrPtr ptr = xmlSetProp(encKeyNode, xmlSecAttrRecipient, recipient);
       
  1574     error = error || !ptr;
       
  1575     }
       
  1576     if (error && OOM_FLAG) 
       
  1577         {
       
  1578         xmlUnlinkNode(encKeyNode);
       
  1579 	    xmlFreeNode(encKeyNode);
       
  1580 	    return(NULL);
       
  1581         }
       
  1582 
       
  1583     if(xmlSecTmplPrepareEncData(encKeyNode, encMethodId) < 0) {
       
  1584 	xmlUnlinkNode(encKeyNode);
       
  1585 	xmlFreeNode(encKeyNode);
       
  1586 	return(NULL);	        	
       
  1587     }    
       
  1588     return(encKeyNode);    
       
  1589 }
       
  1590 
       
  1591 /***********************************************************************
       
  1592  *
       
  1593  * <dsig:X509Data> node
       
  1594  *
       
  1595  **********************************************************************/ 
       
  1596 /**
       
  1597  * xmlSecTmplX509DataAddIssuerSerial:
       
  1598  * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
       
  1599  * 
       
  1600  * Adds <dsig:X509IssuerSerial/> node to the given <dsig:X509Data/> node.
       
  1601  *
       
  1602  * Returns the pointer to the newly created <dsig:X509IssuerSerial/> node or
       
  1603  * NULL if an error occurs.
       
  1604  */
       
  1605 EXPORT_C
       
  1606 
       
  1607 xmlNodePtr 
       
  1608 xmlSecTmplX509DataAddIssuerSerial(xmlNodePtr x509DataNode) {
       
  1609     xmlNodePtr cur;
       
  1610 
       
  1611     xmlSecAssert2(x509DataNode != NULL, NULL);
       
  1612 
       
  1613     cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
       
  1614     if(cur != NULL) {
       
  1615 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1616 		    NULL,
       
  1617 		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial),
       
  1618 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1619 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1620 	return(NULL);
       
  1621     }
       
  1622     
       
  1623     cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
       
  1624     if(cur == NULL) {
       
  1625 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1626 		    NULL,
       
  1627 		    "xmlSecAddChild",
       
  1628 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1629 		    "node=%s", 
       
  1630 		    xmlSecErrorsSafeString(xmlSecNodeX509IssuerSerial));
       
  1631 	return(NULL);
       
  1632     }    
       
  1633     
       
  1634     return (cur);
       
  1635 }
       
  1636 
       
  1637 /**
       
  1638  * xmlSecTmplX509DataAddSubjectName:
       
  1639  * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
       
  1640  * 
       
  1641  * Adds <dsig:X509SubjectName/> node to the given <dsig:X509Data/> node.
       
  1642  *
       
  1643  * Returns the pointer to the newly created <dsig:X509SubjectName/> node or
       
  1644  * NULL if an error occurs.
       
  1645  */
       
  1646 EXPORT_C
       
  1647 
       
  1648 xmlNodePtr 
       
  1649 xmlSecTmplX509DataAddSubjectName(xmlNodePtr x509DataNode) {
       
  1650     xmlNodePtr cur;
       
  1651 
       
  1652     xmlSecAssert2(x509DataNode != NULL, NULL);
       
  1653 
       
  1654     cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509SubjectName, xmlSecDSigNs);
       
  1655     if(cur != NULL) {
       
  1656 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1657 		    NULL,
       
  1658 		    xmlSecErrorsSafeString(xmlSecNodeX509SubjectName),
       
  1659 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1660 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1661 	return(NULL);
       
  1662     }
       
  1663     
       
  1664     cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509SubjectName, xmlSecDSigNs);
       
  1665     if(cur == NULL) {
       
  1666 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1667 		    NULL,
       
  1668 		    "xmlSecAddChild",
       
  1669 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1670 		    "node=%s", 
       
  1671 		    xmlSecErrorsSafeString(xmlSecNodeX509SubjectName));
       
  1672 	return(NULL);
       
  1673     }    
       
  1674     
       
  1675     return (cur);
       
  1676 }
       
  1677 
       
  1678 /**
       
  1679  * xmlSecTmplX509DataAddSKI:
       
  1680  * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
       
  1681  * 
       
  1682  * Adds <dsig:X509SKI/> node to the given <dsig:X509Data/> node.
       
  1683  *
       
  1684  * Returns the pointer to the newly created <dsig:X509SKI/> node or
       
  1685  * NULL if an error occurs.
       
  1686  */
       
  1687 EXPORT_C
       
  1688 
       
  1689 xmlNodePtr 
       
  1690 xmlSecTmplX509DataAddSKI(xmlNodePtr x509DataNode) {
       
  1691     xmlNodePtr cur;
       
  1692 
       
  1693     xmlSecAssert2(x509DataNode != NULL, NULL);
       
  1694 
       
  1695     cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509SKI, xmlSecDSigNs);
       
  1696     if(cur != NULL) {
       
  1697 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1698 		    NULL,
       
  1699 		    xmlSecErrorsSafeString(xmlSecNodeX509SKI),
       
  1700 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1701 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1702 	return(NULL);
       
  1703     }
       
  1704     
       
  1705     cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509SKI, xmlSecDSigNs);
       
  1706     if(cur == NULL) {
       
  1707 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1708 		    NULL,
       
  1709 		    "xmlSecAddChild",
       
  1710 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1711 		    "node=%s", 
       
  1712 		    xmlSecErrorsSafeString(xmlSecNodeX509SKI));
       
  1713 	return(NULL);
       
  1714     }    
       
  1715     
       
  1716     return (cur);
       
  1717 }
       
  1718 
       
  1719 
       
  1720 /**
       
  1721  * xmlSecTmplX509DataAddCertificate:
       
  1722  * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
       
  1723  * 
       
  1724  * Adds <dsig:X509Certificate/> node to the given <dsig:X509Data/> node.
       
  1725  *
       
  1726  * Returns the pointer to the newly created <dsig:X509Certificate/> node or
       
  1727  * NULL if an error occurs.
       
  1728  */
       
  1729 EXPORT_C
       
  1730 
       
  1731 xmlNodePtr 
       
  1732 xmlSecTmplX509DataAddCertificate(xmlNodePtr x509DataNode) {
       
  1733     xmlNodePtr cur;
       
  1734 
       
  1735     xmlSecAssert2(x509DataNode != NULL, NULL);
       
  1736 
       
  1737     cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
       
  1738     if(cur != NULL) {
       
  1739 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1740 		    NULL,
       
  1741 		    xmlSecErrorsSafeString(xmlSecNodeX509Certificate),
       
  1742 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1743 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1744 	return(NULL);
       
  1745     }
       
  1746     
       
  1747     cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
       
  1748     if(cur == NULL) {
       
  1749 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1750 		    NULL,
       
  1751 		    "xmlSecAddChild",
       
  1752 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1753 		    "node=%s", 
       
  1754 		    xmlSecErrorsSafeString(xmlSecNodeX509Certificate));
       
  1755 	return(NULL);
       
  1756     }    
       
  1757     
       
  1758     return (cur);
       
  1759 }
       
  1760 
       
  1761 /**
       
  1762  * xmlSecTmplX509DataAddCRL:
       
  1763  * @x509DataNode: 	the pointer to <dsig:X509Data/> node.
       
  1764  * 
       
  1765  * Adds <dsig:X509CRL/> node to the given <dsig:X509Data/> node.
       
  1766  *
       
  1767  * Returns the pointer to the newly created <dsig:X509CRL/> node or
       
  1768  * NULL if an error occurs.
       
  1769  */
       
  1770 EXPORT_C
       
  1771 
       
  1772 xmlNodePtr 
       
  1773 xmlSecTmplX509DataAddCRL(xmlNodePtr x509DataNode) {
       
  1774     xmlNodePtr cur;
       
  1775 
       
  1776     xmlSecAssert2(x509DataNode != NULL, NULL);
       
  1777 
       
  1778     cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509CRL, xmlSecDSigNs);
       
  1779     if(cur != NULL) {
       
  1780 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1781 		    NULL,
       
  1782 		    xmlSecErrorsSafeString(xmlSecNodeX509CRL),
       
  1783 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1784 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1785 	return(NULL);
       
  1786     }
       
  1787     
       
  1788     cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509CRL, xmlSecDSigNs);
       
  1789     if(cur == NULL) {
       
  1790 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1791 		    NULL,
       
  1792 		    "xmlSecAddChild",
       
  1793 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1794 		    "node=%s", 
       
  1795 		    xmlSecErrorsSafeString(xmlSecNodeX509CRL));
       
  1796 	return(NULL);
       
  1797     }    
       
  1798     
       
  1799     return (cur);
       
  1800 }
       
  1801 
       
  1802 /*************************************************************************
       
  1803  *
       
  1804  * <dsig:Transform/> node
       
  1805  *
       
  1806  ************************************************************************/
       
  1807 
       
  1808 /**
       
  1809  * xmlSecTmplTransformAddHmacOutputLength:
       
  1810  * @transformNode: 	the pointer to <dsig:Transform/> node
       
  1811  * @bitsLen: 		the required length in bits
       
  1812  *
       
  1813  * Creates <dsig:HMACOutputLength/> child for the HMAC transform 
       
  1814  * node @node.
       
  1815  *
       
  1816  * Returns 0 on success and a negatie value otherwise.
       
  1817  */
       
  1818 EXPORT_C
       
  1819 int
       
  1820 xmlSecTmplTransformAddHmacOutputLength(xmlNodePtr transformNode, xmlSecSize bitsLen) {
       
  1821     xmlNodePtr cur;
       
  1822     char buf[32];
       
  1823 
       
  1824     xmlSecAssert2(transformNode != NULL, -1);
       
  1825     xmlSecAssert2(bitsLen > 0, -1);
       
  1826 
       
  1827     cur = xmlSecFindChild(transformNode, xmlSecNodeHMACOutputLength, xmlSecDSigNs);
       
  1828     if(cur != NULL) {
       
  1829 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1830 		    NULL,
       
  1831 		    xmlSecErrorsSafeString(xmlSecNodeHMACOutputLength),
       
  1832 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1833 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1834 	return(-1);
       
  1835     }
       
  1836     
       
  1837     cur = xmlSecAddChild(transformNode, xmlSecNodeHMACOutputLength, xmlSecDSigNs);
       
  1838     if(cur == NULL) {
       
  1839 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1840 		    NULL,
       
  1841 		    "xmlSecAddChild",
       
  1842 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1843 		    "node=%s", 
       
  1844 		    xmlSecErrorsSafeString(xmlSecNodeHMACOutputLength));
       
  1845 	return(-1);
       
  1846     }    
       
  1847     
       
  1848     sprintf(buf, "%u", bitsLen);
       
  1849     xmlNodeSetContent(cur, BAD_CAST buf);
       
  1850     return(0);
       
  1851 }
       
  1852 
       
  1853 /**
       
  1854  * xmlSecTmplTransformAddRsaOaepParam:
       
  1855  * @transformNode: 	the pointer to <dsig:Transform/> node.
       
  1856  * @buf: 		the OAEP param buffer.
       
  1857  * @size: 		the OAEP param buffer size.
       
  1858  * 
       
  1859  * Creates <enc:OAEPParam/> child node in the @node.
       
  1860  *
       
  1861  * Returns 0 on success or a negative value if an error occurs.
       
  1862  */
       
  1863 EXPORT_C
       
  1864 int  	
       
  1865 xmlSecTmplTransformAddRsaOaepParam(xmlNodePtr transformNode, 
       
  1866 			const xmlSecByte *buf, xmlSecSize size) {
       
  1867     xmlNodePtr oaepParamNode;
       
  1868     xmlChar *base64;
       
  1869 
       
  1870     xmlSecAssert2(transformNode != NULL, -1);
       
  1871     xmlSecAssert2(buf != NULL, -1);
       
  1872     xmlSecAssert2(size > 0, -1);
       
  1873 
       
  1874     oaepParamNode = xmlSecFindChild(transformNode, xmlSecNodeRsaOAEPparams, xmlSecEncNs);
       
  1875     if(oaepParamNode != NULL) {
       
  1876 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1877 		    NULL,
       
  1878 		    xmlSecErrorsSafeString(xmlSecNodeRsaOAEPparams),
       
  1879 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1880 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1881 	return(-1);    
       
  1882     }
       
  1883 
       
  1884     oaepParamNode = xmlSecAddChild(transformNode, xmlSecNodeRsaOAEPparams, xmlSecEncNs);
       
  1885     if(oaepParamNode == NULL) {
       
  1886 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1887 		    NULL,
       
  1888 		    "xmlSecAddChild",
       
  1889 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1890 		    "node=%s", 
       
  1891 		    xmlSecErrorsSafeString(xmlSecNodeRsaOAEPparams));
       
  1892 	return(-1);    
       
  1893     }
       
  1894     
       
  1895     base64 = xmlSecBase64Encode(buf, size, 0);
       
  1896     if(base64 == NULL) {
       
  1897 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1898 		    NULL,
       
  1899 		    "xmlSecBase64Encode",
       
  1900 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1901 		    "size=%d", size);
       
  1902 	return(-1);    
       
  1903     }
       
  1904     
       
  1905     xmlNodeSetContent(oaepParamNode, base64);
       
  1906     xmlFree(base64);
       
  1907     return(0);
       
  1908 }
       
  1909 
       
  1910 /**
       
  1911  * xmlSecTmplTransformAddXsltStylesheet:
       
  1912  * @transformNode: 	the pointer to <dsig:Transform/> node.
       
  1913  * @xslt: 		the XSLT transform exspression.
       
  1914  * 
       
  1915  * Writes the XSLT transform expression to the @node.
       
  1916  *
       
  1917  * Returns 0 on success or a negative value otherwise.
       
  1918  */
       
  1919 EXPORT_C
       
  1920 int
       
  1921 xmlSecTmplTransformAddXsltStylesheet(xmlNodePtr transformNode, const xmlChar *xslt) {
       
  1922     xmlDocPtr xsltDoc;
       
  1923     int ret;
       
  1924         
       
  1925     xmlSecAssert2(transformNode != NULL, -1);    
       
  1926     xmlSecAssert2(xslt != NULL, -1);    
       
  1927     
       
  1928     xsltDoc = xmlParseMemory((const char*)xslt, xmlStrlen(xslt));
       
  1929     if(xsltDoc == NULL) {
       
  1930 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1931 		    NULL,
       
  1932 		    "xmlParseMemory",
       
  1933 		    XMLSEC_ERRORS_R_XML_FAILED,
       
  1934 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1935 	return(-1);
       
  1936     }
       
  1937     
       
  1938     ret = xmlSecReplaceContent(transformNode, xmlDocGetRootElement(xsltDoc));
       
  1939     if(ret < 0) {
       
  1940 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1941 		    NULL,
       
  1942 		    "xmlSecReplaceContent",
       
  1943 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1944 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1945 	xmlFreeDoc(xsltDoc);
       
  1946 	return(-1);
       
  1947     }
       
  1948     
       
  1949     xmlFreeDoc(xsltDoc);
       
  1950     return(0);
       
  1951 }
       
  1952 
       
  1953 /**
       
  1954  * xmlSecTmplTransformAddC14NInclNamespaces:
       
  1955  * @transformNode: 	the pointer to <dsig:Transform/> node.
       
  1956  * @prefixList: 	the white space delimited  list of namespace prefixes, 
       
  1957  *			where "#default" indicates the default namespace
       
  1958  *			(optional).
       
  1959  *
       
  1960  * Adds "inclusive" namespaces to the ExcC14N transform node @node.
       
  1961  *
       
  1962  * Returns 0 if success or a negative value otherwise.
       
  1963  */
       
  1964 EXPORT_C
       
  1965 int		
       
  1966 xmlSecTmplTransformAddC14NInclNamespaces(xmlNodePtr transformNode, 
       
  1967 					 const xmlChar *prefixList) {
       
  1968     xmlNodePtr cur;
       
  1969     xmlAttrPtr ptr;
       
  1970 
       
  1971     xmlSecAssert2(transformNode != NULL, -1);    
       
  1972     xmlSecAssert2(prefixList != NULL, -1);
       
  1973 
       
  1974     cur = xmlSecFindChild(transformNode, xmlSecNodeInclusiveNamespaces, xmlSecNsExcC14N);
       
  1975     if(cur != NULL) {
       
  1976 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
  1977 		    NULL,
       
  1978 		    xmlSecErrorsSafeString(xmlSecNodeInclusiveNamespaces),
       
  1979 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  1980 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1981 	return(-1);
       
  1982     }
       
  1983     
       
  1984     cur = xmlSecAddChild(transformNode, xmlSecNodeInclusiveNamespaces, xmlSecNsExcC14N);
       
  1985     if(cur == NULL) {
       
  1986 	xmlSecError(XMLSEC_ERRORS_HERE, 
       
  1987 		    xmlSecErrorsSafeString(xmlSecNodeGetName(transformNode)),
       
  1988 		    "xmlSecAddChild",
       
  1989 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1990 		    "node=%s",
       
  1991 		    xmlSecErrorsSafeString(xmlSecNodeInclusiveNamespaces));
       
  1992 	return(-1);
       
  1993     }    
       
  1994     
       
  1995     ptr = xmlSetProp(cur, xmlSecAttrPrefixList, prefixList);
       
  1996     if (!ptr && OOM_FLAG) 
       
  1997         {
       
  1998         xmlUnlinkNode(cur);
       
  1999 	    xmlFreeNode(cur);
       
  2000 	    return(-1);
       
  2001         }
       
  2002     return(0);
       
  2003 }
       
  2004 
       
  2005 /**
       
  2006  * xmlSecTmplTransformAddXPath:
       
  2007  * @transformNode: 	the pointer to the <dsig:Transform/> node.
       
  2008  * @expression: 	the XPath expression.
       
  2009  * @nsList: 		the NULL terminated list of namespace prefix/href pairs
       
  2010  *			(optional).
       
  2011  *
       
  2012  * Writes XPath transform infromation to the <dsig:Transform/> node 
       
  2013  * @node.
       
  2014  *
       
  2015  * Returns 0 for success or a negative value otherwise.
       
  2016  */
       
  2017 EXPORT_C
       
  2018 int 	
       
  2019 xmlSecTmplTransformAddXPath(xmlNodePtr transformNode, const xmlChar *expression,
       
  2020 			 const xmlChar **nsList) {
       
  2021     xmlNodePtr xpathNode;
       
  2022     
       
  2023     xmlSecAssert2(transformNode != NULL, -1);
       
  2024     xmlSecAssert2(expression != NULL, -1);
       
  2025     
       
  2026     xpathNode = xmlSecFindChild(transformNode, xmlSecNodeXPath, xmlSecDSigNs);
       
  2027     if(xpathNode != NULL) {
       
  2028 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2029 		    NULL,
       
  2030 		    xmlSecErrorsSafeString(xmlSecNodeXPath),
       
  2031 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  2032 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2033 	return(-1);    
       
  2034     }
       
  2035 
       
  2036     xpathNode = xmlSecAddChild(transformNode, xmlSecNodeXPath, xmlSecDSigNs);
       
  2037     if(xpathNode == NULL) {
       
  2038 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2039 		    NULL,
       
  2040 		    "xmlSecAddChild",
       
  2041 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2042 		    "node=%s",
       
  2043 		    xmlSecErrorsSafeString(xmlSecNodeXPath));
       
  2044 	return(-1);    
       
  2045     }
       
  2046     
       
  2047     xmlNodeSetContent(xpathNode, expression);
       
  2048     return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpathNode, nsList) : 0);
       
  2049 }
       
  2050 
       
  2051 /**
       
  2052  * xmlSecTmplTransformAddXPath2:
       
  2053  * @transformNode: 	the pointer to the <dsig:Transform/> node.
       
  2054  * @type: 		the XPath2 transform type ("union", "intersect" or "subtract").
       
  2055  * @expression: 	the XPath expression.
       
  2056  * @nsList: 		the NULL terminated list of namespace prefix/href pairs.
       
  2057  *			(optional).
       
  2058  *
       
  2059  * Writes XPath2 transform infromation to the <dsig:Transform/> node 
       
  2060  * @node.
       
  2061  *
       
  2062  * Returns 0 for success or a negative value otherwise.
       
  2063  */
       
  2064 EXPORT_C
       
  2065 int
       
  2066 xmlSecTmplTransformAddXPath2(xmlNodePtr transformNode, const xmlChar* type,
       
  2067 			const xmlChar *expression, const xmlChar **nsList) {
       
  2068     xmlNodePtr xpathNode;
       
  2069     xmlAttrPtr ptr;
       
  2070 
       
  2071     xmlSecAssert2(transformNode != NULL, -1);
       
  2072     xmlSecAssert2(type != NULL, -1);
       
  2073     xmlSecAssert2(expression != NULL, -1);
       
  2074 
       
  2075     xpathNode = xmlSecAddChild(transformNode, xmlSecNodeXPath, xmlSecXPath2Ns);
       
  2076     if(xpathNode == NULL) {
       
  2077 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2078 		    NULL,
       
  2079 		    "xmlSecAddChild",
       
  2080 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2081 		    "node=%s",
       
  2082 		    xmlSecErrorsSafeString(xmlSecNodeXPath));
       
  2083 	return(-1);    
       
  2084     }
       
  2085     ptr = xmlSetProp(xpathNode, xmlSecAttrFilter, type);
       
  2086     if (!ptr && OOM_FLAG) 
       
  2087         {
       
  2088         xmlUnlinkNode(xpathNode);
       
  2089 	    xmlFreeNode(xpathNode);
       
  2090 	    return(-1);
       
  2091         }
       
  2092     
       
  2093     xmlNodeSetContent(xpathNode, expression);
       
  2094     return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpathNode, nsList) : 0);
       
  2095 }
       
  2096 
       
  2097 /**
       
  2098  * xmlSecTmplTransformAddXPointer:
       
  2099  * @transformNode: 	the pointer to the <dsig:Transform/> node.
       
  2100  * @expression: 	the XPath expression.
       
  2101  * @nsList: 		the NULL terminated list of namespace prefix/href pairs.
       
  2102  *			(optional).
       
  2103  *
       
  2104  * Writes XPoniter transform infromation to the <dsig:Transform/> node 
       
  2105  * @node.
       
  2106  *
       
  2107  * Returns 0 for success or a negative value otherwise.
       
  2108  */
       
  2109 EXPORT_C
       
  2110 int 	
       
  2111 xmlSecTmplTransformAddXPointer(xmlNodePtr transformNode, const xmlChar *expression,
       
  2112 			 const xmlChar **nsList) {
       
  2113     xmlNodePtr xpointerNode;
       
  2114 
       
  2115     xmlSecAssert2(expression != NULL, -1);
       
  2116     xmlSecAssert2(transformNode != NULL, -1);
       
  2117 
       
  2118     xpointerNode = xmlSecFindChild(transformNode, xmlSecNodeXPointer, xmlSecXPointerNs);
       
  2119     if(xpointerNode != NULL) {
       
  2120 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2121 		    NULL,
       
  2122 		    xmlSecErrorsSafeString(xmlSecNodeXPointer),
       
  2123 		    XMLSEC_ERRORS_R_NODE_ALREADY_PRESENT,
       
  2124 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  2125 	return(-1);    
       
  2126     }
       
  2127 
       
  2128     xpointerNode = xmlSecAddChild(transformNode, xmlSecNodeXPointer, xmlSecXPointerNs);
       
  2129     if(xpointerNode == NULL) {
       
  2130 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  2131 		    NULL,
       
  2132 		    "xmlSecAddChild",
       
  2133 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  2134 		    "node=%s",
       
  2135 		    xmlSecErrorsSafeString(xmlSecNodeXPointer));
       
  2136 	return(-1);    
       
  2137     }
       
  2138     
       
  2139     
       
  2140     xmlNodeSetContent(xpointerNode, expression);
       
  2141     return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpointerNode, nsList) : 0);
       
  2142 }
       
  2143 
       
  2144 static int 
       
  2145 xmlSecTmplNodeWriteNsList(xmlNodePtr parentNode, const xmlChar** nsList) {
       
  2146     xmlNsPtr ns;
       
  2147     const xmlChar *prefix;
       
  2148     const xmlChar *href;
       
  2149     const xmlChar **ptr;
       
  2150 
       
  2151     xmlSecAssert2(parentNode != NULL, -1);
       
  2152     xmlSecAssert2(nsList != NULL, -1);
       
  2153     	
       
  2154     ptr = nsList;
       
  2155     while((*ptr) != NULL) {
       
  2156 	if(xmlStrEqual(BAD_CAST "#default", (*ptr))) {
       
  2157 	    prefix = NULL;
       
  2158 	} else {
       
  2159 	    prefix = (*ptr);
       
  2160 	}
       
  2161 	if((++ptr) == NULL) {
       
  2162 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2163 			NULL,
       
  2164 			NULL,
       
  2165 			XMLSEC_ERRORS_R_INVALID_DATA,
       
  2166 			"unexpected end of ns list");
       
  2167 	    return(-1);
       
  2168 	}
       
  2169 	href = *(ptr++);
       
  2170 
       
  2171 	ns = xmlNewNs(parentNode, href, prefix);
       
  2172 	if(ns == NULL) {
       
  2173 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  2174 			NULL,
       
  2175 			"xmlNewNs",
       
  2176 			XMLSEC_ERRORS_R_XML_FAILED,
       
  2177 			"href=%s;prefix=%s", 
       
  2178 			xmlSecErrorsSafeString(href),
       
  2179 			xmlSecErrorsSafeString(prefix));
       
  2180 	    return(-1);
       
  2181 	}
       
  2182     }
       
  2183     return(0);
       
  2184 }