Line data Source code
1 : /**
2 : * XML Security Library (http://www.aleksey.com/xmlsec).
3 : *
4 : * Enveloped 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 :
20 : #include <xmlsec/xmlsec.h>
21 : #include <xmlsec/xmltree.h>
22 : #include <xmlsec/keys.h>
23 : #include <xmlsec/transforms.h>
24 : #include <xmlsec/errors.h>
25 :
26 : /**************************************************************************
27 : *
28 : * Enveloped transform
29 : *
30 : *************************************************************************/
31 : static int xmlSecTransformEnvelopedExecute (xmlSecTransformPtr transform,
32 : int last,
33 : xmlSecTransformCtxPtr transformCtx);
34 :
35 :
36 : static xmlSecTransformKlass xmlSecTransformEnvelopedKlass = {
37 : /* klass/object sizes */
38 : sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
39 : sizeof(xmlSecTransform), /* xmlSecSize objSize */
40 :
41 : xmlSecNameEnveloped, /* const xmlChar* name; */
42 : xmlSecHrefEnveloped, /* const xmlChar* href; */
43 : xmlSecTransformUsageDSigTransform, /* xmlSecTransformUsage usage; */
44 :
45 : NULL, /* xmlSecTransformInitializeMethod initialize; */
46 : NULL, /* xmlSecTransformFinalizeMethod finalize; */
47 : NULL, /* xmlSecTransformNodeReadMethod readNode; */
48 : NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
49 : NULL, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
50 : NULL, /* xmlSecTransformSetKeyMethod setKey; */
51 : NULL, /* xmlSecTransformValidateMethod validate; */
52 : xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
53 : NULL, /* xmlSecTransformPushBinMethod pushBin; */
54 : NULL, /* xmlSecTransformPopBinMethod popBin; */
55 : xmlSecTransformDefaultPushXml, /* xmlSecTransformPushXmlMethod pushXml; */
56 : xmlSecTransformDefaultPopXml, /* xmlSecTransformPopXmlMethod popXml; */
57 : xmlSecTransformEnvelopedExecute, /* xmlSecTransformExecuteMethod execute; */
58 :
59 : NULL, /* void* reserved0; */
60 : NULL, /* void* reserved1; */
61 : };
62 :
63 : /**
64 : * xmlSecTransformEnvelopedGetKlass:
65 : *
66 : * The enveloped transform klass (http://www.w3.org/TR/xmldsig-core/#sec-EnvelopedSignature):
67 : *
68 : * An enveloped signature transform T removes the whole Signature element
69 : * containing T from the digest calculation of the Reference element
70 : * containing T. The entire string of characters used by an XML processor
71 : * to match the Signature with the XML production element is removed.
72 : * The output of the transform is equivalent to the output that would
73 : * result from replacing T with an XPath transform containing the following
74 : * XPath parameter element:
75 : *
76 : * <XPath xmlns:dsig="&dsig;">
77 : * count(ancestor-or-self::dsig:Signature |
78 : * here()/ancestor::dsig:Signature[1]) >
79 : * count(ancestor-or-self::dsig:Signature)</XPath>
80 : *
81 : * The input and output requirements of this transform are identical to
82 : * those of the XPath transform, but may only be applied to a node-set from
83 : * its parent XML document. Note that it is not necessary to use an XPath
84 : * expression evaluator to create this transform. However, this transform
85 : * MUST produce output in exactly the same manner as the XPath transform
86 : * parameterized by the XPath expression above.
87 : *
88 : * Returns: enveloped transform id.
89 : */
90 : xmlSecTransformId
91 0 : xmlSecTransformEnvelopedGetKlass(void) {
92 0 : return(&xmlSecTransformEnvelopedKlass);
93 : }
94 :
95 : static int
96 0 : xmlSecTransformEnvelopedExecute(xmlSecTransformPtr transform, int last,
97 : xmlSecTransformCtxPtr transformCtx) {
98 : xmlNodePtr node;
99 : xmlSecNodeSetPtr children;
100 :
101 0 : xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecTransformEnvelopedId), -1);
102 0 : xmlSecAssert2(transform->hereNode != NULL, -1);
103 0 : xmlSecAssert2(transform->outNodes == NULL, -1);
104 0 : xmlSecAssert2(last != 0, -1);
105 0 : xmlSecAssert2(transformCtx != NULL, -1);
106 :
107 0 : if((transform->inNodes != NULL) && (transform->inNodes->doc != transform->hereNode->doc)) {
108 0 : xmlSecError(XMLSEC_ERRORS_HERE,
109 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
110 : NULL,
111 : XMLSEC_ERRORS_R_TRANSFORM_SAME_DOCUMENT_REQUIRED,
112 : XMLSEC_ERRORS_NO_MESSAGE);
113 0 : return(-1);
114 : }
115 :
116 : /* find signature node and get all its children in the nodes set */
117 0 : node = xmlSecFindParent(transform->hereNode, xmlSecNodeSignature, xmlSecDSigNs);
118 0 : if(node == NULL) {
119 0 : xmlSecError(XMLSEC_ERRORS_HERE,
120 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
121 : xmlSecErrorsSafeString(xmlSecNodeSignature),
122 : XMLSEC_ERRORS_R_NODE_NOT_FOUND,
123 : XMLSEC_ERRORS_NO_MESSAGE);
124 0 : return(-1);
125 : }
126 :
127 0 : children = xmlSecNodeSetGetChildren(node->doc, node, 1, 1);
128 0 : if(children == NULL) {
129 0 : xmlSecError(XMLSEC_ERRORS_HERE,
130 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
131 : "xmlSecNodeSetGetChildren",
132 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
133 : "node=%s",
134 0 : xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
135 0 : return(-1);
136 : }
137 :
138 : /* intersect <dsig:Signature/> node children with input nodes (if exist) */
139 0 : transform->outNodes = xmlSecNodeSetAdd(transform->inNodes, children, xmlSecNodeSetIntersection);
140 0 : if(transform->outNodes == NULL) {
141 0 : xmlSecError(XMLSEC_ERRORS_HERE,
142 0 : xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
143 : "xmlSecNodeSetAdd",
144 : XMLSEC_ERRORS_R_XMLSEC_FAILED,
145 : XMLSEC_ERRORS_NO_MESSAGE);
146 0 : xmlSecNodeSetDestroy(children);
147 0 : return(-1);
148 : }
149 :
150 0 : return(0);
151 : }
152 :
|