Line data Source code
1 : /**
2 : * XML Security Library (http://www.aleksey.com/xmlsec).
3 : *
4 : * XPath transform
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 : */
11 : #include "globals.h"
12 :
13 : #include <stdlib.h>
14 : #include <string.h>
15 :
16 : #include <libxml/tree.h>
17 : #include <libxml/xpath.h>
18 : #include <libxml/xpathInternals.h>
19 : #include <libxml/xpointer.h>
20 :
21 : #include <xmlsec/xmlsec.h>
22 : #include <xmlsec/xmltree.h>
23 : #include <xmlsec/keys.h>
24 : #include <xmlsec/list.h>
25 : #include <xmlsec/transforms.h>
26 : #include <xmlsec/errors.h>
27 :
28 :
29 : /**************************************************************************
30 : *
31 : * xmlSecXPathHereFunction:
32 : * @ctxt: the ponter to XPath context.
33 : * @nargs: the arguments nubmer.
34 : *
35 : * The implementation of XPath "here()" function.
36 : * See xmlXPtrHereFunction() in xpointer.c. the only change is that
37 : * we return NodeSet instead of NodeInterval.
38 : *
39 : *****************************************************************************/
40 : static void
41 0 : xmlSecXPathHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
42 0 : CHECK_ARITY(0);
43 :
44 0 : if((ctxt == NULL) || (ctxt->context == NULL) || (ctxt->context->here == NULL)) {
45 0 : XP_ERROR(XPTR_SYNTAX_ERROR);
46 : }
47 0 : valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->here));
48 : }
49 :
50 : /**************************************************************************
51 : *
52 : * XPath/XPointer data
53 : *
54 : *****************************************************************************/
55 : typedef struct _xmlSecXPathData xmlSecXPathData,
56 : *xmlSecXPathDataPtr;
57 : typedef enum {
58 : xmlSecXPathDataTypeXPath,
59 : xmlSecXPathDataTypeXPath2,
60 : xmlSecXPathDataTypeXPointer
61 : } xmlSecXPathDataType;
62 :
63 : struct _xmlSecXPathData {
64 : xmlSecXPathDataType type;
65 : xmlXPathContextPtr ctx;
66 : xmlChar* expr;
67 : xmlSecNodeSetOp nodeSetOp;
68 : xmlSecNodeSetType nodeSetType;
69 : };
70 :
71 : static xmlSecXPathDataPtr xmlSecXPathDataCreate (xmlSecXPathDataType type);
72 : static void xmlSecXPathDataDestroy (xmlSecXPathDataPtr data);
73 : static int xmlSecXPathDataSetExpr (xmlSecXPathDataPtr data,
74 : const xmlChar* expr);
75 : static int xmlSecXPathDataRegisterNamespaces(xmlSecXPathDataPtr data,
76 : xmlNodePtr node);
77 : static int xmlSecXPathDataNodeRead (xmlSecXPathDataPtr data,
78 : xmlNodePtr node);
79 : static xmlSecNodeSetPtr xmlSecXPathDataExecute (xmlSecXPathDataPtr data,
80 : xmlDocPtr doc,
81 : xmlNodePtr hereNode);
82 :
83 : static xmlSecXPathDataPtr
84 0 : xmlSecXPathDataCreate(xmlSecXPathDataType type) {
85 : xmlSecXPathDataPtr data;
86 :
87 0 : data = (xmlSecXPathDataPtr) xmlMalloc(sizeof(xmlSecXPathData));
88 0 : if(data == NULL) {
89 0 : xmlSecError(XMLSEC_ERRORS_HERE,
90 : NULL,
91 : NULL,
92 : XMLSEC_ERRORS_R_MALLOC_FAILED,
93 : "sizeof(xmlSecXPathData)=%d",
94 : sizeof(xmlSecXPathData));
95 0 : return(NULL);
96 : }
97 0 : memset(data, 0, sizeof(xmlSecXPathData));
98 :
99 0 : data->type = type;
100 0 : data->nodeSetType = xmlSecNodeSetTree;
101 :
102 : /* create xpath or xpointer context */
103 0 : switch(data->type) {
104 : case xmlSecXPathDataTypeXPath:
105 : case xmlSecXPathDataTypeXPath2:
106 0 : data->ctx = xmlXPathNewContext(NULL); /* we'll set doc in the context later */
107 0 : if(data->ctx == NULL) {
108 0 : xmlSecError(XMLSEC_ERRORS_HERE,
109 : NULL,
110 : "xmlXPathNewContext",
111 : XMLSEC_ERRORS_R_XML_FAILED,
112 : XMLSEC_ERRORS_NO_MESSAGE);
113 0 : xmlSecXPathDataDestroy(data);
114 0 : return(NULL);
115 : }
116 0 : break;
117 : case xmlSecXPathDataTypeXPointer:
118 0 : data->ctx = xmlXPtrNewContext(NULL, NULL, NULL); /* we'll set doc in the context later */
119 0 : if(data->ctx == NULL) {
120 0 : xmlSecError(XMLSEC_ERRORS_HERE,
121 : NULL,
122 : "xmlXPtrNewContext",
123 : XMLSEC_ERRORS_R_XML_FAILED,
124 : XMLSEC_ERRORS_NO_MESSAGE);
125 0 : xmlSecXPathDataDestroy(data);
126 0 : return(NULL);
127 : }
128 0 : break;
129 : }
130 :
131 0 : return(data);
132 : }
133 :
134 : static void
135 0 : xmlSecXPathDataDestroy(xmlSecXPathDataPtr data) {
136 0 : xmlSecAssert(data != NULL);
137 :
138 0 : if(data->expr != NULL) {
139 0 : xmlFree(data->expr);
140 : }
141 0 : if(data->ctx != NULL) {
142 0 : xmlXPathFreeContext(data->ctx);
143 : }
144 0 : memset(data, 0, sizeof(xmlSecXPathData));
145 0 : xmlFree(data);
146 : }
147 :
148 : static int
149 0 : xmlSecXPathDataSetExpr(xmlSecXPathDataPtr data, const xmlChar* expr) {
150 0 : xmlSecAssert2(data != NULL, -1);
151 0 : xmlSecAssert2(data->expr == NULL, -1);
152 0 : xmlSecAssert2(data->ctx != NULL, -1);
153 0 : xmlSecAssert2(expr != NULL, -1);
154 :
155 0 : data->expr = xmlStrdup(expr);
156 0 : if(data->expr == NULL) {
157 0 : xmlSecError(XMLSEC_ERRORS_HERE,
158 : NULL,
159 : NULL,
160 : XMLSEC_ERRORS_R_STRDUP_FAILED,
161 : XMLSEC_ERRORS_NO_MESSAGE);
162 0 : return(-1);
163 : }
164 0 : return(0);
165 : }
166 :
167 :
168 : static int
169 0 : xmlSecXPathDataRegisterNamespaces(xmlSecXPathDataPtr data, xmlNodePtr node) {
170 : xmlNodePtr cur;
171 : xmlNsPtr ns;
172 : int ret;
173 :
174 0 : xmlSecAssert2(data != NULL, -1);
175 0 : xmlSecAssert2(data->ctx != NULL, -1);
176 0 : xmlSecAssert2(node != NULL, -1);
177 :
178 : /* register namespaces */
179 0 : for(cur = node; cur != NULL; cur = cur->parent) {
180 0 : for(ns = cur->nsDef; ns != NULL; ns = ns->next) {
181 : /* check that we have no other namespace with same prefix already */
182 0 : if((ns->prefix != NULL) && (xmlXPathNsLookup(data->ctx, ns->prefix) == NULL)){
183 0 : ret = xmlXPathRegisterNs(data->ctx, ns->prefix, ns->href);
184 0 : if(ret != 0) {
185 0 : xmlSecError(XMLSEC_ERRORS_HERE,
186 : NULL,
187 : "xmlXPathRegisterNs",
188 : XMLSEC_ERRORS_R_XML_FAILED,
189 : "href=%s;prefix=%s",
190 0 : xmlSecErrorsSafeString(ns->href),
191 0 : xmlSecErrorsSafeString(ns->prefix));
192 0 : return(-1);
193 : }
194 : }
195 : }
196 : }
197 :
198 0 : return(0);
199 : }
200 :
201 : static int
202 0 : xmlSecXPathDataNodeRead(xmlSecXPathDataPtr data, xmlNodePtr node) {
203 : int ret;
204 :
205 0 : xmlSecAssert2(data != NULL, -1);
206 0 : xmlSecAssert2(data->expr == NULL, -1);
207 0 : xmlSecAssert2(data->ctx != NULL, -1);
208 0 : xmlSecAssert2(node != NULL, -1);
209 :
210 0 : ret = xmlSecXPathDataRegisterNamespaces (data, node);
211 0 : if(ret < 0) {
212 0 : xmlSecError(XMLSEC_ERRORS_HERE,
213 : NULL,
214 : "xmlSecXPathDataRegisterNamespaces",
215 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
216 : XMLSEC_ERRORS_NO_MESSAGE);
217 0 : return(-1);
218 : }
219 :
220 : /* read node content and set expr */
221 0 : data->expr = xmlNodeGetContent(node);
222 0 : if(data->expr == NULL) {
223 0 : xmlSecError(XMLSEC_ERRORS_HERE,
224 : NULL,
225 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
226 : XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
227 : XMLSEC_ERRORS_NO_MESSAGE);
228 0 : return(-1);
229 : }
230 :
231 0 : return(0);
232 : }
233 :
234 : static xmlSecNodeSetPtr
235 0 : xmlSecXPathDataExecute(xmlSecXPathDataPtr data, xmlDocPtr doc, xmlNodePtr hereNode) {
236 0 : xmlXPathObjectPtr xpathObj = NULL;
237 : xmlSecNodeSetPtr nodes;
238 :
239 0 : xmlSecAssert2(data != NULL, NULL);
240 0 : xmlSecAssert2(data->expr != NULL, NULL);
241 0 : xmlSecAssert2(data->ctx != NULL, NULL);
242 0 : xmlSecAssert2(doc != NULL, NULL);
243 0 : xmlSecAssert2(hereNode != NULL, NULL);
244 :
245 : /* do not forget to set the doc */
246 0 : data->ctx->doc = doc;
247 :
248 : /* here function works only on the same document */
249 0 : if(hereNode->doc == doc) {
250 0 : xmlXPathRegisterFunc(data->ctx, (xmlChar *)"here", xmlSecXPathHereFunction);
251 0 : data->ctx->here = hereNode;
252 0 : data->ctx->xptr = 1;
253 : }
254 :
255 : /* execute xpath or xpointer expression */
256 0 : switch(data->type) {
257 : case xmlSecXPathDataTypeXPath:
258 : case xmlSecXPathDataTypeXPath2:
259 0 : xpathObj = xmlXPathEvalExpression(data->expr, data->ctx);
260 0 : if(xpathObj == NULL) {
261 0 : xmlSecError(XMLSEC_ERRORS_HERE,
262 : NULL,
263 : "xmlXPathEvalExpression",
264 : XMLSEC_ERRORS_R_XML_FAILED,
265 : "expr=%s",
266 0 : xmlSecErrorsSafeString(data->expr));
267 0 : return(NULL);
268 : }
269 0 : break;
270 : case xmlSecXPathDataTypeXPointer:
271 0 : xpathObj = xmlXPtrEval(data->expr, data->ctx);
272 0 : if(xpathObj == NULL) {
273 0 : xmlSecError(XMLSEC_ERRORS_HERE,
274 : NULL,
275 : "xmlXPtrEval",
276 : XMLSEC_ERRORS_R_XML_FAILED,
277 : "expr=%s",
278 0 : xmlSecErrorsSafeString(data->expr));
279 0 : return(NULL);
280 : }
281 0 : break;
282 : }
283 :
284 0 : nodes = xmlSecNodeSetCreate(doc, xpathObj->nodesetval, data->nodeSetType);
285 0 : if(nodes == NULL) {
286 0 : xmlSecError(XMLSEC_ERRORS_HERE,
287 : NULL,
288 : "xmlSecNodeSetCreate",
289 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
290 0 : "type=%d", data->nodeSetType);
291 0 : xmlXPathFreeObject(xpathObj);
292 0 : return(NULL);
293 : }
294 0 : xpathObj->nodesetval = NULL;
295 0 : xmlXPathFreeObject(xpathObj);
296 :
297 0 : return(nodes);
298 : }
299 :
300 :
301 : /**************************************************************************
302 : *
303 : * XPath data list
304 : *
305 : *****************************************************************************/
306 : #define xmlSecXPathDataListId \
307 : xmlSecXPathDataListGetKlass()
308 : static xmlSecPtrListId xmlSecXPathDataListGetKlass (void);
309 : static xmlSecNodeSetPtr xmlSecXPathDataListExecute (xmlSecPtrListPtr dataList,
310 : xmlDocPtr doc,
311 : xmlNodePtr hereNode,
312 : xmlSecNodeSetPtr nodes);
313 :
314 : static xmlSecPtrListKlass xmlSecXPathDataListKlass = {
315 : BAD_CAST "xpath-data-list",
316 : NULL, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
317 : (xmlSecPtrDestroyItemMethod)xmlSecXPathDataDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */
318 : NULL, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
319 : NULL, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
320 : };
321 :
322 : static xmlSecPtrListId
323 0 : xmlSecXPathDataListGetKlass(void) {
324 0 : return(&xmlSecXPathDataListKlass);
325 : }
326 :
327 : static xmlSecNodeSetPtr
328 0 : xmlSecXPathDataListExecute(xmlSecPtrListPtr dataList, xmlDocPtr doc,
329 : xmlNodePtr hereNode, xmlSecNodeSetPtr nodes) {
330 : xmlSecXPathDataPtr data;
331 : xmlSecNodeSetPtr res, tmp, tmp2;
332 : xmlSecSize pos;
333 :
334 0 : xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), NULL);
335 0 : xmlSecAssert2(xmlSecPtrListGetSize(dataList) > 0, NULL);
336 0 : xmlSecAssert2(doc != NULL, NULL);
337 0 : xmlSecAssert2(hereNode != NULL, NULL);
338 :
339 0 : res = nodes;
340 0 : for(pos = 0; pos < xmlSecPtrListGetSize(dataList); ++pos) {
341 0 : data = (xmlSecXPathDataPtr)xmlSecPtrListGetItem(dataList, pos);
342 0 : if(data == NULL) {
343 0 : xmlSecError(XMLSEC_ERRORS_HERE,
344 : NULL,
345 : "xmlSecPtrListGetItem",
346 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
347 : "pos=%d", pos);
348 0 : if((res != NULL) && (res != nodes)) {
349 0 : xmlSecNodeSetDestroy(res);
350 : }
351 0 : return(NULL);
352 : }
353 :
354 0 : tmp = xmlSecXPathDataExecute(data, doc, hereNode);
355 0 : if(tmp == NULL) {
356 0 : xmlSecError(XMLSEC_ERRORS_HERE,
357 : NULL,
358 : "xmlSecXPathDataExecute",
359 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
360 : XMLSEC_ERRORS_NO_MESSAGE);
361 0 : if((res != NULL) && (res != nodes)) {
362 0 : xmlSecNodeSetDestroy(res);
363 : }
364 0 : return(NULL);
365 : }
366 :
367 0 : tmp2 = xmlSecNodeSetAdd(res, tmp, data->nodeSetOp);
368 0 : if(tmp2 == NULL) {
369 0 : xmlSecError(XMLSEC_ERRORS_HERE,
370 : NULL,
371 : "xmlSecNodeSetAdd",
372 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
373 : "xmlSecNodeSetIntersection");
374 0 : if((res != NULL) && (res != nodes)) {
375 0 : xmlSecNodeSetDestroy(res);
376 : }
377 0 : xmlSecNodeSetDestroy(tmp);
378 0 : return(NULL);
379 : }
380 0 : res = tmp2;
381 : }
382 :
383 0 : return(res);
384 : }
385 :
386 : /******************************************************************************
387 : *
388 : * XPath/XPointer transforms
389 : *
390 : * xmlSecXPathDataList is located after xmlSecTransform structure
391 : *
392 : *****************************************************************************/
393 : #define xmlSecXPathTransformSize \
394 : (sizeof(xmlSecTransform) + sizeof(xmlSecPtrList))
395 : #define xmlSecXPathTransformGetDataList(transform) \
396 : ((xmlSecTransformCheckSize((transform), xmlSecXPathTransformSize)) ? \
397 : (xmlSecPtrListPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)) : \
398 : (xmlSecPtrListPtr)NULL)
399 : #define xmlSecTransformXPathCheckId(transform) \
400 : (xmlSecTransformCheckId((transform), xmlSecTransformXPathId) || \
401 : xmlSecTransformCheckId((transform), xmlSecTransformXPath2Id) || \
402 : xmlSecTransformCheckId((transform), xmlSecTransformXPointerId))
403 :
404 : static int xmlSecTransformXPathInitialize (xmlSecTransformPtr transform);
405 : static void xmlSecTransformXPathFinalize (xmlSecTransformPtr transform);
406 : static int xmlSecTransformXPathExecute (xmlSecTransformPtr transform,
407 : int last,
408 : xmlSecTransformCtxPtr transformCtx);
409 :
410 : static int
411 0 : xmlSecTransformXPathInitialize(xmlSecTransformPtr transform) {
412 : xmlSecPtrListPtr dataList;
413 : int ret;
414 :
415 0 : xmlSecAssert2(xmlSecTransformXPathCheckId(transform), -1);
416 :
417 0 : dataList = xmlSecXPathTransformGetDataList(transform);
418 0 : xmlSecAssert2(dataList != NULL, -1);
419 :
420 0 : ret = xmlSecPtrListInitialize(dataList, xmlSecXPathDataListId);
421 0 : if(ret < 0) {
422 0 : xmlSecError(XMLSEC_ERRORS_HERE,
423 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
424 : "xmlSecPtrListInitialize",
425 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
426 : XMLSEC_ERRORS_NO_MESSAGE);
427 0 : return(-1);
428 : }
429 0 : return(0);
430 : }
431 :
432 : static void
433 0 : xmlSecTransformXPathFinalize(xmlSecTransformPtr transform) {
434 : xmlSecPtrListPtr dataList;
435 :
436 0 : xmlSecAssert(xmlSecTransformXPathCheckId(transform));
437 :
438 0 : dataList = xmlSecXPathTransformGetDataList(transform);
439 0 : xmlSecAssert(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId));
440 :
441 0 : xmlSecPtrListFinalize(dataList);
442 : }
443 :
444 : static int
445 0 : xmlSecTransformXPathExecute(xmlSecTransformPtr transform, int last,
446 : xmlSecTransformCtxPtr transformCtx) {
447 : xmlSecPtrListPtr dataList;
448 : xmlDocPtr doc;
449 :
450 0 : xmlSecAssert2(xmlSecTransformXPathCheckId(transform), -1);
451 0 : xmlSecAssert2(transform->hereNode != NULL, -1);
452 0 : xmlSecAssert2(transform->outNodes == NULL, -1);
453 0 : xmlSecAssert2(last != 0, -1);
454 0 : xmlSecAssert2(transformCtx != NULL, -1);
455 :
456 0 : dataList = xmlSecXPathTransformGetDataList(transform);
457 0 : xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
458 0 : xmlSecAssert2(xmlSecPtrListGetSize(dataList) > 0, -1);
459 :
460 0 : doc = (transform->inNodes != NULL) ? transform->inNodes->doc : transform->hereNode->doc;
461 0 : xmlSecAssert2(doc != NULL, -1);
462 :
463 0 : transform->outNodes = xmlSecXPathDataListExecute(dataList, doc,
464 : transform->hereNode, transform->inNodes);
465 0 : if(transform->outNodes == NULL) {
466 0 : xmlSecError(XMLSEC_ERRORS_HERE,
467 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
468 : "xmlSecXPathDataExecute",
469 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
470 : XMLSEC_ERRORS_NO_MESSAGE);
471 0 : return(-1);
472 : }
473 0 : return(0);
474 : }
475 :
476 : /******************************************************************************
477 : *
478 : * XPath transform
479 : *
480 : *****************************************************************************/
481 : static int xmlSecTransformXPathNodeRead (xmlSecTransformPtr transform,
482 : xmlNodePtr node,
483 : xmlSecTransformCtxPtr transformCtx);
484 :
485 : static xmlSecTransformKlass xmlSecTransformXPathKlass = {
486 : /* klass/object sizes */
487 : sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
488 : xmlSecXPathTransformSize, /* xmlSecSize objSize */
489 :
490 : xmlSecNameXPath, /* const xmlChar* name; */
491 : xmlSecXPathNs, /* const xmlChar* href; */
492 : xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
493 :
494 : xmlSecTransformXPathInitialize, /* xmlSecTransformInitializeMethod initialize; */
495 : xmlSecTransformXPathFinalize, /* xmlSecTransformFinalizeMethod finalize; */
496 : xmlSecTransformXPathNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
497 : NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
498 : NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
499 : NULL, /* xmlSecTransformSetKeyMethod setKey; */
500 : NULL, /* xmlSecTransformValidateMethod validate; */
501 : xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
502 : NULL, /* xmlSecTransformPushBinMethod pushBin; */
503 : NULL, /* xmlSecTransformPopBinMethod popBin; */
504 : xmlSecTransformDefaultPushXml, /* xmlSecTransformPushXmlMethod pushXml; */
505 : xmlSecTransformDefaultPopXml, /* xmlSecTransformPopXmlMethod popXml; */
506 : xmlSecTransformXPathExecute, /* xmlSecTransformExecuteMethod execute; */
507 :
508 : NULL, /* void* reserved0; */
509 : NULL, /* void* reserved1; */
510 : };
511 :
512 : /**
513 : * xmlSecTransformXPathGetKlass:
514 : *
515 : * The XPath transform evaluates given XPath expression and
516 : * intersects the result with the previous nodes set. See
517 : * http://www.w3.org/TR/xmldsig-core/#sec-XPath for more details.
518 : *
519 : * Returns: XPath transform id.
520 : */
521 : xmlSecTransformId
522 0 : xmlSecTransformXPathGetKlass(void) {
523 0 : return(&xmlSecTransformXPathKlass);
524 : }
525 :
526 : static const char xpathPattern[] = "(//. | //@* | //namespace::*)[boolean(%s)]";
527 : static int
528 0 : xmlSecTransformXPathNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
529 : xmlSecPtrListPtr dataList;
530 : xmlSecXPathDataPtr data;
531 : xmlNodePtr cur;
532 : xmlChar* tmp;
533 : int ret;
534 :
535 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPathId), -1);
536 0 : xmlSecAssert2(node != NULL, -1);
537 0 : xmlSecAssert2(transformCtx != NULL, -1);
538 :
539 0 : dataList = xmlSecXPathTransformGetDataList(transform);
540 0 : xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
541 0 : xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
542 :
543 : /* there is only one required node */
544 0 : cur = xmlSecGetNextElementNode(node->children);
545 0 : if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeXPath, xmlSecDSigNs))) {
546 0 : xmlSecError(XMLSEC_ERRORS_HERE,
547 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
548 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
549 : XMLSEC_ERRORS_R_INVALID_NODE,
550 : "expected=%s",
551 : xmlSecErrorsSafeString(xmlSecNodeXPath));
552 0 : return(-1);
553 : }
554 :
555 : /* read information from the node */
556 0 : data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPath);
557 0 : if(data == NULL) {
558 0 : xmlSecError(XMLSEC_ERRORS_HERE,
559 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
560 : "xmlSecXPathDataCreate",
561 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
562 : XMLSEC_ERRORS_NO_MESSAGE);
563 0 : return(-1);
564 : }
565 :
566 0 : ret = xmlSecXPathDataNodeRead(data, cur);
567 0 : if(ret < 0) {
568 0 : xmlSecError(XMLSEC_ERRORS_HERE,
569 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
570 : "xmlSecXPathDataNodeRead",
571 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
572 : XMLSEC_ERRORS_NO_MESSAGE);
573 0 : xmlSecXPathDataDestroy(data);
574 0 : return(-1);
575 : }
576 :
577 : /* append it to the list */
578 0 : ret = xmlSecPtrListAdd(dataList, data);
579 0 : if(ret < 0) {
580 0 : xmlSecError(XMLSEC_ERRORS_HERE,
581 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
582 : "xmlSecPtrListAdd",
583 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
584 : XMLSEC_ERRORS_NO_MESSAGE);
585 0 : xmlSecXPathDataDestroy(data);
586 0 : return(-1);
587 : }
588 :
589 : /* create full XPath expression */
590 0 : xmlSecAssert2(data->expr != NULL, -1);
591 0 : tmp = (xmlChar*) xmlMalloc(sizeof(xmlChar) * (xmlStrlen(data->expr) +
592 0 : strlen(xpathPattern) + 1));
593 0 : if(tmp == NULL) {
594 0 : xmlSecError(XMLSEC_ERRORS_HERE,
595 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
596 : NULL,
597 : XMLSEC_ERRORS_R_MALLOC_FAILED,
598 : "size=%d",
599 0 : xmlStrlen(data->expr) + strlen(xpathPattern) + 1);
600 0 : return(-1);
601 : }
602 0 : sprintf((char*)tmp, xpathPattern, (char*)data->expr);
603 0 : xmlFree(data->expr);
604 0 : data->expr = tmp;
605 :
606 : /* set correct node set type and operation */
607 0 : data->nodeSetOp = xmlSecNodeSetIntersection;
608 0 : data->nodeSetType = xmlSecNodeSetNormal;
609 :
610 : /* check that we have nothing else */
611 0 : cur = xmlSecGetNextElementNode(cur->next);
612 0 : if(cur != NULL) {
613 0 : xmlSecError(XMLSEC_ERRORS_HERE,
614 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
615 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
616 : XMLSEC_ERRORS_R_UNEXPECTED_NODE,
617 : XMLSEC_ERRORS_NO_MESSAGE);
618 0 : return(-1);
619 : }
620 0 : return(0);
621 : }
622 :
623 : /******************************************************************************
624 : *
625 : * XPath2 transform
626 : *
627 : *****************************************************************************/
628 : static int xmlSecTransformXPath2NodeRead (xmlSecTransformPtr transform,
629 : xmlNodePtr node,
630 : xmlSecTransformCtxPtr transformCtx);
631 : static xmlSecTransformKlass xmlSecTransformXPath2Klass = {
632 : /* klass/object sizes */
633 : sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
634 : xmlSecXPathTransformSize, /* xmlSecSize objSize */
635 :
636 : xmlSecNameXPath2, /* const xmlChar* name; */
637 : xmlSecXPath2Ns, /* const xmlChar* href; */
638 : xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
639 :
640 : xmlSecTransformXPathInitialize, /* xmlSecTransformInitializeMethod initialize; */
641 : xmlSecTransformXPathFinalize, /* xmlSecTransformFinalizeMethod finalize; */
642 : xmlSecTransformXPath2NodeRead, /* xmlSecTransformNodeReadMethod readNode; */
643 : NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
644 : NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
645 : NULL, /* xmlSecTransformSetKeyMethod setKey; */
646 : NULL, /* xmlSecTransformValidateMethod validate; */
647 : xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
648 : NULL, /* xmlSecTransformPushBinMethod pushBin; */
649 : NULL, /* xmlSecTransformPopBinMethod popBin; */
650 : xmlSecTransformDefaultPushXml, /* xmlSecTransformPushXmlMethod pushXml; */
651 : xmlSecTransformDefaultPopXml, /* xmlSecTransformPopXmlMethod popXml; */
652 : xmlSecTransformXPathExecute, /* xmlSecTransformExecuteMethod execute; */
653 :
654 : NULL, /* void* reserved0; */
655 : NULL, /* void* reserved1; */
656 : };
657 :
658 : /**
659 : * xmlSecTransformXPath2GetKlass:
660 : *
661 : * The XPath2 transform (http://www.w3.org/TR/xmldsig-filter2/).
662 : *
663 : * Returns: XPath2 transform klass.
664 : */
665 : xmlSecTransformId
666 0 : xmlSecTransformXPath2GetKlass(void) {
667 0 : return(&xmlSecTransformXPath2Klass);
668 : }
669 :
670 : static int
671 0 : xmlSecTransformXPath2NodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
672 : xmlSecPtrListPtr dataList;
673 : xmlSecXPathDataPtr data;
674 : xmlNodePtr cur;
675 : xmlChar* op;
676 : int ret;
677 :
678 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPath2Id), -1);
679 0 : xmlSecAssert2(node != NULL, -1);
680 0 : xmlSecAssert2(transformCtx != NULL, -1);
681 :
682 0 : dataList = xmlSecXPathTransformGetDataList(transform);
683 0 : xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
684 0 : xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
685 :
686 : /* There are only xpath nodes */
687 0 : cur = xmlSecGetNextElementNode(node->children);
688 0 : while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeXPath2, xmlSecXPath2Ns)) {
689 : /* read information from the node */
690 0 : data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPath2);
691 0 : if(data == NULL) {
692 0 : xmlSecError(XMLSEC_ERRORS_HERE,
693 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
694 : "xmlSecXPathDataCreate",
695 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
696 : XMLSEC_ERRORS_NO_MESSAGE);
697 0 : return(-1);
698 : }
699 :
700 0 : ret = xmlSecXPathDataNodeRead(data, cur);
701 0 : if(ret < 0) {
702 0 : xmlSecError(XMLSEC_ERRORS_HERE,
703 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
704 : "xmlSecXPathDataNodeRead",
705 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
706 : XMLSEC_ERRORS_NO_MESSAGE);
707 0 : xmlSecXPathDataDestroy(data);
708 0 : return(-1);
709 : }
710 :
711 : /* append it to the list */
712 0 : ret = xmlSecPtrListAdd(dataList, data);
713 0 : if(ret < 0) {
714 0 : xmlSecError(XMLSEC_ERRORS_HERE,
715 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
716 : "xmlSecPtrListAdd",
717 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
718 : XMLSEC_ERRORS_NO_MESSAGE);
719 0 : xmlSecXPathDataDestroy(data);
720 0 : return(-1);
721 : }
722 :
723 : /* set correct node set type and operation */
724 0 : data->nodeSetType = xmlSecNodeSetTree;
725 0 : op = xmlGetProp(cur, xmlSecAttrFilter);
726 0 : if(op == NULL) {
727 0 : xmlSecError(XMLSEC_ERRORS_HERE,
728 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
729 : xmlSecErrorsSafeString(xmlSecAttrFilter),
730 : XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
731 : "node=%s",
732 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
733 0 : return(-1);
734 : }
735 0 : if(xmlStrEqual(op, xmlSecXPath2FilterIntersect)) {
736 0 : data->nodeSetOp = xmlSecNodeSetIntersection;
737 0 : } else if(xmlStrEqual(op, xmlSecXPath2FilterSubtract)) {
738 0 : data->nodeSetOp = xmlSecNodeSetSubtraction;
739 0 : } else if(xmlStrEqual(op, xmlSecXPath2FilterUnion)) {
740 0 : data->nodeSetOp = xmlSecNodeSetUnion;
741 : } else {
742 0 : xmlSecError(XMLSEC_ERRORS_HERE,
743 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
744 : xmlSecErrorsSafeString(xmlSecAttrFilter),
745 : XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
746 : "filter=%s",
747 : xmlSecErrorsSafeString(op));
748 0 : xmlFree(op);
749 0 : return(-1);
750 : }
751 0 : xmlFree(op);
752 :
753 0 : cur = xmlSecGetNextElementNode(cur->next);
754 : }
755 :
756 : /* check that we have nothing else */
757 0 : if(cur != NULL) {
758 0 : xmlSecError(XMLSEC_ERRORS_HERE,
759 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
760 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
761 : XMLSEC_ERRORS_R_UNEXPECTED_NODE,
762 : XMLSEC_ERRORS_NO_MESSAGE);
763 0 : return(-1);
764 : }
765 0 : return(0);
766 : }
767 :
768 : /******************************************************************************
769 : *
770 : * XPointer transform
771 : *
772 : *****************************************************************************/
773 : static int xmlSecTransformXPointerNodeRead (xmlSecTransformPtr transform,
774 : xmlNodePtr node,
775 : xmlSecTransformCtxPtr transformCtx);
776 : static xmlSecTransformKlass xmlSecTransformXPointerKlass = {
777 : /* klass/object sizes */
778 : sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
779 : xmlSecXPathTransformSize, /* xmlSecSize objSize */
780 :
781 : xmlSecNameXPointer, /* const xmlChar* name; */
782 : xmlSecXPointerNs, /* const xmlChar* href; */
783 : xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
784 :
785 : xmlSecTransformXPathInitialize, /* xmlSecTransformInitializeMethod initialize; */
786 : xmlSecTransformXPathFinalize, /* xmlSecTransformFinalizeMethod finalize; */
787 : xmlSecTransformXPointerNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
788 : NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
789 : NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
790 : NULL, /* xmlSecTransformSetKeyMethod setKey; */
791 : NULL, /* xmlSecTransformValidateMethod validate; */
792 : xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
793 : NULL, /* xmlSecTransformPushBinMethod pushBin; */
794 : NULL, /* xmlSecTransformPopBinMethod popBin; */
795 : xmlSecTransformDefaultPushXml, /* xmlSecTransformPushXmlMethod pushXml; */
796 : xmlSecTransformDefaultPopXml, /* xmlSecTransformPopXmlMethod popXml; */
797 : xmlSecTransformXPathExecute, /* xmlSecTransformExecuteMethod execute; */
798 :
799 : NULL, /* void* reserved0; */
800 : NULL, /* void* reserved1; */
801 : };
802 :
803 : /**
804 : * xmlSecTransformXPointerGetKlass:
805 : *
806 : * The XPointer transform klass
807 : * (http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt).
808 : *
809 : * Returns: XPointer transform klass.
810 : */
811 : xmlSecTransformId
812 0 : xmlSecTransformXPointerGetKlass(void) {
813 0 : return(&xmlSecTransformXPointerKlass);
814 : }
815 :
816 : /**
817 : * xmlSecTransformXPointerSetExpr:
818 : * @transform: the pointer to XPointer transform.
819 : * @expr: the XPointer expression.
820 : * @nodeSetType: the type of evaluated XPointer expression.
821 : * @hereNode: the pointer to "here" node.
822 : *
823 : * Sets the XPointer expression for an XPointer @transform.
824 : *
825 : * Returns: 0 on success or a negative value if an error occurs.
826 : */
827 : int
828 0 : xmlSecTransformXPointerSetExpr(xmlSecTransformPtr transform, const xmlChar* expr,
829 : xmlSecNodeSetType nodeSetType, xmlNodePtr hereNode) {
830 : xmlSecPtrListPtr dataList;
831 : xmlSecXPathDataPtr data;
832 : int ret;
833 :
834 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPointerId), -1);
835 0 : xmlSecAssert2(transform->hereNode == NULL, -1);
836 0 : xmlSecAssert2(expr != NULL, -1);
837 0 : xmlSecAssert2(hereNode != NULL, -1);
838 :
839 0 : transform->hereNode = hereNode;
840 :
841 0 : dataList = xmlSecXPathTransformGetDataList(transform);
842 0 : xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
843 0 : xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
844 :
845 0 : data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPointer);
846 0 : if(data == NULL) {
847 0 : xmlSecError(XMLSEC_ERRORS_HERE,
848 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
849 : "xmlSecXPathDataCreate",
850 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
851 : XMLSEC_ERRORS_NO_MESSAGE);
852 0 : return(-1);
853 : }
854 :
855 0 : ret = xmlSecXPathDataRegisterNamespaces(data, hereNode);
856 0 : if(ret < 0) {
857 0 : xmlSecError(XMLSEC_ERRORS_HERE,
858 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
859 : "xmlSecXPathDataRegisterNamespaces",
860 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
861 : XMLSEC_ERRORS_NO_MESSAGE);
862 0 : xmlSecXPathDataDestroy(data);
863 0 : return(-1);
864 : }
865 :
866 0 : ret = xmlSecXPathDataSetExpr(data, expr);
867 0 : if(ret < 0) {
868 0 : xmlSecError(XMLSEC_ERRORS_HERE,
869 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
870 : "xmlSecXPathDataSetExpr",
871 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
872 : XMLSEC_ERRORS_NO_MESSAGE);
873 0 : xmlSecXPathDataDestroy(data);
874 0 : return(-1);
875 : }
876 :
877 : /* append it to the list */
878 0 : ret = xmlSecPtrListAdd(dataList, data);
879 0 : if(ret < 0) {
880 0 : xmlSecError(XMLSEC_ERRORS_HERE,
881 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
882 : "xmlSecPtrListAdd",
883 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
884 : XMLSEC_ERRORS_NO_MESSAGE);
885 0 : xmlSecXPathDataDestroy(data);
886 0 : return(-1);
887 : }
888 :
889 : /* set correct node set type and operation */
890 0 : data->nodeSetOp = xmlSecNodeSetIntersection;
891 0 : data->nodeSetType = nodeSetType;
892 :
893 0 : return(0);
894 : }
895 :
896 : static int
897 0 : xmlSecTransformXPointerNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
898 : xmlSecPtrListPtr dataList;
899 : xmlSecXPathDataPtr data;
900 : xmlNodePtr cur;
901 : int ret;
902 :
903 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformXPointerId), -1);
904 0 : xmlSecAssert2(node != NULL, -1);
905 0 : xmlSecAssert2(transformCtx != NULL, -1);
906 :
907 0 : dataList = xmlSecXPathTransformGetDataList(transform);
908 0 : xmlSecAssert2(xmlSecPtrListCheckId(dataList, xmlSecXPathDataListId), -1);
909 0 : xmlSecAssert2(xmlSecPtrListGetSize(dataList) == 0, -1);
910 :
911 : /* there is only one required node */
912 0 : cur = xmlSecGetNextElementNode(node->children);
913 0 : if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeXPointer, xmlSecXPointerNs))) {
914 0 : xmlSecError(XMLSEC_ERRORS_HERE,
915 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
916 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
917 : XMLSEC_ERRORS_R_INVALID_NODE,
918 : "expected=%s",
919 : xmlSecErrorsSafeString(xmlSecNodeXPath));
920 0 : return(-1);
921 : }
922 :
923 : /* read information from the node */
924 0 : data = xmlSecXPathDataCreate(xmlSecXPathDataTypeXPointer);
925 0 : if(data == NULL) {
926 0 : xmlSecError(XMLSEC_ERRORS_HERE,
927 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
928 : "xmlSecXPathDataCreate",
929 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
930 : XMLSEC_ERRORS_NO_MESSAGE);
931 0 : return(-1);
932 : }
933 :
934 0 : ret = xmlSecXPathDataNodeRead(data, cur);
935 0 : if(ret < 0) {
936 0 : xmlSecError(XMLSEC_ERRORS_HERE,
937 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
938 : "xmlSecXPathDataNodeRead",
939 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
940 : XMLSEC_ERRORS_NO_MESSAGE);
941 0 : xmlSecXPathDataDestroy(data);
942 0 : return(-1);
943 : }
944 :
945 : /* append it to the list */
946 0 : ret = xmlSecPtrListAdd(dataList, data);
947 0 : if(ret < 0) {
948 0 : xmlSecError(XMLSEC_ERRORS_HERE,
949 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
950 : "xmlSecPtrListAdd",
951 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
952 : XMLSEC_ERRORS_NO_MESSAGE);
953 0 : xmlSecXPathDataDestroy(data);
954 0 : return(-1);
955 : }
956 :
957 : /* set correct node set type and operation */
958 0 : data->nodeSetOp = xmlSecNodeSetIntersection;
959 0 : data->nodeSetType = xmlSecNodeSetTree;
960 :
961 : /* check that we have nothing else */
962 0 : cur = xmlSecGetNextElementNode(cur->next);
963 0 : if(cur != NULL) {
964 0 : xmlSecError(XMLSEC_ERRORS_HERE,
965 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
966 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
967 : XMLSEC_ERRORS_R_UNEXPECTED_NODE,
968 : XMLSEC_ERRORS_NO_MESSAGE);
969 0 : return(-1);
970 : }
971 0 : return(0);
972 : }
973 :
974 :
975 : /******************************************************************************
976 : *
977 : * Visa3DHack transform
978 : *
979 : *****************************************************************************/
980 : #define xmlSecVisa3DHackTransformSize \
981 : (sizeof(xmlSecTransform) + sizeof(xmlChar*))
982 : #define xmlSecVisa3DHackTransformGetIDPtr(transform) \
983 : ((xmlSecTransformCheckSize((transform), xmlSecVisa3DHackTransformSize)) ? \
984 : (xmlChar**)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)) : \
985 : (xmlChar**)NULL)
986 : #define xmlSecTransformVisa3DHackCheckId(transform) \
987 : (xmlSecTransformCheckId((transform), xmlSecTransformVisa3DHackId))
988 :
989 : static int xmlSecTransformVisa3DHackInitialize (xmlSecTransformPtr transform);
990 : static void xmlSecTransformVisa3DHackFinalize (xmlSecTransformPtr transform);
991 : static int xmlSecTransformVisa3DHackExecute (xmlSecTransformPtr transform,
992 : int last,
993 : xmlSecTransformCtxPtr transformCtx);
994 :
995 : static xmlSecTransformKlass xmlSecTransformVisa3DHackKlass = {
996 : /* klass/object sizes */
997 : sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
998 : xmlSecVisa3DHackTransformSize, /* xmlSecSize objSize */
999 :
1000 : BAD_CAST "Visa3DHackTransform", /* const xmlChar* name; */
1001 : NULL, /* const xmlChar* href; */
1002 : xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
1003 :
1004 : xmlSecTransformVisa3DHackInitialize, /* xmlSecTransformInitializeMethod initialize; */
1005 : xmlSecTransformVisa3DHackFinalize, /* xmlSecTransformFinalizeMethod finalize; */
1006 : NULL, /* xmlSecTransformNodeReadMethod readNode; */
1007 : NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
1008 : NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
1009 : NULL, /* xmlSecTransformSetKeyMethod setKey; */
1010 : NULL, /* xmlSecTransformValidateMethod validate; */
1011 : xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
1012 : NULL, /* xmlSecTransformPushBinMethod pushBin; */
1013 : NULL, /* xmlSecTransformPopBinMethod popBin; */
1014 : xmlSecTransformDefaultPushXml, /* xmlSecTransformPushXmlMethod pushXml; */
1015 : xmlSecTransformDefaultPopXml, /* xmlSecTransformPopXmlMethod popXml; */
1016 : xmlSecTransformVisa3DHackExecute, /* xmlSecTransformExecuteMethod execute; */
1017 :
1018 : NULL, /* void* reserved0; */
1019 : NULL, /* void* reserved1; */
1020 : };
1021 :
1022 : /**
1023 : * xmlSecTransformVisa3DHackGetKlass:
1024 : *
1025 : * The Visa3DHack transform klass. The only reason why we need this
1026 : * is Visa3D protocol. It doesn't follow XML/XPointer/XMLDSig specs and allows
1027 : * invalid XPointer expressions in the URI attribute. Since we couldn't evaluate
1028 : * such expressions thru XPath/XPointer engine, we need to have this hack here.
1029 : *
1030 : * Returns: Visa3DHack transform klass.
1031 : */
1032 : xmlSecTransformId
1033 0 : xmlSecTransformVisa3DHackGetKlass(void) {
1034 0 : return(&xmlSecTransformVisa3DHackKlass);
1035 : }
1036 :
1037 : /**
1038 : * xmlSecTransformVisa3DHackSetID:
1039 : * @transform: the pointer to Visa3DHack transform.
1040 : * @id: the ID value.
1041 : *
1042 : * Sets the ID value for an Visa3DHack @transform.
1043 : *
1044 : * Returns: 0 on success or a negative value if an error occurs.
1045 : */
1046 : int
1047 0 : xmlSecTransformVisa3DHackSetID(xmlSecTransformPtr transform, const xmlChar* id) {
1048 : xmlChar** idPtr;
1049 :
1050 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformVisa3DHackId), -1);
1051 0 : xmlSecAssert2(id != NULL, -1);
1052 :
1053 0 : idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
1054 0 : xmlSecAssert2(idPtr != NULL, -1);
1055 0 : xmlSecAssert2((*idPtr) == NULL, -1);
1056 :
1057 0 : (*idPtr) = xmlStrdup(id);
1058 0 : if((*idPtr) == NULL) {
1059 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1060 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1061 : "xmlStrdup",
1062 : XMLSEC_ERRORS_R_MALLOC_FAILED,
1063 : XMLSEC_ERRORS_NO_MESSAGE);
1064 0 : return(-1);
1065 : }
1066 :
1067 0 : return(0);
1068 : }
1069 :
1070 : static int
1071 0 : xmlSecTransformVisa3DHackInitialize(xmlSecTransformPtr transform) {
1072 0 : xmlSecAssert2(xmlSecTransformVisa3DHackCheckId(transform), -1);
1073 :
1074 0 : return(0);
1075 : }
1076 :
1077 : static void
1078 0 : xmlSecTransformVisa3DHackFinalize(xmlSecTransformPtr transform) {
1079 : xmlChar** idPtr;
1080 :
1081 0 : xmlSecAssert(xmlSecTransformVisa3DHackCheckId(transform));
1082 :
1083 0 : idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
1084 0 : xmlSecAssert(idPtr != NULL);
1085 :
1086 0 : if((*idPtr) != NULL) {
1087 0 : xmlFree((*idPtr));
1088 : }
1089 0 : (*idPtr) = NULL;
1090 : }
1091 :
1092 : static int
1093 0 : xmlSecTransformVisa3DHackExecute(xmlSecTransformPtr transform, int last,
1094 : xmlSecTransformCtxPtr transformCtx) {
1095 : xmlChar** idPtr;
1096 : xmlDocPtr doc;
1097 : xmlAttrPtr attr;
1098 : xmlNodeSetPtr nodeSet;
1099 :
1100 0 : xmlSecAssert2(xmlSecTransformVisa3DHackCheckId(transform), -1);
1101 0 : xmlSecAssert2(transform->outNodes == NULL, -1);
1102 0 : xmlSecAssert2(last != 0, -1);
1103 0 : xmlSecAssert2(transformCtx != NULL, -1);
1104 :
1105 0 : idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
1106 0 : xmlSecAssert2(idPtr != NULL, -1);
1107 0 : xmlSecAssert2((*idPtr) != NULL, -1);
1108 :
1109 0 : doc = (transform->inNodes != NULL) ? transform->inNodes->doc : transform->hereNode->doc;
1110 0 : xmlSecAssert2(doc != NULL, -1);
1111 :
1112 0 : attr = xmlGetID(doc, (*idPtr));
1113 0 : if((attr == NULL) || (attr->parent == NULL)) {
1114 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1115 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1116 : "xmlGetID",
1117 : XMLSEC_ERRORS_R_XML_FAILED,
1118 : "id=\"%s\"",
1119 0 : xmlSecErrorsSafeString((*idPtr)));
1120 0 : return(-1);
1121 : }
1122 :
1123 0 : nodeSet = xmlXPathNodeSetCreate(attr->parent);
1124 0 : if(nodeSet == NULL) {
1125 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1126 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1127 : "xmlXPathNodeSetCreate",
1128 : XMLSEC_ERRORS_R_XML_FAILED,
1129 : "id=\"%s\"",
1130 0 : xmlSecErrorsSafeString((*idPtr)));
1131 0 : return(-1);
1132 : }
1133 :
1134 0 : transform->outNodes = xmlSecNodeSetCreate(doc, nodeSet, xmlSecNodeSetTreeWithoutComments);
1135 0 : if(transform->outNodes == NULL) {
1136 0 : xmlSecError(XMLSEC_ERRORS_HERE,
1137 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
1138 : "xmlSecNodeSetCreate",
1139 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
1140 : XMLSEC_ERRORS_NO_MESSAGE);
1141 0 : xmlXPathFreeNodeSet(nodeSet);
1142 0 : return(-1);
1143 : }
1144 0 : return(0);
1145 : }
1146 :
1147 :
1148 :
|