1 /*
2 * XML Security Library (http://www.aleksey.com/xmlsec).
3 *
4 *
5 * This is free software; see Copyright file in the source
6 * distribution for preciese wording.
7 *
8 * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
9 */
10 /**
11 * SECTION:templates
12 * @Short_description: XML signature and encryption template functions.
13 * @Stability: Stable
14 *
15 */
16 #include "globals.h"
17
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include <libxml/tree.h>
22
23 #include <xmlsec/xmlsec.h>
24 #include <xmlsec/xmltree.h>
25 #include <xmlsec/transforms.h>
26 #include <xmlsec/strings.h>
27 #include <xmlsec/base64.h>
28 #include <xmlsec/templates.h>
29 #include <xmlsec/errors.h>
30
31
32 static xmlNodePtr xmlSecTmplAddReference (xmlNodePtr parentNode,
33 xmlSecTransformId digestMethodId,
34 const xmlChar *id,
35 const xmlChar *uri,
36 const xmlChar *type);
37 static int xmlSecTmplPrepareEncData (xmlNodePtr parentNode,
38 xmlSecTransformId encMethodId);
39 static int xmlSecTmplNodeWriteNsList (xmlNodePtr parentNode,
40 const xmlChar** namespaces);
41 /**************************************************************************
42 *
43 * <dsig:Signature/> node
44 *
45 **************************************************************************/
46 /**
47 * xmlSecTmplSignatureCreate:
48 * @doc: the pointer to signature document or NULL; in the
49 * second case, application must later call @xmlSetTreeDoc
50 * to ensure that all the children nodes have correct
51 * pointer to XML document.
52 * @c14nMethodId: the signature canonicalization method.
53 * @signMethodId: the signature method.
54 * @id: the node id (may be NULL).
55 *
56 * Creates new <dsig:Signature/> node with the mandatory <dsig:SignedInfo/>,
57 * <dsig:CanonicalizationMethod/>, <dsig:SignatureMethod/> and
58 * <dsig:SignatureValue/> children and sub-children.
59 * The application is responsible for inserting the returned node
60 * in the XML document.
61 *
62 * Returns: the pointer to newly created <dsig:Signature/> node or NULL if an
63 * error occurs.
64 */
65 xmlNodePtr
xmlSecTmplSignatureCreate(xmlDocPtr doc,xmlSecTransformId c14nMethodId,xmlSecTransformId signMethodId,const xmlChar * id)66 xmlSecTmplSignatureCreate(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
67 xmlSecTransformId signMethodId, const xmlChar *id) {
68 return xmlSecTmplSignatureCreateNsPref(doc, c14nMethodId, signMethodId, id, NULL);
69 }
70
71 /**
72 * xmlSecTmplSignatureCreateNsPref:
73 * @doc: the pointer to signature document or NULL; in the
74 * second case, application must later call @xmlSetTreeDoc
75 * to ensure that all the children nodes have correct
76 * pointer to XML document.
77 * @c14nMethodId: the signature canonicalization method.
78 * @signMethodId: the signature method.
79 * @id: the node id (may be NULL).
80 * @nsPrefix: the namespace prefix for the signature element (e.g. "dsig"), or NULL
81 *
82 * Creates new <dsig:Signature/> node with the mandatory
83 * <dsig:SignedInfo/>, <dsig:CanonicalizationMethod/>,
84 * <dsig:SignatureMethod/> and <dsig:SignatureValue/> children and
85 * sub-children. This method differs from xmlSecTmplSignatureCreate in
86 * that it will define the http://www.w3.org/2000/09/xmldsig#
87 * namespace with the given prefix that will be used for all of the
88 * appropriate child nodes. The application is responsible for
89 * inserting the returned node in the XML document.
90 *
91 * Returns: the pointer to newly created <dsig:Signature/> node or NULL if an
92 * error occurs.
93 */
94 xmlNodePtr
xmlSecTmplSignatureCreateNsPref(xmlDocPtr doc,xmlSecTransformId c14nMethodId,xmlSecTransformId signMethodId,const xmlChar * id,const xmlChar * nsPrefix)95 xmlSecTmplSignatureCreateNsPref(xmlDocPtr doc, xmlSecTransformId c14nMethodId,
96 xmlSecTransformId signMethodId, const xmlChar *id,
97 const xmlChar* nsPrefix) {
98 xmlNodePtr signNode;
99 xmlNodePtr signedInfoNode;
100 xmlNodePtr cur;
101 xmlNsPtr ns;
102
103 xmlSecAssert2(c14nMethodId != NULL, NULL);
104 xmlSecAssert2(c14nMethodId->href != NULL, NULL);
105 xmlSecAssert2(signMethodId != NULL, NULL);
106 xmlSecAssert2(signMethodId->href != NULL, NULL);
107
108 /* create Signature node itself */
109 signNode = xmlNewDocNode(doc, NULL, xmlSecNodeSignature, NULL);
110 if(signNode == NULL) {
111 xmlSecXmlError2("xmlNewDocNode", NULL,
112 "node=%s", xmlSecErrorsSafeString(xmlSecNodeSignature));
113 return(NULL);
114 }
115
116 ns = xmlNewNs(signNode, xmlSecDSigNs, nsPrefix);
117 if(ns == NULL) {
118 xmlSecXmlError2("xmlNewNs", NULL,
119 "ns=%s", xmlSecErrorsSafeString(xmlSecDSigNs));
120 xmlFreeNode(signNode);
121 return(NULL);
122 }
123 xmlSetNs(signNode, ns);
124
125 if(id != NULL) {
126 xmlSetProp(signNode, BAD_CAST "Id", id);
127 }
128
129 /* add SignedInfo node */
130 signedInfoNode = xmlSecAddChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
131 if(signedInfoNode == NULL) {
132 xmlSecInternalError("xmlSecAddChild(xmlSecNodeSignedInfo)", NULL);
133 xmlFreeNode(signNode);
134 return(NULL);
135 }
136
137 /* add SignatureValue node */
138 cur = xmlSecAddChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
139 if(cur == NULL) {
140 xmlSecInternalError("xmlSecAddChild(xmlSecNodeSignatureValue)", NULL);
141 xmlFreeNode(signNode);
142 return(NULL);
143 }
144
145 /* add CanonicalizationMethod node to SignedInfo */
146 cur = xmlSecAddChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs);
147 if(cur == NULL) {
148 xmlSecInternalError("xmlSecAddChild(xmlSecNodeCanonicalizationMethod)", NULL);
149 xmlFreeNode(signNode);
150 return(NULL);
151 }
152 if(xmlSetProp(cur, xmlSecAttrAlgorithm, c14nMethodId->href) == NULL) {
153 xmlSecXmlError2("xmlSetProp", NULL,
154 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
155 xmlFreeNode(signNode);
156 return(NULL);
157 }
158
159 /* add SignatureMethod node to SignedInfo */
160 cur = xmlSecAddChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs);
161 if(cur == NULL) {
162 xmlSecInternalError("xmlSecAddChild(xmlSecNodeSignatureMethod)", NULL);
163 xmlFreeNode(signNode);
164 return(NULL);
165 }
166 if(xmlSetProp(cur, xmlSecAttrAlgorithm, signMethodId->href) == NULL) {
167 xmlSecXmlError2("xmlSetProp", NULL,
168 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
169 xmlFreeNode(signNode);
170 return(NULL);
171 }
172
173 return(signNode);
174 }
175
176 /**
177 * xmlSecTmplSignatureEnsureKeyInfo:
178 * @signNode: the pointer to <dsig:Signature/> node.
179 * @id: the node id (may be NULL).
180 *
181 * Adds (if necessary) <dsig:KeyInfo/> node to the <dsig:Signature/>
182 * node @signNode.
183 *
184 * Returns: the pointer to newly created <dsig:KeyInfo/> node or NULL if an
185 * error occurs.
186 */
187 xmlNodePtr
xmlSecTmplSignatureEnsureKeyInfo(xmlNodePtr signNode,const xmlChar * id)188 xmlSecTmplSignatureEnsureKeyInfo(xmlNodePtr signNode, const xmlChar *id) {
189 xmlNodePtr res;
190
191 xmlSecAssert2(signNode != NULL, NULL);
192
193 res = xmlSecFindChild(signNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
194 if(res == NULL) {
195 xmlNodePtr signValueNode;
196
197 signValueNode = xmlSecFindChild(signNode, xmlSecNodeSignatureValue, xmlSecDSigNs);
198 if(signValueNode == NULL) {
199 xmlSecNodeNotFoundError("xmlSecFindChild", signNode,
200 xmlSecNodeSignatureValue, NULL);
201 return(NULL);
202 }
203
204 res = xmlSecAddNextSibling(signValueNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
205 if(res == NULL) {
206 xmlSecInternalError("xmlSecAddNextSibling(xmlSecNodeKeyInfo)", NULL);
207 return(NULL);
208 }
209 }
210 if(id != NULL) {
211 xmlSetProp(res, xmlSecAttrId, id);
212 }
213 return(res);
214 }
215
216 /**
217 * xmlSecTmplSignatureAddReference:
218 * @signNode: the pointer to <dsig:Signature/> node.
219 * @digestMethodId: the reference digest method.
220 * @id: the node id (may be NULL).
221 * @uri: the reference node uri (may be NULL).
222 * @type: the reference node type (may be NULL).
223 *
224 * Adds <dsig:Reference/> node with given URI (@uri), Id (@id) and
225 * Type (@type) attributes and the required children <dsig:DigestMethod/> and
226 * <dsig:DigestValue/> to the <dsig:SignedInfo/> child of @signNode.
227 *
228 * Returns: the pointer to newly created <dsig:Reference/> node or NULL
229 * if an error occurs.
230 */
231 xmlNodePtr
xmlSecTmplSignatureAddReference(xmlNodePtr signNode,xmlSecTransformId digestMethodId,const xmlChar * id,const xmlChar * uri,const xmlChar * type)232 xmlSecTmplSignatureAddReference(xmlNodePtr signNode, xmlSecTransformId digestMethodId,
233 const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
234 xmlNodePtr signedInfoNode;
235
236 xmlSecAssert2(signNode != NULL, NULL);
237 xmlSecAssert2(digestMethodId != NULL, NULL);
238 xmlSecAssert2(digestMethodId->href != NULL, NULL);
239
240 signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
241 if(signedInfoNode == NULL) {
242 xmlSecNodeNotFoundError("xmlSecFindChild", signNode,
243 xmlSecNodeSignedInfo, NULL);
244 return(NULL);
245 }
246
247 return(xmlSecTmplAddReference(signedInfoNode, digestMethodId, id, uri, type));
248 }
249
250 static xmlNodePtr
xmlSecTmplAddReference(xmlNodePtr parentNode,xmlSecTransformId digestMethodId,const xmlChar * id,const xmlChar * uri,const xmlChar * type)251 xmlSecTmplAddReference(xmlNodePtr parentNode, xmlSecTransformId digestMethodId,
252 const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
253 xmlNodePtr res;
254 xmlNodePtr cur;
255
256 xmlSecAssert2(parentNode != NULL, NULL);
257 xmlSecAssert2(digestMethodId != NULL, NULL);
258 xmlSecAssert2(digestMethodId->href != NULL, NULL);
259
260 /* add Reference node */
261 res = xmlSecAddChild(parentNode, xmlSecNodeReference, xmlSecDSigNs);
262 if(res == NULL) {
263 xmlSecInternalError("xmlSecAddChild(xmlSecNodeReference)", NULL);
264 return(NULL);
265 }
266
267 /* set Reference node attributes */
268 if(id != NULL) {
269 xmlSetProp(res, xmlSecAttrId, id);
270 }
271 if(type != NULL) {
272 xmlSetProp(res, xmlSecAttrType, type);
273 }
274 if(uri != NULL) {
275 xmlSetProp(res, xmlSecAttrURI, uri);
276 }
277
278 /* add DigestMethod node and set algorithm */
279 cur = xmlSecAddChild(res, xmlSecNodeDigestMethod, xmlSecDSigNs);
280 if(cur == NULL) {
281 xmlSecInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL);
282 xmlUnlinkNode(res);
283 xmlFreeNode(res);
284 return(NULL);
285 }
286 if(xmlSetProp(cur, xmlSecAttrAlgorithm, digestMethodId->href) == NULL) {
287 xmlSecXmlError2("xmlSetProp", NULL,
288 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
289 xmlUnlinkNode(res);
290 xmlFreeNode(res);
291 return(NULL);
292 }
293
294 /* add DigestValue node */
295 cur = xmlSecAddChild(res, xmlSecNodeDigestValue, xmlSecDSigNs);
296 if(cur == NULL) {
297 xmlSecInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL);
298 xmlUnlinkNode(res);
299 xmlFreeNode(res);
300 return(NULL);
301 }
302
303 return(res);
304 }
305
306 /**
307 * xmlSecTmplSignatureAddObject:
308 * @signNode: the pointer to <dsig:Signature/> node.
309 * @id: the node id (may be NULL).
310 * @mimeType: the object mime type (may be NULL).
311 * @encoding: the object encoding (may be NULL).
312 *
313 * Adds <dsig:Object/> node to the <dsig:Signature/> node @signNode.
314 *
315 * Returns: the pointer to newly created <dsig:Object/> node or NULL
316 * if an error occurs.
317 */
318 xmlNodePtr
xmlSecTmplSignatureAddObject(xmlNodePtr signNode,const xmlChar * id,const xmlChar * mimeType,const xmlChar * encoding)319 xmlSecTmplSignatureAddObject(xmlNodePtr signNode, const xmlChar *id,
320 const xmlChar *mimeType, const xmlChar *encoding) {
321 xmlNodePtr res;
322
323 xmlSecAssert2(signNode != NULL, NULL);
324
325 res = xmlSecAddChild(signNode, xmlSecNodeObject, xmlSecDSigNs);
326 if(res == NULL) {
327 xmlSecInternalError("xmlSecAddChild(xmlSecNodeObject)", NULL);
328 return(NULL);
329 }
330 if(id != NULL) {
331 xmlSetProp(res, xmlSecAttrId, id);
332 }
333 if(mimeType != NULL) {
334 xmlSetProp(res, xmlSecAttrMimeType, mimeType);
335 }
336 if(encoding != NULL) {
337 xmlSetProp(res, xmlSecAttrEncoding, encoding);
338 }
339 return(res);
340 }
341
342 /**
343 * xmlSecTmplSignatureGetSignMethodNode:
344 * @signNode: the pointer to <dsig:Signature /> node.
345 *
346 * Gets pointer to <dsig:SignatureMethod/> child of <dsig:KeyInfo/> node.
347 *
348 * Returns: pointer to <dsig:SignatureMethod /> node or NULL if an error occurs.
349 */
350 xmlNodePtr
xmlSecTmplSignatureGetSignMethodNode(xmlNodePtr signNode)351 xmlSecTmplSignatureGetSignMethodNode(xmlNodePtr signNode) {
352 xmlNodePtr signedInfoNode;
353
354 xmlSecAssert2(signNode != NULL, NULL);
355
356 signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
357 if(signedInfoNode == NULL) {
358 xmlSecNodeNotFoundError("xmlSecFindChild", signNode,
359 xmlSecNodeSignedInfo, NULL);
360 return(NULL);
361 }
362 return(xmlSecFindChild(signedInfoNode, xmlSecNodeSignatureMethod, xmlSecDSigNs));
363 }
364
365 /**
366 * xmlSecTmplSignatureGetC14NMethodNode:
367 * @signNode: the pointer to <dsig:Signature /> node.
368 *
369 * Gets pointer to <dsig:CanonicalizationMethod/> child of <dsig:KeyInfo/> node.
370 *
371 * Returns: pointer to <dsig:CanonicalizationMethod /> node or NULL if an error occurs.
372 */
373 xmlNodePtr
xmlSecTmplSignatureGetC14NMethodNode(xmlNodePtr signNode)374 xmlSecTmplSignatureGetC14NMethodNode(xmlNodePtr signNode) {
375 xmlNodePtr signedInfoNode;
376
377 xmlSecAssert2(signNode != NULL, NULL);
378
379 signedInfoNode = xmlSecFindChild(signNode, xmlSecNodeSignedInfo, xmlSecDSigNs);
380 if(signedInfoNode == NULL) {
381 xmlSecNodeNotFoundError("xmlSecFindChild", signNode,
382 xmlSecNodeSignedInfo, NULL);
383 return(NULL);
384 }
385 return(xmlSecFindChild(signedInfoNode, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs));
386 }
387
388 /**
389 * xmlSecTmplReferenceAddTransform:
390 * @referenceNode: the pointer to <dsig:Reference/> node.
391 * @transformId: the transform method id.
392 *
393 * Adds <dsig:Transform/> node to the <dsig:Reference/> node @referenceNode.
394 *
395 * Returns: the pointer to newly created <dsig:Transform/> node or NULL if an
396 * error occurs.
397 */
398 xmlNodePtr
xmlSecTmplReferenceAddTransform(xmlNodePtr referenceNode,xmlSecTransformId transformId)399 xmlSecTmplReferenceAddTransform(xmlNodePtr referenceNode, xmlSecTransformId transformId) {
400 xmlNodePtr transformsNode;
401 xmlNodePtr res;
402
403 xmlSecAssert2(referenceNode != NULL, NULL);
404 xmlSecAssert2(transformId != NULL, NULL);
405 xmlSecAssert2(transformId->href != NULL, NULL);
406
407 /* do we need to create Transforms node first */
408 transformsNode = xmlSecFindChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
409 if(transformsNode == NULL) {
410 xmlNodePtr tmp;
411
412 tmp = xmlSecGetNextElementNode(referenceNode->children);
413 if(tmp == NULL) {
414 transformsNode = xmlSecAddChild(referenceNode, xmlSecNodeTransforms, xmlSecDSigNs);
415 if(transformsNode == NULL) {
416 xmlSecInternalError("xmlSecAddChild(xmlSecNodeTransforms)", NULL);
417 return(NULL);
418 }
419 } else {
420 transformsNode = xmlSecAddPrevSibling(tmp, xmlSecNodeTransforms, xmlSecDSigNs);
421 if(transformsNode == NULL) {
422 xmlSecInternalError("xmlSecAddPrevSibling(xmlSecNodeTransforms)", NULL);
423 return(NULL);
424 }
425 }
426 }
427
428 res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
429 if(res == NULL) {
430 xmlSecInternalError("xmlSecAddChild(xmlSecNodeTransform)", NULL);
431 return(NULL);
432 }
433
434 if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
435 xmlSecXmlError2("xmlSetProp", NULL,
436 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
437 xmlUnlinkNode(res);
438 xmlFreeNode(res);
439 return(NULL);
440 }
441
442 return(res);
443 }
444
445 /**
446 * xmlSecTmplObjectAddSignProperties:
447 * @objectNode: the pointer to <dsig:Object/> node.
448 * @id: the node id (may be NULL).
449 * @target: the Target (may be NULL).
450 *
451 * Adds <dsig:SignatureProperties/> node to the <dsig:Object/> node @objectNode.
452 *
453 * Returns: the pointer to newly created <dsig:SignatureProperties/> node or NULL
454 * if an error occurs.
455 */
456 xmlNodePtr
xmlSecTmplObjectAddSignProperties(xmlNodePtr objectNode,const xmlChar * id,const xmlChar * target)457 xmlSecTmplObjectAddSignProperties(xmlNodePtr objectNode, const xmlChar *id, const xmlChar *target) {
458 xmlNodePtr res;
459
460 xmlSecAssert2(objectNode != NULL, NULL);
461
462 res = xmlSecAddChild(objectNode, xmlSecNodeSignatureProperties, xmlSecDSigNs);
463 if(res == NULL) {
464 xmlSecInternalError("xmlSecAddChild(xmlSecNodeSignatureProperties)", NULL);
465 return(NULL);
466 }
467 if(id != NULL) {
468 xmlSetProp(res, xmlSecAttrId, id);
469 }
470 if(target != NULL) {
471 xmlSetProp(res, xmlSecAttrTarget, target);
472 }
473 return(res);
474 }
475
476 /**
477 * xmlSecTmplObjectAddManifest:
478 * @objectNode: the pointer to <dsig:Object/> node.
479 * @id: the node id (may be NULL).
480 *
481 * Adds <dsig:Manifest/> node to the <dsig:Object/> node @objectNode.
482 *
483 * Returns: the pointer to newly created <dsig:Manifest/> node or NULL
484 * if an error occurs.
485 */
486 xmlNodePtr
xmlSecTmplObjectAddManifest(xmlNodePtr objectNode,const xmlChar * id)487 xmlSecTmplObjectAddManifest(xmlNodePtr objectNode, const xmlChar *id) {
488 xmlNodePtr res;
489
490 xmlSecAssert2(objectNode != NULL, NULL);
491
492 res = xmlSecAddChild(objectNode, xmlSecNodeManifest, xmlSecDSigNs);
493 if(res == NULL) {
494 xmlSecInternalError("xmlSecAddChild(xmlSecNodeManifest)", NULL);
495 return(NULL);
496 }
497 if(id != NULL) {
498 xmlSetProp(res, xmlSecAttrId, id);
499 }
500 return(res);
501 }
502
503 /**
504 * xmlSecTmplManifestAddReference:
505 * @manifestNode: the pointer to <dsig:Manifest/> node.
506 * @digestMethodId: the reference digest method.
507 * @id: the node id (may be NULL).
508 * @uri: the reference node uri (may be NULL).
509 * @type: the reference node type (may be NULL).
510 *
511 * Adds <dsig:Reference/> node with specified URI (@uri), Id (@id) and
512 * Type (@type) attributes and the required children <dsig:DigestMethod/> and
513 * <dsig:DigestValue/> to the <dsig:Manifest/> node @manifestNode.
514 *
515 * Returns: the pointer to newly created <dsig:Reference/> node or NULL
516 * if an error occurs.
517 */
518 xmlNodePtr
xmlSecTmplManifestAddReference(xmlNodePtr manifestNode,xmlSecTransformId digestMethodId,const xmlChar * id,const xmlChar * uri,const xmlChar * type)519 xmlSecTmplManifestAddReference(xmlNodePtr manifestNode, xmlSecTransformId digestMethodId,
520 const xmlChar *id, const xmlChar *uri, const xmlChar *type) {
521 return(xmlSecTmplAddReference(manifestNode, digestMethodId, id, uri, type));
522 }
523
524 /**************************************************************************
525 *
526 * <enc:EncryptedData/> node
527 *
528 **************************************************************************/
529 /**
530 * xmlSecTmplEncDataCreate:
531 * @doc: the pointer to signature document or NULL; in the later
532 * case, application must later call @xmlSetTreeDoc to ensure
533 * that all the children nodes have correct pointer to XML document.
534 * @encMethodId: the encryption method (may be NULL).
535 * @id: the Id attribute (optional).
536 * @type: the Type attribute (optional)
537 * @mimeType: the MimeType attribute (optional)
538 * @encoding: the Encoding attribute (optional)
539 *
540 * Creates new <enc:EncryptedData /> node for encryption template.
541 *
542 * Returns: the pointer newly created <enc:EncryptedData/> node or NULL
543 * if an error occurs.
544 */
545 xmlNodePtr
xmlSecTmplEncDataCreate(xmlDocPtr doc,xmlSecTransformId encMethodId,const xmlChar * id,const xmlChar * type,const xmlChar * mimeType,const xmlChar * encoding)546 xmlSecTmplEncDataCreate(xmlDocPtr doc, xmlSecTransformId encMethodId,
547 const xmlChar *id, const xmlChar *type,
548 const xmlChar *mimeType, const xmlChar *encoding) {
549 xmlNodePtr encNode;
550 xmlNsPtr ns;
551
552 encNode = xmlNewDocNode(doc, NULL, xmlSecNodeEncryptedData, NULL);
553 if(encNode == NULL) {
554 xmlSecXmlError2("xmlNewDocNode", NULL,
555 "node=%s", xmlSecErrorsSafeString(xmlSecNodeEncryptedData));
556 return(NULL);
557 }
558
559 ns = xmlNewNs(encNode, xmlSecEncNs, NULL);
560 if(ns == NULL) {
561 xmlSecXmlError2("xmlNewNs", NULL,
562 "ns=%s", xmlSecErrorsSafeString(xmlSecEncNs));
563 return(NULL);
564 }
565 xmlSetNs(encNode, ns);
566
567 if(id != NULL) {
568 xmlSetProp(encNode, xmlSecAttrId, id);
569 }
570 if(type != NULL) {
571 xmlSetProp(encNode, xmlSecAttrType, type);
572 }
573 if(mimeType != NULL) {
574 xmlSetProp(encNode, xmlSecAttrMimeType, mimeType);
575 }
576 if(encoding != NULL) {
577 xmlSetProp(encNode, xmlSecAttrEncoding, encoding);
578 }
579
580 if(xmlSecTmplPrepareEncData(encNode, encMethodId) < 0) {
581 xmlFreeNode(encNode);
582 return(NULL);
583 }
584 return(encNode);
585 }
586
587 static int
xmlSecTmplPrepareEncData(xmlNodePtr parentNode,xmlSecTransformId encMethodId)588 xmlSecTmplPrepareEncData(xmlNodePtr parentNode, xmlSecTransformId encMethodId) {
589 xmlNodePtr cur;
590
591 xmlSecAssert2(parentNode != NULL, -1);
592 xmlSecAssert2((encMethodId == NULL) || (encMethodId->href != NULL), -1);
593
594 /* add EncryptionMethod node if requested */
595 if(encMethodId != NULL) {
596 cur = xmlSecAddChild(parentNode, xmlSecNodeEncryptionMethod, xmlSecEncNs);
597 if(cur == NULL) {
598 xmlSecInternalError("xmlSecAddChild(xmlSecNodeEncryptionMethod)", NULL);
599 return(-1);
600 }
601 if(xmlSetProp(cur, xmlSecAttrAlgorithm, encMethodId->href) == NULL) {
602 xmlSecXmlError2("xmlSetProp", NULL,
603 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
604 return(-1);
605 }
606 }
607
608 /* and CipherData node */
609 cur = xmlSecAddChild(parentNode, xmlSecNodeCipherData, xmlSecEncNs);
610 if(cur == NULL) {
611 xmlSecInternalError("xmlSecAddChild(xmlSecNodeCipherData)", NULL);
612 return(-1);
613 }
614
615 return(0);
616 }
617
618
619 /**
620 * xmlSecTmplEncDataEnsureKeyInfo:
621 * @encNode: the pointer to <enc:EncryptedData/> node.
622 * @id: the Id attrbibute (optional).
623 *
624 * Adds <dsig:KeyInfo/> to the <enc:EncryptedData/> node @encNode.
625 *
626 * Returns: the pointer to newly created <dsig:KeyInfo/> node or
627 * NULL if an error occurs.
628 */
629 xmlNodePtr
xmlSecTmplEncDataEnsureKeyInfo(xmlNodePtr encNode,const xmlChar * id)630 xmlSecTmplEncDataEnsureKeyInfo(xmlNodePtr encNode, const xmlChar* id) {
631 xmlNodePtr res;
632
633 xmlSecAssert2(encNode != NULL, NULL);
634
635 res = xmlSecFindChild(encNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
636 if(res == NULL) {
637 xmlNodePtr cipherDataNode;
638
639 cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
640 if(cipherDataNode == NULL) {
641 xmlSecNodeNotFoundError("xmlSecFindChild", encNode,
642 xmlSecNodeCipherData, NULL);
643 return(NULL);
644 }
645
646 res = xmlSecAddPrevSibling(cipherDataNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
647 if(res == NULL) {
648 xmlSecInternalError("xmlSecAddPrevSibling(xmlSecNodeKeyInfo)", NULL);
649 return(NULL);
650 }
651 }
652 if(id != NULL) {
653 xmlSetProp(res, xmlSecAttrId, id);
654 }
655 return(res);
656 }
657
658 /**
659 * xmlSecTmplEncDataEnsureEncProperties:
660 * @encNode: the pointer to <enc:EncryptedData/> node.
661 * @id: the Id attribute (optional).
662 *
663 * Adds <enc:EncryptionProperties/> node to the <enc:EncryptedData/>
664 * node @encNode.
665 *
666 * Returns: the pointer to newly created <enc:EncryptionProperties/> node or
667 * NULL if an error occurs.
668 */
669 xmlNodePtr
xmlSecTmplEncDataEnsureEncProperties(xmlNodePtr encNode,const xmlChar * id)670 xmlSecTmplEncDataEnsureEncProperties(xmlNodePtr encNode, const xmlChar *id) {
671 xmlNodePtr res;
672
673 xmlSecAssert2(encNode != NULL, NULL);
674
675 res = xmlSecFindChild(encNode, xmlSecNodeEncryptionProperties, xmlSecEncNs);
676 if(res == NULL) {
677 res = xmlSecAddChild(encNode, xmlSecNodeEncryptionProperties, xmlSecEncNs);
678 if(res == NULL) {
679 xmlSecInternalError("xmlSecAddChild(xmlSecNodeEncryptionProperties)", NULL);
680 return(NULL);
681 }
682 }
683
684 if(id != NULL) {
685 xmlSetProp(res, xmlSecAttrId, id);
686 }
687
688 return(res);
689 }
690
691 /**
692 * xmlSecTmplEncDataAddEncProperty:
693 * @encNode: the pointer to <enc:EncryptedData/> node.
694 * @id: the Id attribute (optional).
695 * @target: the Target attribute (optional).
696 *
697 * Adds <enc:EncryptionProperty/> node (and the parent
698 * <enc:EncryptionProperties/> node if required) to the
699 * <enc:EncryptedData/> node @encNode.
700 *
701 * Returns: the pointer to newly created <enc:EncryptionProperty/> node or
702 * NULL if an error occurs.
703 */
704 xmlNodePtr
xmlSecTmplEncDataAddEncProperty(xmlNodePtr encNode,const xmlChar * id,const xmlChar * target)705 xmlSecTmplEncDataAddEncProperty(xmlNodePtr encNode, const xmlChar *id, const xmlChar *target) {
706 xmlNodePtr encProps;
707 xmlNodePtr res;
708
709 xmlSecAssert2(encNode != NULL, NULL);
710
711 encProps = xmlSecTmplEncDataEnsureEncProperties(encNode, NULL);
712 if(encProps == NULL) {
713 xmlSecInternalError("xmlSecTmplEncDataEnsureEncProperties", NULL);
714 return(NULL);
715 }
716
717 res = xmlSecAddChild(encProps, xmlSecNodeEncryptionProperty, xmlSecEncNs);
718 if(res == NULL) {
719 xmlSecInternalError("xmlSecAddChild(xmlSecNodeEncryptionProperty)", NULL);
720 return(NULL);
721 }
722 if(id != NULL) {
723 xmlSetProp(res, xmlSecAttrId, id);
724 }
725 if(target != NULL) {
726 xmlSetProp(res, xmlSecAttrTarget, target);
727 }
728
729 return(res);
730 }
731
732 /**
733 * xmlSecTmplEncDataEnsureCipherValue:
734 * @encNode: the pointer to <enc:EncryptedData/> node.
735 *
736 * Adds <enc:CipherValue/> to the <enc:EncryptedData/> node @encNode.
737 *
738 * Returns: the pointer to newly created <enc:CipherValue/> node or
739 * NULL if an error occurs.
740 */
741 xmlNodePtr
xmlSecTmplEncDataEnsureCipherValue(xmlNodePtr encNode)742 xmlSecTmplEncDataEnsureCipherValue(xmlNodePtr encNode) {
743 xmlNodePtr cipherDataNode;
744 xmlNodePtr res, tmp;
745
746 xmlSecAssert2(encNode != NULL, NULL);
747
748 cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
749 if(cipherDataNode == NULL) {
750 xmlSecNodeNotFoundError("xmlSecFindChild", encNode,
751 xmlSecNodeCipherData, NULL);
752 return(NULL);
753 }
754
755 /* check that we don;t have CipherReference node */
756 tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
757 if(tmp != NULL) {
758 xmlSecNodeAlreadyPresentError(cipherDataNode, xmlSecNodeCipherReference, NULL);
759 return(NULL);
760 }
761
762 res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
763 if(res == NULL) {
764 res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
765 if(res == NULL) {
766 xmlSecInternalError("xmlSecAddChild(xmlSecNodeCipherValue)", NULL);
767 return(NULL);
768 }
769 }
770
771 return(res);
772 }
773
774 /**
775 * xmlSecTmplEncDataEnsureCipherReference:
776 * @encNode: the pointer to <enc:EncryptedData/> node.
777 * @uri: the URI attribute (may be NULL).
778 *
779 * Adds <enc:CipherReference/> node with specified URI attribute @uri
780 * to the <enc:EncryptedData/> node @encNode.
781 *
782 * Returns: the pointer to newly created <enc:CipherReference/> node or
783 * NULL if an error occurs.
784 */
785 xmlNodePtr
xmlSecTmplEncDataEnsureCipherReference(xmlNodePtr encNode,const xmlChar * uri)786 xmlSecTmplEncDataEnsureCipherReference(xmlNodePtr encNode, const xmlChar *uri) {
787 xmlNodePtr cipherDataNode;
788 xmlNodePtr res, tmp;
789
790 xmlSecAssert2(encNode != NULL, NULL);
791
792 cipherDataNode = xmlSecFindChild(encNode, xmlSecNodeCipherData, xmlSecEncNs);
793 if(cipherDataNode == NULL) {
794 xmlSecNodeNotFoundError("xmlSecFindChild", encNode,
795 xmlSecNodeCipherData, NULL);
796 return(NULL);
797 }
798
799 /* check that we don;t have CipherValue node */
800 tmp = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherValue, xmlSecEncNs);
801 if(tmp != NULL) {
802 xmlSecNodeAlreadyPresentError(cipherDataNode, xmlSecNodeCipherValue, NULL);
803 return(NULL);
804 }
805
806 res = xmlSecFindChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
807 if(res == NULL) {
808 res = xmlSecAddChild(cipherDataNode, xmlSecNodeCipherReference, xmlSecEncNs);
809 if(res == NULL) {
810 xmlSecInternalError("xmlSecAddChild(xmlSecNodeCipherReference)", NULL);
811 return(NULL);
812 }
813 }
814
815 if(uri != NULL) {
816 xmlSetProp(res, xmlSecAttrURI, uri);
817 }
818
819 return(res);
820 }
821
822 /**
823 * xmlSecTmplEncDataGetEncMethodNode:
824 * @encNode: the pointer to <enc:EcnryptedData /> node.
825 *
826 * Gets pointer to <enc:EncryptionMethod/> node.
827 *
828 * Returns: pointer to <enc:EncryptionMethod /> node or NULL if an error occurs.
829 */
830 xmlNodePtr
xmlSecTmplEncDataGetEncMethodNode(xmlNodePtr encNode)831 xmlSecTmplEncDataGetEncMethodNode(xmlNodePtr encNode) {
832 xmlSecAssert2(encNode != NULL, NULL);
833
834 return(xmlSecFindChild(encNode, xmlSecNodeEncryptionMethod, xmlSecEncNs));
835 }
836
837 /**
838 * xmlSecTmplCipherReferenceAddTransform:
839 * @cipherReferenceNode: the pointer to <enc:CipherReference/> node.
840 * @transformId: the transform id.
841 *
842 * Adds <dsig:Transform/> node (and the parent <dsig:Transforms/> node)
843 * with specified transform methods @transform to the <enc:CipherReference/>
844 * child node of the <enc:EncryptedData/> node @encNode.
845 *
846 * Returns: the pointer to newly created <dsig:Transform/> node or
847 * NULL if an error occurs.
848 */
849 xmlNodePtr
xmlSecTmplCipherReferenceAddTransform(xmlNodePtr cipherReferenceNode,xmlSecTransformId transformId)850 xmlSecTmplCipherReferenceAddTransform(xmlNodePtr cipherReferenceNode,
851 xmlSecTransformId transformId) {
852 xmlNodePtr transformsNode;
853 xmlNodePtr res;
854
855 xmlSecAssert2(cipherReferenceNode != NULL, NULL);
856 xmlSecAssert2(transformId != NULL, NULL);
857 xmlSecAssert2(transformId->href != NULL, NULL);
858
859 transformsNode = xmlSecFindChild(cipherReferenceNode, xmlSecNodeTransforms, xmlSecEncNs);
860 if(transformsNode == NULL) {
861 transformsNode = xmlSecAddChild(cipherReferenceNode, xmlSecNodeTransforms, xmlSecEncNs);
862 if(transformsNode == NULL) {
863 xmlSecInternalError("xmlSecAddChild(xmlSecNodeTransforms)", NULL);
864 return(NULL);
865 }
866 }
867
868 res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
869 if(res == NULL) {
870 xmlSecInternalError("xmlSecAddChild(xmlSecNodeTransform)", NULL);
871 return(NULL);
872 }
873
874 if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
875 xmlSecXmlError2("xmlSetProp", NULL,
876 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
877 xmlUnlinkNode(res);
878 xmlFreeNode(res);
879 return(NULL);
880 }
881
882 return(res);
883 }
884
885
886 /***********************************************************************
887 *
888 * <enc:EncryptedKey> node
889 *
890 **********************************************************************/
891
892 /**
893 * xmlSecTmplReferenceListAddDataReference:
894 * @encNode: the pointer to <enc:EncryptedKey/> node.
895 * @uri: uri to reference (optional)
896 *
897 * Adds <enc:DataReference/> and the parent <enc:ReferenceList/> node (if needed).
898 *
899 * Returns: the pointer to newly created <enc:DataReference/> node or
900 * NULL if an error occurs.
901 */
902 xmlNodePtr
xmlSecTmplReferenceListAddDataReference(xmlNodePtr encNode,const xmlChar * uri)903 xmlSecTmplReferenceListAddDataReference(xmlNodePtr encNode, const xmlChar *uri) {
904 xmlNodePtr refListNode, res;
905
906 xmlSecAssert2(encNode != NULL, NULL);
907
908 refListNode = xmlSecFindChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
909 if(refListNode == NULL) {
910 refListNode = xmlSecAddChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
911 if(refListNode == NULL) {
912 xmlSecInternalError("xmlSecAddChild(xmlSecNodeReferenceList)", NULL);
913 return(NULL);
914 }
915 }
916
917 res = xmlSecAddChild(refListNode, xmlSecNodeDataReference, xmlSecEncNs);
918 if(res == NULL) {
919 xmlSecInternalError("xmlSecAddChild(xmlSecNodeDataReference)", NULL);
920 return(NULL);
921 }
922
923 if(uri != NULL) {
924 if(xmlSetProp(res, xmlSecAttrURI, uri) == NULL) {
925 xmlSecXmlError2("xmlSetProp", NULL,
926 "name=%s", xmlSecErrorsSafeString(xmlSecAttrURI));
927 xmlUnlinkNode(res);
928 xmlFreeNode(res);
929 return(NULL);
930 }
931 }
932
933 return(res);
934 }
935
936 /**
937 * xmlSecTmplReferenceListAddKeyReference:
938 * @encNode: the pointer to <enc:EncryptedKey/> node.
939 * @uri: uri to reference (optional)
940 *
941 * Adds <enc:KeyReference/> and the parent <enc:ReferenceList/> node (if needed).
942 *
943 * Returns: the pointer to newly created <enc:KeyReference/> node or
944 * NULL if an error occurs.
945 */
946 xmlNodePtr
xmlSecTmplReferenceListAddKeyReference(xmlNodePtr encNode,const xmlChar * uri)947 xmlSecTmplReferenceListAddKeyReference(xmlNodePtr encNode, const xmlChar *uri) {
948 xmlNodePtr refListNode, res;
949
950 xmlSecAssert2(encNode != NULL, NULL);
951
952 refListNode = xmlSecFindChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
953 if(refListNode == NULL) {
954 refListNode = xmlSecAddChild(encNode, xmlSecNodeReferenceList, xmlSecEncNs);
955 if(refListNode == NULL) {
956 xmlSecInternalError("xmlSecAddChild(xmlSecNodeReferenceList)", NULL);
957 return(NULL);
958 }
959 }
960
961 res = xmlSecAddChild(refListNode, xmlSecNodeKeyReference, xmlSecEncNs);
962 if(res == NULL) {
963 xmlSecInternalError("xmlSecAddChild(xmlSecNodeKeyReference)", NULL);
964 return(NULL);
965 }
966
967 if(uri != NULL) {
968 if(xmlSetProp(res, xmlSecAttrURI, uri) == NULL) {
969 xmlSecXmlError2("xmlSetProp", NULL,
970 "name=%s", xmlSecErrorsSafeString(xmlSecAttrURI));
971 xmlUnlinkNode(res);
972 xmlFreeNode(res);
973 return(NULL);
974 }
975 }
976
977 return(res);
978 }
979
980
981 /**************************************************************************
982 *
983 * <dsig:KeyInfo/> node
984 *
985 **************************************************************************/
986
987 /**
988 * xmlSecTmplKeyInfoAddKeyName:
989 * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
990 * @name: the key name (optional).
991 *
992 * Adds <dsig:KeyName/> node to the <dsig:KeyInfo/> node @keyInfoNode.
993 *
994 * Returns: the pointer to the newly created <dsig:KeyName/> node or
995 * NULL if an error occurs.
996 */
997 xmlNodePtr
xmlSecTmplKeyInfoAddKeyName(xmlNodePtr keyInfoNode,const xmlChar * name)998 xmlSecTmplKeyInfoAddKeyName(xmlNodePtr keyInfoNode, const xmlChar* name) {
999 xmlNodePtr res;
1000 int ret;
1001
1002 xmlSecAssert2(keyInfoNode != NULL, NULL);
1003
1004 res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyName, xmlSecDSigNs);
1005 if(res == NULL) {
1006 xmlSecInternalError("xmlSecAddChild(xmlSecNodeKeyName)", NULL);
1007 return(NULL);
1008 }
1009 if(name != NULL) {
1010 ret = xmlSecNodeEncodeAndSetContent(res, name);
1011 if(ret < 0) {
1012 xmlSecInternalError("xmlSecNodeEncodeAndSetContent", NULL);
1013 return(NULL);
1014 }
1015 }
1016 return(res);
1017 }
1018
1019 /**
1020 * xmlSecTmplKeyInfoAddKeyValue:
1021 * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
1022 *
1023 * Adds <dsig:KeyValue/> node to the <dsig:KeyInfo/> node @keyInfoNode.
1024 *
1025 * Returns: the pointer to the newly created <dsig:KeyValue/> node or
1026 * NULL if an error occurs.
1027 */
1028 xmlNodePtr
xmlSecTmplKeyInfoAddKeyValue(xmlNodePtr keyInfoNode)1029 xmlSecTmplKeyInfoAddKeyValue(xmlNodePtr keyInfoNode) {
1030 xmlNodePtr res;
1031
1032 xmlSecAssert2(keyInfoNode != NULL, NULL);
1033
1034 res = xmlSecAddChild(keyInfoNode, xmlSecNodeKeyValue, xmlSecDSigNs);
1035 if(res == NULL) {
1036 xmlSecInternalError("xmlSecAddChild(xmlSecNodeKeyValue)", NULL);
1037 return(NULL);
1038 }
1039
1040 return(res);
1041 }
1042
1043 /**
1044 * xmlSecTmplKeyInfoAddX509Data:
1045 * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
1046 *
1047 * Adds <dsig:X509Data/> node to the <dsig:KeyInfo/> node @keyInfoNode.
1048 *
1049 * Returns: the pointer to the newly created <dsig:X509Data/> node or
1050 * NULL if an error occurs.
1051 */
1052 xmlNodePtr
xmlSecTmplKeyInfoAddX509Data(xmlNodePtr keyInfoNode)1053 xmlSecTmplKeyInfoAddX509Data(xmlNodePtr keyInfoNode) {
1054 xmlNodePtr res;
1055
1056 xmlSecAssert2(keyInfoNode != NULL, NULL);
1057
1058 res = xmlSecAddChild(keyInfoNode, xmlSecNodeX509Data, xmlSecDSigNs);
1059 if(res == NULL) {
1060 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509Data)", NULL);
1061 return(NULL);
1062 }
1063
1064 return(res);
1065 }
1066
1067 /**
1068 * xmlSecTmplKeyInfoAddRetrievalMethod:
1069 * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
1070 * @uri: the URI attribute (optional).
1071 * @type: the Type attribute(optional).
1072 *
1073 * Adds <dsig:RetrievalMethod/> node to the <dsig:KeyInfo/> node @keyInfoNode.
1074 *
1075 * Returns: the pointer to the newly created <dsig:RetrievalMethod/> node or
1076 * NULL if an error occurs.
1077 */
1078 xmlNodePtr
xmlSecTmplKeyInfoAddRetrievalMethod(xmlNodePtr keyInfoNode,const xmlChar * uri,const xmlChar * type)1079 xmlSecTmplKeyInfoAddRetrievalMethod(xmlNodePtr keyInfoNode, const xmlChar *uri,
1080 const xmlChar *type) {
1081 xmlNodePtr res;
1082
1083 xmlSecAssert2(keyInfoNode != NULL, NULL);
1084
1085 res = xmlSecAddChild(keyInfoNode, xmlSecNodeRetrievalMethod, xmlSecDSigNs);
1086 if(res == NULL) {
1087 xmlSecInternalError("xmlSecAddChild(xmlSecNodeRetrievalMethod)", NULL);
1088 return(NULL);
1089 }
1090
1091 if(uri != NULL) {
1092 xmlSetProp(res, xmlSecAttrURI, uri);
1093 }
1094 if(type != NULL) {
1095 xmlSetProp(res, xmlSecAttrType, type);
1096 }
1097 return(res);
1098 }
1099
1100 /**
1101 * xmlSecTmplRetrievalMethodAddTransform:
1102 * @retrMethodNode: the pointer to <dsig:RetrievalMethod/> node.
1103 * @transformId: the transform id.
1104 *
1105 * Adds <dsig:Transform/> node (and the parent <dsig:Transforms/> node
1106 * if required) to the <dsig:RetrievalMethod/> node @retrMethod.
1107 *
1108 * Returns: the pointer to the newly created <dsig:Transforms/> node or
1109 * NULL if an error occurs.
1110 */
1111 xmlNodePtr
xmlSecTmplRetrievalMethodAddTransform(xmlNodePtr retrMethodNode,xmlSecTransformId transformId)1112 xmlSecTmplRetrievalMethodAddTransform(xmlNodePtr retrMethodNode, xmlSecTransformId transformId) {
1113 xmlNodePtr transformsNode;
1114 xmlNodePtr res;
1115
1116 xmlSecAssert2(retrMethodNode != NULL, NULL);
1117 xmlSecAssert2(transformId != NULL, NULL);
1118 xmlSecAssert2(transformId->href != NULL, NULL);
1119
1120 transformsNode = xmlSecFindChild(retrMethodNode, xmlSecNodeTransforms, xmlSecDSigNs);
1121 if(transformsNode == NULL) {
1122 transformsNode = xmlSecAddChild(retrMethodNode, xmlSecNodeTransforms, xmlSecDSigNs);
1123 if(transformsNode == NULL) {
1124 xmlSecInternalError("xmlSecAddChild(xmlSecNodeTransforms)", NULL);
1125 return(NULL);
1126 }
1127 }
1128
1129 res = xmlSecAddChild(transformsNode, xmlSecNodeTransform, xmlSecDSigNs);
1130 if(res == NULL) {
1131 xmlSecInternalError("xmlSecAddChild(xmlSecNodeTransform)", NULL);
1132 return(NULL);
1133 }
1134
1135 if(xmlSetProp(res, xmlSecAttrAlgorithm, transformId->href) == NULL) {
1136 xmlSecXmlError2("xmlSetProp", NULL,
1137 "name=%s", xmlSecErrorsSafeString(xmlSecAttrAlgorithm));
1138 xmlUnlinkNode(res);
1139 xmlFreeNode(res);
1140 return(NULL);
1141 }
1142
1143 return(res);
1144 }
1145
1146
1147 /**
1148 * xmlSecTmplKeyInfoAddEncryptedKey:
1149 * @keyInfoNode: the pointer to <dsig:KeyInfo/> node.
1150 * @encMethodId: the encryption method (optional).
1151 * @id: the Id attribute (optional).
1152 * @type: the Type attribute (optional).
1153 * @recipient: the Recipient attribute (optional).
1154 *
1155 * Adds <enc:EncryptedKey/> node with given attributes to
1156 * the <dsig:KeyInfo/> node @keyInfoNode.
1157 *
1158 * Returns: the pointer to the newly created <enc:EncryptedKey/> node or
1159 * NULL if an error occurs.
1160 */
1161 xmlNodePtr
xmlSecTmplKeyInfoAddEncryptedKey(xmlNodePtr keyInfoNode,xmlSecTransformId encMethodId,const xmlChar * id,const xmlChar * type,const xmlChar * recipient)1162 xmlSecTmplKeyInfoAddEncryptedKey(xmlNodePtr keyInfoNode, xmlSecTransformId encMethodId,
1163 const xmlChar* id, const xmlChar* type, const xmlChar* recipient) {
1164 xmlNodePtr encKeyNode;
1165
1166 xmlSecAssert2(keyInfoNode != NULL, NULL);
1167
1168 /* we allow multiple encrypted key elements */
1169 encKeyNode = xmlSecAddChild(keyInfoNode, xmlSecNodeEncryptedKey, xmlSecEncNs);
1170 if(encKeyNode == NULL) {
1171 xmlSecInternalError("xmlSecAddChild(xmlSecNodeEncryptedKey)", NULL);
1172 return(NULL);
1173 }
1174
1175 if(id != NULL) {
1176 xmlSetProp(encKeyNode, xmlSecAttrId, id);
1177 }
1178 if(type != NULL) {
1179 xmlSetProp(encKeyNode, xmlSecAttrType, type);
1180 }
1181 if(recipient != NULL) {
1182 xmlSetProp(encKeyNode, xmlSecAttrRecipient, recipient);
1183 }
1184
1185 if(xmlSecTmplPrepareEncData(encKeyNode, encMethodId) < 0) {
1186 xmlUnlinkNode(encKeyNode);
1187 xmlFreeNode(encKeyNode);
1188 return(NULL);
1189 }
1190 return(encKeyNode);
1191 }
1192
1193 /***********************************************************************
1194 *
1195 * <dsig:X509Data> node
1196 *
1197 **********************************************************************/
1198 /**
1199 * xmlSecTmplX509DataAddIssuerSerial:
1200 * @x509DataNode: the pointer to <dsig:X509Data/> node.
1201 *
1202 * Adds <dsig:X509IssuerSerial/> node to the given <dsig:X509Data/> node.
1203 *
1204 * Returns: the pointer to the newly created <dsig:X509IssuerSerial/> node or
1205 * NULL if an error occurs.
1206 */
1207
1208 xmlNodePtr
xmlSecTmplX509DataAddIssuerSerial(xmlNodePtr x509DataNode)1209 xmlSecTmplX509DataAddIssuerSerial(xmlNodePtr x509DataNode) {
1210 xmlNodePtr cur;
1211
1212 xmlSecAssert2(x509DataNode != NULL, NULL);
1213
1214 cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
1215 if(cur != NULL) {
1216 xmlSecNodeAlreadyPresentError(x509DataNode, xmlSecNodeX509IssuerSerial, NULL);
1217 return(NULL);
1218 }
1219
1220 cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509IssuerSerial, xmlSecDSigNs);
1221 if(cur == NULL) {
1222 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509IssuerSerial)", NULL);
1223 return(NULL);
1224 }
1225
1226 return (cur);
1227 }
1228
1229 /**
1230 * xmlSecTmplX509IssuerSerialAddIssuerName:
1231 * @x509IssuerSerialNode: the pointer to <dsig:X509IssuerSerial/> node.
1232 * @issuerName: the issuer name (optional).
1233 *
1234 * Adds <dsig:X509IssuerName/> node to the <dsig:X509IssuerSerial/> node @x509IssuerSerialNode.
1235 *
1236 * Returns: the pointer to the newly created <dsig:X509IssuerName/> node or
1237 * NULL if an error occurs.
1238 */
1239 xmlNodePtr
xmlSecTmplX509IssuerSerialAddIssuerName(xmlNodePtr x509IssuerSerialNode,const xmlChar * issuerName)1240 xmlSecTmplX509IssuerSerialAddIssuerName(xmlNodePtr x509IssuerSerialNode, const xmlChar* issuerName) {
1241 xmlNodePtr res;
1242 int ret;
1243
1244 xmlSecAssert2(x509IssuerSerialNode != NULL, NULL);
1245 if(xmlSecFindChild(x509IssuerSerialNode, xmlSecNodeX509IssuerName, xmlSecDSigNs) != NULL) {
1246 xmlSecNodeAlreadyPresentError(x509IssuerSerialNode, xmlSecNodeX509IssuerName, NULL);
1247 return(NULL);
1248 }
1249
1250 res = xmlSecAddChild(x509IssuerSerialNode, xmlSecNodeX509IssuerName, xmlSecDSigNs);
1251 if(res == NULL) {
1252 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509IssuerName)", NULL);
1253 return(NULL);
1254 }
1255
1256 if (issuerName != NULL) {
1257 ret = xmlSecNodeEncodeAndSetContent(res, issuerName);
1258 if(ret < 0) {
1259 xmlSecInternalError("xmlSecNodeEncodeAndSetContent", NULL);
1260 return(NULL);
1261 }
1262 }
1263 return(res);
1264 }
1265
1266 /**
1267 * xmlSecTmplX509IssuerSerialAddSerialNumber:
1268 * @x509IssuerSerialNode: the pointer to <dsig:X509IssuerSerial/> node.
1269 * @serial: the serial number (optional).
1270 *
1271 * Adds <dsig:X509SerialNumber/> node to the <dsig:X509IssuerSerial/> node @x509IssuerSerialNode.
1272 *
1273 * Returns: the pointer to the newly created <dsig:X509SerialNumber/> node or
1274 * NULL if an error occurs.
1275 */
1276 xmlNodePtr
xmlSecTmplX509IssuerSerialAddSerialNumber(xmlNodePtr x509IssuerSerialNode,const xmlChar * serial)1277 xmlSecTmplX509IssuerSerialAddSerialNumber(xmlNodePtr x509IssuerSerialNode, const xmlChar* serial) {
1278 xmlNodePtr res;
1279 int ret;
1280
1281 xmlSecAssert2(x509IssuerSerialNode != NULL, NULL);
1282
1283 if(xmlSecFindChild(x509IssuerSerialNode, xmlSecNodeX509SerialNumber, xmlSecDSigNs) != NULL) {
1284 xmlSecNodeAlreadyPresentError(x509IssuerSerialNode, xmlSecNodeX509SerialNumber, NULL);
1285 return(NULL);
1286 }
1287
1288 res = xmlSecAddChild(x509IssuerSerialNode, xmlSecNodeX509SerialNumber, xmlSecDSigNs);
1289 if(res == NULL) {
1290 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509SerialNumber)", NULL);
1291 return(NULL);
1292 }
1293
1294 if (serial != NULL) {
1295 ret = xmlSecNodeEncodeAndSetContent(res, serial);
1296 if(ret < 0) {
1297 xmlSecInternalError("xmlSecNodeEncodeAndSetContent", NULL);
1298 return(NULL);
1299 }
1300 }
1301 return(res);
1302 }
1303
1304 /**
1305 * xmlSecTmplX509DataAddSubjectName:
1306 * @x509DataNode: the pointer to <dsig:X509Data/> node.
1307 *
1308 * Adds <dsig:X509SubjectName/> node to the given <dsig:X509Data/> node.
1309 *
1310 * Returns: the pointer to the newly created <dsig:X509SubjectName/> node or
1311 * NULL if an error occurs.
1312 */
1313
1314 xmlNodePtr
xmlSecTmplX509DataAddSubjectName(xmlNodePtr x509DataNode)1315 xmlSecTmplX509DataAddSubjectName(xmlNodePtr x509DataNode) {
1316 xmlNodePtr cur;
1317
1318 xmlSecAssert2(x509DataNode != NULL, NULL);
1319
1320 cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509SubjectName, xmlSecDSigNs);
1321 if(cur != NULL) {
1322 xmlSecNodeAlreadyPresentError(x509DataNode, xmlSecNodeX509SubjectName, NULL);
1323 return(NULL);
1324 }
1325
1326 cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509SubjectName, xmlSecDSigNs);
1327 if(cur == NULL) {
1328 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509SubjectName)", NULL);
1329 return(NULL);
1330 }
1331
1332 return (cur);
1333 }
1334
1335 /**
1336 * xmlSecTmplX509DataAddSKI:
1337 * @x509DataNode: the pointer to <dsig:X509Data/> node.
1338 *
1339 * Adds <dsig:X509SKI/> node to the given <dsig:X509Data/> node.
1340 *
1341 * Returns: the pointer to the newly created <dsig:X509SKI/> node or
1342 * NULL if an error occurs.
1343 */
1344
1345 xmlNodePtr
xmlSecTmplX509DataAddSKI(xmlNodePtr x509DataNode)1346 xmlSecTmplX509DataAddSKI(xmlNodePtr x509DataNode) {
1347 xmlNodePtr cur;
1348
1349 xmlSecAssert2(x509DataNode != NULL, NULL);
1350
1351 cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509SKI, xmlSecDSigNs);
1352 if(cur != NULL) {
1353 xmlSecNodeAlreadyPresentError(x509DataNode, xmlSecNodeX509SKI, NULL);
1354 return(NULL);
1355 }
1356
1357 cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509SKI, xmlSecDSigNs);
1358 if(cur == NULL) {
1359 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509SKI)", NULL);
1360 return(NULL);
1361 }
1362
1363 return (cur);
1364 }
1365
1366
1367 /**
1368 * xmlSecTmplX509DataAddCertificate:
1369 * @x509DataNode: the pointer to <dsig:X509Data/> node.
1370 *
1371 * Adds <dsig:X509Certificate/> node to the given <dsig:X509Data/> node.
1372 *
1373 * Returns: the pointer to the newly created <dsig:X509Certificate/> node or
1374 * NULL if an error occurs.
1375 */
1376
1377 xmlNodePtr
xmlSecTmplX509DataAddCertificate(xmlNodePtr x509DataNode)1378 xmlSecTmplX509DataAddCertificate(xmlNodePtr x509DataNode) {
1379 xmlNodePtr cur;
1380
1381 xmlSecAssert2(x509DataNode != NULL, NULL);
1382
1383 cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
1384 if(cur != NULL) {
1385 xmlSecNodeAlreadyPresentError(x509DataNode, xmlSecNodeX509Certificate, NULL);
1386 return(NULL);
1387 }
1388
1389 cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509Certificate, xmlSecDSigNs);
1390 if(cur == NULL) {
1391 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509Certificate)", NULL);
1392 return(NULL);
1393 }
1394
1395 return (cur);
1396 }
1397
1398 /**
1399 * xmlSecTmplX509DataAddCRL:
1400 * @x509DataNode: the pointer to <dsig:X509Data/> node.
1401 *
1402 * Adds <dsig:X509CRL/> node to the given <dsig:X509Data/> node.
1403 *
1404 * Returns: the pointer to the newly created <dsig:X509CRL/> node or
1405 * NULL if an error occurs.
1406 */
1407
1408 xmlNodePtr
xmlSecTmplX509DataAddCRL(xmlNodePtr x509DataNode)1409 xmlSecTmplX509DataAddCRL(xmlNodePtr x509DataNode) {
1410 xmlNodePtr cur;
1411
1412 xmlSecAssert2(x509DataNode != NULL, NULL);
1413
1414 cur = xmlSecFindChild(x509DataNode, xmlSecNodeX509CRL, xmlSecDSigNs);
1415 if(cur != NULL) {
1416 xmlSecNodeAlreadyPresentError(x509DataNode, xmlSecNodeX509CRL, NULL);
1417 return(NULL);
1418 }
1419
1420 cur = xmlSecAddChild(x509DataNode, xmlSecNodeX509CRL, xmlSecDSigNs);
1421 if(cur == NULL) {
1422 xmlSecInternalError("xmlSecAddChild(xmlSecNodeX509CRL)", NULL);
1423 return(NULL);
1424 }
1425
1426 return (cur);
1427 }
1428
1429 /*************************************************************************
1430 *
1431 * <dsig:Transform/> node
1432 *
1433 ************************************************************************/
1434
1435 /**
1436 * xmlSecTmplTransformAddHmacOutputLength:
1437 * @transformNode: the pointer to <dsig:Transform/> node
1438 * @bitsLen: the required length in bits
1439 *
1440 * Creates <dsig:HMACOutputLength/> child for the HMAC transform
1441 * node @node.
1442 *
1443 * Returns: 0 on success and a negative value otherwise.
1444 */
1445 int
xmlSecTmplTransformAddHmacOutputLength(xmlNodePtr transformNode,xmlSecSize bitsLen)1446 xmlSecTmplTransformAddHmacOutputLength(xmlNodePtr transformNode, xmlSecSize bitsLen) {
1447 xmlNodePtr cur;
1448 char buf[64];
1449
1450 xmlSecAssert2(transformNode != NULL, -1);
1451 xmlSecAssert2(bitsLen > 0, -1);
1452
1453 cur = xmlSecFindChild(transformNode, xmlSecNodeHMACOutputLength, xmlSecDSigNs);
1454 if(cur != NULL) {
1455 xmlSecNodeAlreadyPresentError(transformNode, xmlSecNodeHMACOutputLength, NULL);
1456 return(-1);
1457 }
1458
1459 cur = xmlSecAddChild(transformNode, xmlSecNodeHMACOutputLength, xmlSecDSigNs);
1460 if(cur == NULL) {
1461 xmlSecInternalError("xmlSecAddChild(xmlSecNodeHMACOutputLength)", NULL);
1462 return(-1);
1463 }
1464
1465 #ifdef WIN32
1466 sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)bitsLen);
1467 #else /* WIN32 */
1468 sprintf(buf, "%lu", (unsigned long)bitsLen);
1469 #endif /* WIN32 */
1470 xmlNodeSetContent(cur, BAD_CAST buf);
1471 return(0);
1472 }
1473
1474 /**
1475 * xmlSecTmplTransformAddRsaOaepParam:
1476 * @transformNode: the pointer to <dsig:Transform/> node.
1477 * @buf: the OAEP param buffer.
1478 * @size: the OAEP param buffer size.
1479 *
1480 * Creates <enc:OAEPParam/> child node in the @node.
1481 *
1482 * Returns: 0 on success or a negative value if an error occurs.
1483 */
1484 int
xmlSecTmplTransformAddRsaOaepParam(xmlNodePtr transformNode,const xmlSecByte * buf,xmlSecSize size)1485 xmlSecTmplTransformAddRsaOaepParam(xmlNodePtr transformNode,
1486 const xmlSecByte *buf, xmlSecSize size) {
1487 xmlNodePtr oaepParamNode;
1488 xmlChar *base64;
1489
1490 xmlSecAssert2(transformNode != NULL, -1);
1491 xmlSecAssert2(buf != NULL, -1);
1492 xmlSecAssert2(size > 0, -1);
1493
1494 oaepParamNode = xmlSecFindChild(transformNode, xmlSecNodeRsaOAEPparams, xmlSecEncNs);
1495 if(oaepParamNode != NULL) {
1496 xmlSecNodeAlreadyPresentError(transformNode, xmlSecNodeRsaOAEPparams, NULL);
1497 return(-1);
1498 }
1499
1500 oaepParamNode = xmlSecAddChild(transformNode, xmlSecNodeRsaOAEPparams, xmlSecEncNs);
1501 if(oaepParamNode == NULL) {
1502 xmlSecInternalError("xmlSecAddChild(xmlSecNodeRsaOAEPparams)", NULL);
1503 return(-1);
1504 }
1505
1506 base64 = xmlSecBase64Encode(buf, size, 0);
1507 if(base64 == NULL) {
1508 xmlSecInternalError2("xmlSecBase64Encode", NULL, "size=%d", size);
1509 return(-1);
1510 }
1511
1512 xmlNodeSetContent(oaepParamNode, base64);
1513 xmlFree(base64);
1514 return(0);
1515 }
1516
1517 /**
1518 * xmlSecTmplTransformAddXsltStylesheet:
1519 * @transformNode: the pointer to <dsig:Transform/> node.
1520 * @xslt: the XSLT transform expression.
1521 *
1522 * Writes the XSLT transform expression to the @node.
1523 *
1524 * Returns: 0 on success or a negative value otherwise.
1525 */
1526 int
xmlSecTmplTransformAddXsltStylesheet(xmlNodePtr transformNode,const xmlChar * xslt)1527 xmlSecTmplTransformAddXsltStylesheet(xmlNodePtr transformNode, const xmlChar *xslt) {
1528 xmlDocPtr xsltDoc;
1529 int ret;
1530
1531 xmlSecAssert2(transformNode != NULL, -1);
1532 xmlSecAssert2(xslt != NULL, -1);
1533
1534 xsltDoc = xmlParseMemory((const char*)xslt, xmlStrlen(xslt));
1535 if(xsltDoc == NULL) {
1536 xmlSecXmlError("xmlParseMemory", NULL);
1537 return(-1);
1538 }
1539
1540 ret = xmlSecReplaceContent(transformNode, xmlDocGetRootElement(xsltDoc));
1541 if(ret < 0) {
1542 xmlSecInternalError("xmlSecReplaceContent", NULL);
1543 xmlFreeDoc(xsltDoc);
1544 return(-1);
1545 }
1546
1547 xmlFreeDoc(xsltDoc);
1548 return(0);
1549 }
1550
1551 /**
1552 * xmlSecTmplTransformAddC14NInclNamespaces:
1553 * @transformNode: the pointer to <dsig:Transform/> node.
1554 * @prefixList: the white space delimited list of namespace prefixes,
1555 * where "#default" indicates the default namespace
1556 * (optional).
1557 *
1558 * Adds "inclusive" namespaces to the ExcC14N transform node @node.
1559 *
1560 * Returns: 0 if success or a negative value otherwise.
1561 */
1562 int
xmlSecTmplTransformAddC14NInclNamespaces(xmlNodePtr transformNode,const xmlChar * prefixList)1563 xmlSecTmplTransformAddC14NInclNamespaces(xmlNodePtr transformNode,
1564 const xmlChar *prefixList) {
1565 xmlNodePtr cur;
1566
1567 xmlSecAssert2(transformNode != NULL, -1);
1568 xmlSecAssert2(prefixList != NULL, -1);
1569
1570 cur = xmlSecFindChild(transformNode, xmlSecNodeInclusiveNamespaces, xmlSecNsExcC14N);
1571 if(cur != NULL) {
1572 xmlSecNodeAlreadyPresentError(transformNode, xmlSecNodeInclusiveNamespaces, NULL);
1573 return(-1);
1574 }
1575
1576 cur = xmlSecAddChild(transformNode, xmlSecNodeInclusiveNamespaces, xmlSecNsExcC14N);
1577 if(cur == NULL) {
1578 xmlSecInternalError("xmlSecAddChild(xmlSecNodeInclusiveNamespaces)",
1579 xmlSecNodeGetName(transformNode));
1580 return(-1);
1581 }
1582
1583 xmlSetProp(cur, xmlSecAttrPrefixList, prefixList);
1584 return(0);
1585 }
1586
1587 /**
1588 * xmlSecTmplTransformAddXPath:
1589 * @transformNode: the pointer to the <dsig:Transform/> node.
1590 * @expression: the XPath expression.
1591 * @nsList: the NULL terminated list of namespace prefix/href pairs
1592 * (optional).
1593 *
1594 * Writes XPath transform information to the <dsig:Transform/> node
1595 * @node.
1596 *
1597 * Returns: 0 for success or a negative value otherwise.
1598 */
1599 int
xmlSecTmplTransformAddXPath(xmlNodePtr transformNode,const xmlChar * expression,const xmlChar ** nsList)1600 xmlSecTmplTransformAddXPath(xmlNodePtr transformNode, const xmlChar *expression,
1601 const xmlChar **nsList) {
1602 xmlNodePtr xpathNode;
1603 int ret;
1604
1605 xmlSecAssert2(transformNode != NULL, -1);
1606 xmlSecAssert2(expression != NULL, -1);
1607
1608 xpathNode = xmlSecFindChild(transformNode, xmlSecNodeXPath, xmlSecDSigNs);
1609 if(xpathNode != NULL) {
1610 xmlSecNodeAlreadyPresentError(transformNode, xmlSecNodeXPath, NULL);
1611 return(-1);
1612 }
1613
1614 xpathNode = xmlSecAddChild(transformNode, xmlSecNodeXPath, xmlSecDSigNs);
1615 if(xpathNode == NULL) {
1616 xmlSecInternalError("xmlSecAddChild(xmlSecNodeXPath)", NULL);
1617 return(-1);
1618 }
1619
1620 ret = xmlSecNodeEncodeAndSetContent(xpathNode, expression);
1621 if(ret < 0) {
1622 xmlSecInternalError("xmlSecNodeEncodeAndSetContent", NULL);
1623 return(-1);
1624 }
1625
1626 return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpathNode, nsList) : 0);
1627 }
1628
1629 /**
1630 * xmlSecTmplTransformAddXPath2:
1631 * @transformNode: the pointer to the <dsig:Transform/> node.
1632 * @type: the XPath2 transform type ("union", "intersect" or "subtract").
1633 * @expression: the XPath expression.
1634 * @nsList: the NULL terminated list of namespace prefix/href pairs.
1635 * (optional).
1636 *
1637 * Writes XPath2 transform information to the <dsig:Transform/> node
1638 * @node.
1639 *
1640 * Returns: 0 for success or a negative value otherwise.
1641 */
1642 int
xmlSecTmplTransformAddXPath2(xmlNodePtr transformNode,const xmlChar * type,const xmlChar * expression,const xmlChar ** nsList)1643 xmlSecTmplTransformAddXPath2(xmlNodePtr transformNode, const xmlChar* type,
1644 const xmlChar *expression, const xmlChar **nsList) {
1645 xmlNodePtr xpathNode;
1646 int ret;
1647
1648 xmlSecAssert2(transformNode != NULL, -1);
1649 xmlSecAssert2(type != NULL, -1);
1650 xmlSecAssert2(expression != NULL, -1);
1651
1652 xpathNode = xmlSecAddChild(transformNode, xmlSecNodeXPath, xmlSecXPath2Ns);
1653 if(xpathNode == NULL) {
1654 xmlSecInternalError("xmlSecAddChild(xmlSecNodeXPath)", NULL);
1655 return(-1);
1656 }
1657 xmlSetProp(xpathNode, xmlSecAttrFilter, type);
1658
1659 ret = xmlSecNodeEncodeAndSetContent(xpathNode, expression);
1660 if(ret < 0) {
1661 xmlSecInternalError("xmlSecNodeEncodeAndSetContent", NULL);
1662 return(-1);
1663 }
1664
1665 return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpathNode, nsList) : 0);
1666 }
1667
1668 /**
1669 * xmlSecTmplTransformAddXPointer:
1670 * @transformNode: the pointer to the <dsig:Transform/> node.
1671 * @expression: the XPath expression.
1672 * @nsList: the NULL terminated list of namespace prefix/href pairs.
1673 * (optional).
1674 *
1675 * Writes XPointer transform information to the <dsig:Transform/> node
1676 * @node.
1677 *
1678 * Returns: 0 for success or a negative value otherwise.
1679 */
1680 int
xmlSecTmplTransformAddXPointer(xmlNodePtr transformNode,const xmlChar * expression,const xmlChar ** nsList)1681 xmlSecTmplTransformAddXPointer(xmlNodePtr transformNode, const xmlChar *expression,
1682 const xmlChar **nsList) {
1683 xmlNodePtr xpointerNode;
1684 int ret;
1685
1686 xmlSecAssert2(expression != NULL, -1);
1687 xmlSecAssert2(transformNode != NULL, -1);
1688
1689 xpointerNode = xmlSecFindChild(transformNode, xmlSecNodeXPointer, xmlSecXPointerNs);
1690 if(xpointerNode != NULL) {
1691 xmlSecNodeAlreadyPresentError(transformNode, xmlSecNodeXPointer, NULL);
1692 return(-1);
1693 }
1694
1695 xpointerNode = xmlSecAddChild(transformNode, xmlSecNodeXPointer, xmlSecXPointerNs);
1696 if(xpointerNode == NULL) {
1697 xmlSecInternalError("xmlSecAddChild(xmlSecNodeXPointer)", NULL);
1698 return(-1);
1699 }
1700
1701 ret = xmlSecNodeEncodeAndSetContent(xpointerNode, expression);
1702 if(ret < 0) {
1703 xmlSecInternalError("xmlSecNodeEncodeAndSetContent", NULL);
1704 return(-1);
1705 }
1706
1707 return((nsList != NULL) ? xmlSecTmplNodeWriteNsList(xpointerNode, nsList) : 0);
1708 }
1709
1710 static int
xmlSecTmplNodeWriteNsList(xmlNodePtr parentNode,const xmlChar ** nsList)1711 xmlSecTmplNodeWriteNsList(xmlNodePtr parentNode, const xmlChar** nsList) {
1712 xmlNsPtr ns;
1713 const xmlChar *prefix;
1714 const xmlChar *href;
1715 const xmlChar **ptr;
1716
1717 xmlSecAssert2(parentNode != NULL, -1);
1718 xmlSecAssert2(nsList != NULL, -1);
1719
1720 /* nsList contains pairs of prefix/href with NULL at the end. We use special
1721 "#default" prefix instead of NULL prefix */
1722 ptr = nsList;
1723 while((*ptr) != NULL) {
1724 /* get next prefix/href pair */
1725 if(xmlStrEqual(BAD_CAST "#default", (*ptr))) {
1726 prefix = NULL;
1727 } else {
1728 prefix = (*ptr);
1729 }
1730 href = *(++ptr);
1731 if(href == NULL) {
1732 xmlSecInvalidDataError("unexpected end of ns list", NULL);
1733 return(-1);
1734 }
1735
1736 /* create namespace node */
1737 ns = xmlNewNs(parentNode, href, prefix);
1738 if(ns == NULL) {
1739 xmlSecXmlError2("xmlNewNs", NULL,
1740 "prefix=%s", xmlSecErrorsSafeString(prefix));
1741 return(-1);
1742 }
1743
1744 /* next pair */
1745 ++ptr;
1746 }
1747 return(0);
1748 }
1749