File: | libxmlsec/unxlngi6.pro/misc/build/xmlsec1-1.2.14/src/xmldsig.c |
Location: | line 776, column 36 |
Description: | Access to field 'next' results in a dereference of a null pointer (loaded from variable 'cur') |
1 | /** | |||
2 | * XML Security Library (http://www.aleksey.com/xmlsec). | |||
3 | * | |||
4 | * "XML Digital Signature" implementation | |||
5 | * http://www.w3.org/TR/xmldsig-core/ | |||
6 | * http://www.w3.org/Signature/Overview.html | |||
7 | * | |||
8 | * This is free software; see Copyright file in the source | |||
9 | * distribution for preciese wording. | |||
10 | * | |||
11 | * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> | |||
12 | */ | |||
13 | #include "globals.h" | |||
14 | ||||
15 | #ifndef XMLSEC_NO_XMLDSIG | |||
16 | ||||
17 | #include <stdlib.h> | |||
18 | #include <stdio.h> | |||
19 | #include <string.h> | |||
20 | ||||
21 | #include <libxml/tree.h> | |||
22 | #include <libxml/parser.h> | |||
23 | ||||
24 | #include <xmlsec/xmlsec.h> | |||
25 | #include <xmlsec/buffer.h> | |||
26 | #include <xmlsec/xmltree.h> | |||
27 | #include <xmlsec/keys.h> | |||
28 | #include <xmlsec/keysmngr.h> | |||
29 | #include <xmlsec/transforms.h> | |||
30 | #include <xmlsec/membuf.h> | |||
31 | #include <xmlsec/xmldsig.h> | |||
32 | #include <xmlsec/errors.h> | |||
33 | ||||
34 | /************************************************************************** | |||
35 | * | |||
36 | * xmlSecDSigCtx | |||
37 | * | |||
38 | *************************************************************************/ | |||
39 | static int xmlSecDSigCtxProcessSignatureNode (xmlSecDSigCtxPtr dsigCtx, | |||
40 | xmlNodePtr node); | |||
41 | static int xmlSecDSigCtxProcessSignedInfoNode (xmlSecDSigCtxPtr dsigCtx, | |||
42 | xmlNodePtr node); | |||
43 | static int xmlSecDSigCtxProcessKeyInfoNode (xmlSecDSigCtxPtr dsigCtx, | |||
44 | xmlNodePtr node); | |||
45 | static int xmlSecDSigCtxProcessObjectNode (xmlSecDSigCtxPtr dsigCtx, | |||
46 | xmlNodePtr node); | |||
47 | static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCtx, | |||
48 | xmlNodePtr node); | |||
49 | ||||
50 | /* The ID attribute in XMLDSig is 'Id' */ | |||
51 | static const xmlChar* xmlSecDSigIds[] = { xmlSecAttrId, NULL((void*)0) }; | |||
52 | ||||
53 | /** | |||
54 | * xmlSecDSigCtxCreate: | |||
55 | * @keysMngr: the pointer to keys manager. | |||
56 | * | |||
57 | * Creates <dsig:Signature/> element processing context. | |||
58 | * The caller is responsible for destroying returend object by calling | |||
59 | * #xmlSecDSigCtxDestroy function. | |||
60 | * | |||
61 | * Returns: pointer to newly allocated context object or NULL if an error | |||
62 | * occurs. | |||
63 | */ | |||
64 | xmlSecDSigCtxPtr | |||
65 | xmlSecDSigCtxCreate(xmlSecKeysMngrPtr keysMngr) { | |||
66 | xmlSecDSigCtxPtr dsigCtx; | |||
67 | int ret; | |||
68 | ||||
69 | dsigCtx = (xmlSecDSigCtxPtr) xmlMalloc(sizeof(xmlSecDSigCtx)); | |||
70 | if(dsigCtx == NULL((void*)0)) { | |||
71 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",71,__FUNCTION__, | |||
72 | NULL((void*)0), | |||
73 | NULL((void*)0), | |||
74 | XMLSEC_ERRORS_R_MALLOC_FAILED2, | |||
75 | "sizeof(xmlSecDSigCtx)=%d", | |||
76 | sizeof(xmlSecDSigCtx)); | |||
77 | return(NULL((void*)0)); | |||
78 | } | |||
79 | ||||
80 | ret = xmlSecDSigCtxInitialize(dsigCtx, keysMngr); | |||
81 | if(ret < 0) { | |||
82 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",82,__FUNCTION__, | |||
83 | NULL((void*)0), | |||
84 | "xmlSecDSigCtxInitialize", | |||
85 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
86 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
87 | xmlSecDSigCtxDestroy(dsigCtx); | |||
88 | return(NULL((void*)0)); | |||
89 | } | |||
90 | return(dsigCtx); | |||
91 | } | |||
92 | ||||
93 | /** | |||
94 | * xmlSecDSigCtxDestroy: | |||
95 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
96 | * | |||
97 | * Destroy context object created with #xmlSecDSigCtxCreate function. | |||
98 | */ | |||
99 | void | |||
100 | xmlSecDSigCtxDestroy(xmlSecDSigCtxPtr dsigCtx) { | |||
101 | xmlSecAssert(dsigCtx != NULL)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",101 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return ; }; | |||
102 | ||||
103 | xmlSecDSigCtxFinalize(dsigCtx); | |||
104 | xmlFree(dsigCtx); | |||
105 | } | |||
106 | ||||
107 | /** | |||
108 | * xmlSecDSigCtxInitialize: | |||
109 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
110 | * @keysMngr: the pointer to keys manager. | |||
111 | * | |||
112 | * Initializes <dsig:Signature/> element processing context. | |||
113 | * The caller is responsible for cleaing up returend object by calling | |||
114 | * #xmlSecDSigCtxFinalize function. | |||
115 | * | |||
116 | * Returns: 0 on success or a negative value if an error occurs. | |||
117 | */ | |||
118 | int | |||
119 | xmlSecDSigCtxInitialize(xmlSecDSigCtxPtr dsigCtx, xmlSecKeysMngrPtr keysMngr) { | |||
120 | int ret; | |||
121 | ||||
122 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",122 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
123 | ||||
124 | memset(dsigCtx, 0, sizeof(xmlSecDSigCtx)); | |||
125 | ||||
126 | /* initialize key info */ | |||
127 | ret = xmlSecKeyInfoCtxInitialize(&(dsigCtx->keyInfoReadCtx), keysMngr); | |||
128 | if(ret < 0) { | |||
129 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",129,__FUNCTION__, | |||
130 | NULL((void*)0), | |||
131 | "xmlSecKeyInfoCtxInitialize", | |||
132 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
133 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
134 | return(-1); | |||
135 | } | |||
136 | dsigCtx->keyInfoReadCtx.mode = xmlSecKeyInfoModeRead; | |||
137 | ||||
138 | ret = xmlSecKeyInfoCtxInitialize(&(dsigCtx->keyInfoWriteCtx), keysMngr); | |||
139 | if(ret < 0) { | |||
140 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",140,__FUNCTION__, | |||
141 | NULL((void*)0), | |||
142 | "xmlSecKeyInfoCtxInitialize", | |||
143 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
144 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
145 | return(-1); | |||
146 | } | |||
147 | dsigCtx->keyInfoWriteCtx.mode = xmlSecKeyInfoModeWrite; | |||
148 | /* it's not wise to write private key :) */ | |||
149 | dsigCtx->keyInfoWriteCtx.keyReq.keyType = xmlSecKeyDataTypePublic0x0001; | |||
150 | ||||
151 | /* initializes transforms dsigCtx */ | |||
152 | ret = xmlSecTransformCtxInitialize(&(dsigCtx->transformCtx)); | |||
153 | if(ret < 0) { | |||
154 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",154,__FUNCTION__, | |||
155 | NULL((void*)0), | |||
156 | "xmlSecTransformCtxInitialize", | |||
157 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
158 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
159 | return(-1); | |||
160 | } | |||
161 | ||||
162 | /* references lists from SignedInfo and Manifest elements */ | |||
163 | xmlSecPtrListInitialize(&(dsigCtx->signedInfoReferences), | |||
164 | xmlSecDSigReferenceCtxListIdxmlSecDSigReferenceCtxListGetKlass()); | |||
165 | xmlSecPtrListInitialize(&(dsigCtx->manifestReferences), | |||
166 | xmlSecDSigReferenceCtxListIdxmlSecDSigReferenceCtxListGetKlass()); | |||
167 | ||||
168 | dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeAny0xFFFF; | |||
169 | return(0); | |||
170 | } | |||
171 | ||||
172 | /** | |||
173 | * xmlSecDSigCtxFinalize: | |||
174 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
175 | * | |||
176 | * Cleans up @dsigCtx object initialized with #xmlSecDSigCtxInitialize function. | |||
177 | */ | |||
178 | void | |||
179 | xmlSecDSigCtxFinalize(xmlSecDSigCtxPtr dsigCtx) { | |||
180 | xmlSecAssert(dsigCtx != NULL)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",180 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return ; }; | |||
181 | ||||
182 | xmlSecTransformCtxFinalize(&(dsigCtx->transformCtx)); | |||
183 | xmlSecKeyInfoCtxFinalize(&(dsigCtx->keyInfoReadCtx)); | |||
184 | xmlSecKeyInfoCtxFinalize(&(dsigCtx->keyInfoWriteCtx)); | |||
185 | xmlSecPtrListFinalize(&(dsigCtx->signedInfoReferences)); | |||
186 | xmlSecPtrListFinalize(&(dsigCtx->manifestReferences)); | |||
187 | ||||
188 | if(dsigCtx->enabledReferenceTransforms != NULL((void*)0)) { | |||
189 | xmlSecPtrListDestroy(dsigCtx->enabledReferenceTransforms); | |||
190 | } | |||
191 | if(dsigCtx->signKey != NULL((void*)0)) { | |||
192 | xmlSecKeyDestroy(dsigCtx->signKey); | |||
193 | } | |||
194 | if(dsigCtx->id != NULL((void*)0)) { | |||
195 | xmlFree(dsigCtx->id); | |||
196 | } | |||
197 | memset(dsigCtx, 0, sizeof(xmlSecDSigCtx)); | |||
198 | } | |||
199 | ||||
200 | /** | |||
201 | * xmlSecDSigCtxEnableReferenceTransform: | |||
202 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
203 | * @transformId: the transform klass. | |||
204 | * | |||
205 | * Enables @transformId for <dsig:Reference/> elements processing. | |||
206 | * | |||
207 | * Returns: 0 on success or a negative value if an error occurs. | |||
208 | */ | |||
209 | int | |||
210 | xmlSecDSigCtxEnableReferenceTransform(xmlSecDSigCtxPtr dsigCtx, xmlSecTransformId transformId) { | |||
211 | int ret; | |||
212 | ||||
213 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",213 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
214 | xmlSecAssert2(dsigCtx->result == NULL, -1)if(!( dsigCtx->result == ((void*)0) ) ) { xmlSecError("xmldsig.c" ,214,__FUNCTION__, ((void*)0), "dsigCtx->result == NULL", 100 , " "); return(-1); }; | |||
215 | xmlSecAssert2(transformId != xmlSecTransformIdUnknown, -1)if(!( transformId != ((xmlSecTransformId)((void*)0)) ) ) { xmlSecError ("xmldsig.c",215,__FUNCTION__, ((void*)0), "transformId != xmlSecTransformIdUnknown" , 100, " "); return(-1); }; | |||
216 | ||||
217 | if(dsigCtx->enabledReferenceTransforms == NULL((void*)0)) { | |||
218 | dsigCtx->enabledReferenceTransforms = xmlSecPtrListCreate(xmlSecTransformIdListIdxmlSecTransformIdListGetKlass()); | |||
219 | if(dsigCtx->enabledReferenceTransforms == NULL((void*)0)) { | |||
220 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",220,__FUNCTION__, | |||
221 | NULL((void*)0), | |||
222 | "xmlSecPtrListCreate", | |||
223 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
224 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
225 | return(-1); | |||
226 | } | |||
227 | } | |||
228 | ||||
229 | ret = xmlSecPtrListAdd(dsigCtx->enabledReferenceTransforms, (void*)transformId); | |||
230 | if(ret < 0) { | |||
231 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",231,__FUNCTION__, | |||
232 | NULL((void*)0), | |||
233 | "xmlSecPtrListAdd", | |||
234 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
235 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
236 | return(-1); | |||
237 | } | |||
238 | return(0); | |||
239 | } | |||
240 | ||||
241 | /** | |||
242 | * xmlSecDSigCtxEnableSignatureTransform: | |||
243 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
244 | * @transformId: the transform klass. | |||
245 | * | |||
246 | * Enables @transformId for <dsig:SignedInfo/> element processing. | |||
247 | * | |||
248 | * Returns: 0 on success or a negative value if an error occurs. | |||
249 | */ | |||
250 | int | |||
251 | xmlSecDSigCtxEnableSignatureTransform(xmlSecDSigCtxPtr dsigCtx, xmlSecTransformId transformId) { | |||
252 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",252 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
253 | xmlSecAssert2(dsigCtx->result == NULL, -1)if(!( dsigCtx->result == ((void*)0) ) ) { xmlSecError("xmldsig.c" ,253,__FUNCTION__, ((void*)0), "dsigCtx->result == NULL", 100 , " "); return(-1); }; | |||
254 | xmlSecAssert2(transformId != xmlSecTransformIdUnknown, -1)if(!( transformId != ((xmlSecTransformId)((void*)0)) ) ) { xmlSecError ("xmldsig.c",254,__FUNCTION__, ((void*)0), "transformId != xmlSecTransformIdUnknown" , 100, " "); return(-1); }; | |||
255 | ||||
256 | return(xmlSecPtrListAdd(&(dsigCtx->transformCtx.enabledTransforms), (void*)transformId)); | |||
257 | } | |||
258 | ||||
259 | /** | |||
260 | * xmlSecDSigCtxGetPreSignBuffer: | |||
261 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
262 | * | |||
263 | * Gets pointer to the buffer with serialized <dsig:SignedInfo/> element | |||
264 | * just before signature claculation (valid if and only if | |||
265 | * #XMLSEC_DSIG_FLAGS_STORE_SIGNATURE context flag is set. | |||
266 | * | |||
267 | * Returns: 0 on success or a negative value if an error occurs. | |||
268 | */ | |||
269 | xmlSecBufferPtr | |||
270 | xmlSecDSigCtxGetPreSignBuffer(xmlSecDSigCtxPtr dsigCtx) { | |||
271 | xmlSecAssert2(dsigCtx != NULL, NULL)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",271 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (((void*)0)); }; | |||
272 | ||||
273 | return((dsigCtx->preSignMemBufMethod != NULL((void*)0)) ? | |||
274 | xmlSecTransformMemBufGetBuffer(dsigCtx->preSignMemBufMethod) : NULL((void*)0)); | |||
275 | } | |||
276 | ||||
277 | /** | |||
278 | * xmlSecDSigCtxSign: | |||
279 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
280 | * @tmpl: the pointer to <dsig:Signature/> node with signature template. | |||
281 | * | |||
282 | * Signs the data as described in @tmpl node. | |||
283 | * | |||
284 | * Returns: 0 on success or a negative value if an error occurs. | |||
285 | */ | |||
286 | int | |||
287 | xmlSecDSigCtxSign(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr tmpl) { | |||
288 | int ret; | |||
289 | ||||
290 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",290 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
291 | xmlSecAssert2(dsigCtx->result == NULL, -1)if(!( dsigCtx->result == ((void*)0) ) ) { xmlSecError("xmldsig.c" ,291,__FUNCTION__, ((void*)0), "dsigCtx->result == NULL", 100 , " "); return(-1); }; | |||
292 | xmlSecAssert2(tmpl != NULL, -1)if(!( tmpl != ((void*)0) ) ) { xmlSecError("xmldsig.c",292,__FUNCTION__ , ((void*)0), "tmpl != NULL", 100, " "); return(-1); }; | |||
293 | xmlSecAssert2(tmpl->doc != NULL, -1)if(!( tmpl->doc != ((void*)0) ) ) { xmlSecError("xmldsig.c" ,293,__FUNCTION__, ((void*)0), "tmpl->doc != NULL", 100, " " ); return(-1); }; | |||
294 | ||||
295 | /* add ids for Signature nodes */ | |||
296 | dsigCtx->operation = xmlSecTransformOperationSign; | |||
297 | dsigCtx->status = xmlSecDSigStatusUnknown; | |||
298 | xmlSecAddIDs(tmpl->doc, tmpl, xmlSecDSigIds); | |||
299 | ||||
300 | /* read signature template */ | |||
301 | ret = xmlSecDSigCtxProcessSignatureNode(dsigCtx, tmpl); | |||
302 | if(ret < 0) { | |||
303 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",303,__FUNCTION__, | |||
304 | NULL((void*)0), | |||
305 | "xmlSecDSigCtxSigantureProcessNode", | |||
306 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
307 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
308 | return(-1); | |||
309 | } | |||
310 | xmlSecAssert2(dsigCtx->signMethod != NULL, -1)if(!( dsigCtx->signMethod != ((void*)0) ) ) { xmlSecError( "xmldsig.c",310,__FUNCTION__, ((void*)0), "dsigCtx->signMethod != NULL" , 100, " "); return(-1); }; | |||
311 | xmlSecAssert2(dsigCtx->signValueNode != NULL, -1)if(!( dsigCtx->signValueNode != ((void*)0) ) ) { xmlSecError ("xmldsig.c",311,__FUNCTION__, ((void*)0), "dsigCtx->signValueNode != NULL" , 100, " "); return(-1); }; | |||
312 | ||||
313 | /* references processing might change the status */ | |||
314 | if(dsigCtx->status != xmlSecDSigStatusUnknown) { | |||
315 | return(0); | |||
316 | } | |||
317 | ||||
318 | /* check what we've got */ | |||
319 | dsigCtx->result = dsigCtx->transformCtx.result; | |||
320 | if((dsigCtx->result == NULL((void*)0)) || (xmlSecBufferGetData(dsigCtx->result) == NULL((void*)0))) { | |||
321 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",321,__FUNCTION__, | |||
322 | NULL((void*)0), | |||
323 | NULL((void*)0), | |||
324 | XMLSEC_ERRORS_R_INVALID_RESULT13, | |||
325 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
326 | return(-1); | |||
327 | } | |||
328 | ||||
329 | /* write signed data to xml */ | |||
330 | xmlNodeSetContentLen(dsigCtx->signValueNode, | |||
331 | xmlSecBufferGetData(dsigCtx->result), | |||
332 | xmlSecBufferGetSize(dsigCtx->result)); | |||
333 | ||||
334 | /* set success status and we are done */ | |||
335 | dsigCtx->status = xmlSecDSigStatusSucceeded; | |||
336 | return(0); | |||
337 | } | |||
338 | ||||
339 | /** | |||
340 | * xmlSecDSigCtxVerify: | |||
341 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
342 | * @node: the pointer with <dsig:Signature/> node. | |||
343 | * | |||
344 | * Vaidates signature in the @node. The verification result is returned | |||
345 | * in #status member of the @dsigCtx object. | |||
346 | * | |||
347 | * Returns: 0 on success (check #status member of @dsigCtx to get | |||
348 | * signature verification result) or a negative value if an error occurs. | |||
349 | */ | |||
350 | int | |||
351 | xmlSecDSigCtxVerify(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) { | |||
352 | int ret; | |||
353 | ||||
354 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",354 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
355 | xmlSecAssert2(node != NULL, -1)if(!( node != ((void*)0) ) ) { xmlSecError("xmldsig.c",355,__FUNCTION__ , ((void*)0), "node != NULL", 100, " "); return(-1); }; | |||
356 | xmlSecAssert2(node->doc != NULL, -1)if(!( node->doc != ((void*)0) ) ) { xmlSecError("xmldsig.c" ,356,__FUNCTION__, ((void*)0), "node->doc != NULL", 100, " " ); return(-1); }; | |||
357 | ||||
358 | /* add ids for Signature nodes */ | |||
359 | dsigCtx->operation = xmlSecTransformOperationVerify; | |||
360 | dsigCtx->status = xmlSecDSigStatusUnknown; | |||
361 | xmlSecAddIDs(node->doc, node, xmlSecDSigIds); | |||
362 | ||||
363 | /* read siganture info */ | |||
364 | ret = xmlSecDSigCtxProcessSignatureNode(dsigCtx, node); | |||
365 | if(ret < 0) { | |||
366 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",366,__FUNCTION__, | |||
367 | NULL((void*)0), | |||
368 | "xmlSecDSigCtxSigantureProcessNode", | |||
369 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
370 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
371 | return(-1); | |||
372 | } | |||
373 | xmlSecAssert2(dsigCtx->signMethod != NULL, -1)if(!( dsigCtx->signMethod != ((void*)0) ) ) { xmlSecError( "xmldsig.c",373,__FUNCTION__, ((void*)0), "dsigCtx->signMethod != NULL" , 100, " "); return(-1); }; | |||
374 | xmlSecAssert2(dsigCtx->signValueNode != NULL, -1)if(!( dsigCtx->signValueNode != ((void*)0) ) ) { xmlSecError ("xmldsig.c",374,__FUNCTION__, ((void*)0), "dsigCtx->signValueNode != NULL" , 100, " "); return(-1); }; | |||
375 | ||||
376 | /* references processing might change the status */ | |||
377 | if(dsigCtx->status != xmlSecDSigStatusUnknown) { | |||
378 | return(0); | |||
379 | } | |||
380 | ||||
381 | /* verify SignatureValue node content */ | |||
382 | ret = xmlSecTransformVerifyNodeContent(dsigCtx->signMethod, dsigCtx->signValueNode, | |||
383 | &(dsigCtx->transformCtx)); | |||
384 | if(ret < 0) { | |||
385 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",385,__FUNCTION__, | |||
386 | NULL((void*)0), | |||
387 | "xmlSecTransformVerifyNodeContent", | |||
388 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
389 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
390 | return(-1); | |||
391 | } | |||
392 | ||||
393 | /* set status and we are done */ | |||
394 | if(dsigCtx->signMethod->status == xmlSecTransformStatusOk) { | |||
395 | dsigCtx->status = xmlSecDSigStatusSucceeded; | |||
396 | } else { | |||
397 | dsigCtx->status = xmlSecDSigStatusInvalid; | |||
398 | } | |||
399 | return(0); | |||
400 | } | |||
401 | ||||
402 | /** | |||
403 | * xmlSecDSigCtxProcessSignatureNode: | |||
404 | * | |||
405 | * The Signature element (http://www.w3.org/TR/xmldsig-core/#sec-Signature) | |||
406 | * | |||
407 | * The Signature element is the root element of an XML Signature. | |||
408 | * Implementation MUST generate laxly schema valid [XML-schema] Signature | |||
409 | * elements as specified by the following schema: | |||
410 | * The way in which the SignedInfo element is presented to the | |||
411 | * canonicalization method is dependent on that method. The following | |||
412 | * applies to algorithms which process XML as nodes or characters: | |||
413 | * | |||
414 | * - XML based canonicalization implementations MUST be provided with | |||
415 | * a [XPath] node-set originally formed from the document containing | |||
416 | * the SignedInfo and currently indicating the SignedInfo, its descendants, | |||
417 | * and the attribute and namespace nodes of SignedInfo and its descendant | |||
418 | * elements. | |||
419 | * | |||
420 | * - Text based canonicalization algorithms (such as CRLF and charset | |||
421 | * normalization) should be provided with the UTF-8 octets that represent | |||
422 | * the well-formed SignedInfo element, from the first character to the | |||
423 | * last character of the XML representation, inclusive. This includes | |||
424 | * the entire text of the start and end tags of the SignedInfo element | |||
425 | * as well as all descendant markup and character data (i.e., the text) | |||
426 | * between those tags. Use of text based canonicalization of SignedInfo | |||
427 | * is NOT RECOMMENDED. | |||
428 | * | |||
429 | * ================================= | |||
430 | * we do not support any non XML based C14N | |||
431 | * | |||
432 | * Schema Definition: | |||
433 | * | |||
434 | * <element name="Signature" type="ds:SignatureType"/> | |||
435 | * <complexType name="SignatureType"> | |||
436 | * <sequence> | |||
437 | * <element ref="ds:SignedInfo"/> | |||
438 | * <element ref="ds:SignatureValue"/> | |||
439 | * <element ref="ds:KeyInfo" minOccurs="0"/> | |||
440 | * <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/> | |||
441 | * </sequence> <attribute name="Id" type="ID" use="optional"/> | |||
442 | * </complexType> | |||
443 | * | |||
444 | * DTD: | |||
445 | * | |||
446 | * <!ELEMENT Signature (SignedInfo, SignatureValue, KeyInfo?, Object*) > | |||
447 | * <!ATTLIST Signature | |||
448 | * xmlns CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#' | |||
449 | * Id ID #IMPLIED > | |||
450 | * | |||
451 | */ | |||
452 | static int | |||
453 | xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) { | |||
454 | xmlSecTransformDataType firstType; | |||
455 | xmlNodePtr signedInfoNode = NULL((void*)0); | |||
456 | xmlNodePtr keyInfoNode = NULL((void*)0); | |||
457 | xmlNodePtr cur; | |||
458 | int ret; | |||
459 | ||||
460 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",460 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
461 | xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify), -1)if(!( (dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify) ) ) { xmlSecError("xmldsig.c",461,__FUNCTION__, ((void*)0), "(dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify)" , 100, " "); return(-1); }; | |||
462 | xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1)if(!( dsigCtx->status == xmlSecDSigStatusUnknown ) ) { xmlSecError ("xmldsig.c",462,__FUNCTION__, ((void*)0), "dsigCtx->status == xmlSecDSigStatusUnknown" , 100, " "); return(-1); }; | |||
463 | xmlSecAssert2(dsigCtx->signValueNode == NULL, -1)if(!( dsigCtx->signValueNode == ((void*)0) ) ) { xmlSecError ("xmldsig.c",463,__FUNCTION__, ((void*)0), "dsigCtx->signValueNode == NULL" , 100, " "); return(-1); }; | |||
464 | xmlSecAssert2(dsigCtx->signMethod == NULL, -1)if(!( dsigCtx->signMethod == ((void*)0) ) ) { xmlSecError( "xmldsig.c",464,__FUNCTION__, ((void*)0), "dsigCtx->signMethod == NULL" , 100, " "); return(-1); }; | |||
465 | xmlSecAssert2(dsigCtx->c14nMethod == NULL, -1)if(!( dsigCtx->c14nMethod == ((void*)0) ) ) { xmlSecError( "xmldsig.c",465,__FUNCTION__, ((void*)0), "dsigCtx->c14nMethod == NULL" , 100, " "); return(-1); }; | |||
466 | xmlSecAssert2(node != NULL, -1)if(!( node != ((void*)0) ) ) { xmlSecError("xmldsig.c",466,__FUNCTION__ , ((void*)0), "node != NULL", 100, " "); return(-1); }; | |||
467 | ||||
468 | if(!xmlSecCheckNodeName(node, xmlSecNodeSignature, xmlSecDSigNs)) { | |||
469 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",469,__FUNCTION__, | |||
470 | NULL((void*)0), | |||
471 | xmlSecErrorsSafeString(xmlSecNodeGetName(node))((((((node)) ? ((const char*)((node)->name)) : ((void*)0)) ) != ((void*)0)) ? ((char*)((((node)) ? ((const char*)((node) ->name)) : ((void*)0)))) : (char*)"NULL"), | |||
472 | XMLSEC_ERRORS_R_INVALID_NODE21, | |||
473 | "expected=%s", | |||
474 | xmlSecErrorsSafeString(xmlSecNodeSignature)(((xmlSecNodeSignature) != ((void*)0)) ? ((char*)(xmlSecNodeSignature )) : (char*)"NULL")); | |||
475 | return(-1); | |||
476 | } | |||
477 | ||||
478 | /* read node data */ | |||
479 | xmlSecAssert2(dsigCtx->id == NULL, -1)if(!( dsigCtx->id == ((void*)0) ) ) { xmlSecError("xmldsig.c" ,479,__FUNCTION__, ((void*)0), "dsigCtx->id == NULL", 100, " "); return(-1); }; | |||
480 | dsigCtx->id = xmlGetProp(node, xmlSecAttrId); | |||
481 | ||||
482 | /* first node is required SignedInfo */ | |||
483 | cur = xmlSecGetNextElementNode(node->children); | |||
484 | if((cur == NULL((void*)0)) || (!xmlSecCheckNodeName(cur, xmlSecNodeSignedInfo, xmlSecDSigNs))) { | |||
485 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",485,__FUNCTION__, | |||
486 | NULL((void*)0), | |||
487 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
488 | XMLSEC_ERRORS_R_INVALID_NODE21, | |||
489 | "expected=%s", | |||
490 | xmlSecErrorsSafeString(xmlSecNodeSignedInfo)(((xmlSecNodeSignedInfo) != ((void*)0)) ? ((char*)(xmlSecNodeSignedInfo )) : (char*)"NULL")); | |||
491 | return(-1); | |||
492 | } | |||
493 | signedInfoNode = cur; | |||
494 | cur = xmlSecGetNextElementNode(cur->next); | |||
495 | ||||
496 | /* next node is required SignatureValue */ | |||
497 | if((cur == NULL((void*)0)) || (!xmlSecCheckNodeName(cur, xmlSecNodeSignatureValue, xmlSecDSigNs))) { | |||
498 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",498,__FUNCTION__, | |||
499 | NULL((void*)0), | |||
500 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
501 | XMLSEC_ERRORS_R_INVALID_NODE21, | |||
502 | "expected=%s", | |||
503 | xmlSecErrorsSafeString(xmlSecNodeSignatureValue)(((xmlSecNodeSignatureValue) != ((void*)0)) ? ((char*)(xmlSecNodeSignatureValue )) : (char*)"NULL")); | |||
504 | return(-1); | |||
505 | } | |||
506 | dsigCtx->signValueNode = cur; | |||
507 | cur = xmlSecGetNextElementNode(cur->next); | |||
508 | ||||
509 | /* next node is optional KeyInfo */ | |||
510 | if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs))) { | |||
511 | keyInfoNode = cur; | |||
512 | cur = xmlSecGetNextElementNode(cur->next); | |||
513 | } else { | |||
514 | keyInfoNode = NULL((void*)0); | |||
515 | } | |||
516 | ||||
517 | /* next nodes are optional Object nodes */ | |||
518 | while((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeObject, xmlSecDSigNs))) { | |||
519 | /* read manifests from objects */ | |||
520 | if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_IGNORE_MANIFESTS0x00000001) == 0) { | |||
521 | ret = xmlSecDSigCtxProcessObjectNode(dsigCtx, cur); | |||
522 | if(ret < 0) { | |||
523 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",523,__FUNCTION__, | |||
524 | NULL((void*)0), | |||
525 | "xmlSecDSigCtxProcessObjectNode", | |||
526 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
527 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
528 | return(-1); | |||
529 | } | |||
530 | } | |||
531 | cur = xmlSecGetNextElementNode(cur->next); | |||
532 | } | |||
533 | ||||
534 | /* if there is something left than it's an error */ | |||
535 | if(cur != NULL((void*)0)) { | |||
536 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",536,__FUNCTION__, | |||
537 | NULL((void*)0), | |||
538 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
539 | XMLSEC_ERRORS_R_UNEXPECTED_NODE27, | |||
540 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
541 | return(-1); | |||
542 | } | |||
543 | ||||
544 | /* now validated all the references and prepare transform */ | |||
545 | ret = xmlSecDSigCtxProcessSignedInfoNode(dsigCtx, signedInfoNode); | |||
546 | if(ret < 0) { | |||
547 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",547,__FUNCTION__, | |||
548 | NULL((void*)0), | |||
549 | "xmlSecDSigCtxProcessSignedInfoNode", | |||
550 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
551 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
552 | return(-1); | |||
553 | } | |||
554 | /* references processing might change the status */ | |||
555 | if(dsigCtx->status != xmlSecDSigStatusUnknown) { | |||
556 | return(0); | |||
557 | } | |||
558 | ||||
559 | /* as the result, we should have sign and c14n methods set */ | |||
560 | xmlSecAssert2(dsigCtx->signMethod != NULL, -1)if(!( dsigCtx->signMethod != ((void*)0) ) ) { xmlSecError( "xmldsig.c",560,__FUNCTION__, ((void*)0), "dsigCtx->signMethod != NULL" , 100, " "); return(-1); }; | |||
561 | xmlSecAssert2(dsigCtx->c14nMethod != NULL, -1)if(!( dsigCtx->c14nMethod != ((void*)0) ) ) { xmlSecError( "xmldsig.c",561,__FUNCTION__, ((void*)0), "dsigCtx->c14nMethod != NULL" , 100, " "); return(-1); }; | |||
562 | ||||
563 | ret = xmlSecDSigCtxProcessKeyInfoNode(dsigCtx, keyInfoNode); | |||
564 | if(ret < 0) { | |||
565 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",565,__FUNCTION__, | |||
566 | NULL((void*)0), | |||
567 | "xmlSecDSigCtxProcessKeyInfoNode", | |||
568 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
569 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
570 | return(-1); | |||
571 | } | |||
572 | /* as the result, we should have a key */ | |||
573 | xmlSecAssert2(dsigCtx->signKey != NULL, -1)if(!( dsigCtx->signKey != ((void*)0) ) ) { xmlSecError("xmldsig.c" ,573,__FUNCTION__, ((void*)0), "dsigCtx->signKey != NULL", 100, " "); return(-1); }; | |||
574 | ||||
575 | /* if we need to write result to xml node then we need base64 encode result */ | |||
576 | if(dsigCtx->operation == xmlSecTransformOperationSign) { | |||
577 | xmlSecTransformPtr base64Encode; | |||
578 | ||||
579 | /* we need to add base64 encode transform */ | |||
580 | base64Encode = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), | |||
581 | xmlSecTransformBase64IdxmlSecTransformBase64GetKlass()); | |||
582 | if(base64Encode == NULL((void*)0)) { | |||
583 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",583,__FUNCTION__, | |||
584 | NULL((void*)0), | |||
585 | "xmlSecTransformCtxCreateAndAppend", | |||
586 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
587 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
588 | return(-1); | |||
589 | } | |||
590 | base64Encode->operation = xmlSecTransformOperationEncode; | |||
591 | } | |||
592 | ||||
593 | firstType = xmlSecTransformGetDataType(dsigCtx->transformCtx.first, | |||
594 | xmlSecTransformModePush, | |||
595 | &(dsigCtx->transformCtx)); | |||
596 | if((firstType & xmlSecTransformDataTypeXml0x0002) != 0) { | |||
597 | xmlSecNodeSetPtr nodeset = NULL((void*)0); | |||
598 | ||||
599 | xmlSecAssert2(signedInfoNode != NULL, -1)if(!( signedInfoNode != ((void*)0) ) ) { xmlSecError("xmldsig.c" ,599,__FUNCTION__, ((void*)0), "signedInfoNode != NULL", 100, " "); return(-1); }; | |||
600 | nodeset = xmlSecNodeSetGetChildren(signedInfoNode->doc, signedInfoNode, 1, 0); | |||
601 | if(nodeset == NULL((void*)0)) { | |||
602 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",602,__FUNCTION__, | |||
603 | NULL((void*)0), | |||
604 | "xmlSecNodeSetGetChildren", | |||
605 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
606 | "node=%s", | |||
607 | xmlSecErrorsSafeString(xmlSecNodeGetName(signedInfoNode))((((((signedInfoNode)) ? ((const char*)((signedInfoNode)-> name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((signedInfoNode )) ? ((const char*)((signedInfoNode)->name)) : ((void*)0)) )) : (char*)"NULL")); | |||
608 | return(-1); | |||
609 | } | |||
610 | ||||
611 | /* calculate the signature */ | |||
612 | ret = xmlSecTransformCtxXmlExecute(&(dsigCtx->transformCtx), nodeset); | |||
613 | if(ret < 0) { | |||
614 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",614,__FUNCTION__, | |||
615 | NULL((void*)0), | |||
616 | "xmlSecTransformCtxXmlExecute", | |||
617 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
618 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
619 | xmlSecNodeSetDestroy(nodeset); | |||
620 | return(-1); | |||
621 | } | |||
622 | xmlSecNodeSetDestroy(nodeset); | |||
623 | } else { | |||
624 | /* TODO */ | |||
625 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",625,__FUNCTION__, | |||
626 | NULL((void*)0), | |||
627 | "the binary c14n transforms are not supported yet", | |||
628 | XMLSEC_ERRORS_R_NOT_IMPLEMENTED9, | |||
629 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
630 | return(-1); | |||
631 | } | |||
632 | return(0); | |||
633 | } | |||
634 | ||||
635 | /** | |||
636 | * xmlSecDSigCtxProcessSignedInfoNode: | |||
637 | * | |||
638 | * The SignedInfo Element (http://www.w3.org/TR/xmldsig-core/#sec-SignedInfo) | |||
639 | * | |||
640 | * The structure of SignedInfo includes the canonicalization algorithm, | |||
641 | * a result algorithm, and one or more references. The SignedInfo element | |||
642 | * may contain an optional ID attribute that will allow it to be referenced by | |||
643 | * other signatures and objects. | |||
644 | * | |||
645 | * SignedInfo does not include explicit result or digest properties (such as | |||
646 | * calculation time, cryptographic device serial number, etc.). If an | |||
647 | * application needs to associate properties with the result or digest, | |||
648 | * it may include such information in a SignatureProperties element within | |||
649 | * an Object element. | |||
650 | * | |||
651 | * Schema Definition: | |||
652 | * | |||
653 | * <element name="SignedInfo" type="ds:SignedInfoType"/> | |||
654 | * <complexType name="SignedInfoType"> | |||
655 | * <sequence> | |||
656 | * <element ref="ds:CanonicalizationMethod"/> | |||
657 | * <element ref="ds:SignatureMethod"/> | |||
658 | * <element ref="ds:Reference" maxOccurs="unbounded"/> | |||
659 | * </sequence> | |||
660 | * <attribute name="Id" type="ID" use="optional"/> | |||
661 | * </complexType> | |||
662 | * | |||
663 | * DTD: | |||
664 | * | |||
665 | * <!ELEMENT SignedInfo (CanonicalizationMethod, SignatureMethod, Reference+) > | |||
666 | * <!ATTLIST SignedInfo Id ID #IMPLIED> | |||
667 | * | |||
668 | */ | |||
669 | static int | |||
670 | xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) { | |||
671 | xmlSecDSigReferenceCtxPtr dsigRefCtx; | |||
672 | xmlNodePtr cur; | |||
673 | int ret; | |||
674 | ||||
675 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",675 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
676 | xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1)if(!( dsigCtx->status == xmlSecDSigStatusUnknown ) ) { xmlSecError ("xmldsig.c",676,__FUNCTION__, ((void*)0), "dsigCtx->status == xmlSecDSigStatusUnknown" , 100, " "); return(-1); }; | |||
677 | xmlSecAssert2(dsigCtx->signMethod == NULL, -1)if(!( dsigCtx->signMethod == ((void*)0) ) ) { xmlSecError( "xmldsig.c",677,__FUNCTION__, ((void*)0), "dsigCtx->signMethod == NULL" , 100, " "); return(-1); }; | |||
678 | xmlSecAssert2(dsigCtx->c14nMethod == NULL, -1)if(!( dsigCtx->c14nMethod == ((void*)0) ) ) { xmlSecError( "xmldsig.c",678,__FUNCTION__, ((void*)0), "dsigCtx->c14nMethod == NULL" , 100, " "); return(-1); }; | |||
679 | xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify), -1)if(!( (dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify) ) ) { xmlSecError("xmldsig.c",679,__FUNCTION__, ((void*)0), "(dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify)" , 100, " "); return(-1); }; | |||
680 | xmlSecAssert2(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0, -1)if(!( xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences )) == 0 ) ) { xmlSecError("xmldsig.c",680,__FUNCTION__, ((void *)0), "xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0" , 100, " "); return(-1); }; | |||
681 | xmlSecAssert2(node != NULL, -1)if(!( node != ((void*)0) ) ) { xmlSecError("xmldsig.c",681,__FUNCTION__ , ((void*)0), "node != NULL", 100, " "); return(-1); }; | |||
682 | ||||
683 | /* first node is required CanonicalizationMethod. */ | |||
684 | cur = xmlSecGetNextElementNode(node->children); | |||
685 | if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs))) { | |||
| ||||
686 | dsigCtx->c14nMethod = xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx), | |||
687 | cur, xmlSecTransformUsageC14NMethod0x0002); | |||
688 | if(dsigCtx->c14nMethod == NULL((void*)0)) { | |||
689 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",689,__FUNCTION__, | |||
690 | NULL((void*)0), | |||
691 | "xmlSecTransformCtxNodeRead", | |||
692 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
693 | "node=%s", | |||
694 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL")); | |||
695 | return(-1); | |||
696 | } | |||
697 | } else if(dsigCtx->defC14NMethodId != xmlSecTransformIdUnknown((xmlSecTransformId)((void*)0))) { | |||
698 | /* the dsig spec does require CanonicalizationMethod node | |||
699 | * to be present but in some case it application might decide to | |||
700 | * minimize traffic */ | |||
701 | dsigCtx->c14nMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), | |||
702 | dsigCtx->defC14NMethodId); | |||
703 | if(dsigCtx->c14nMethod == NULL((void*)0)) { | |||
704 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",704,__FUNCTION__, | |||
705 | NULL((void*)0), | |||
706 | "xmlSecTransformCtxAppend", | |||
707 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
708 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
709 | return(-1); | |||
710 | } | |||
711 | } else { | |||
712 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",712,__FUNCTION__, | |||
713 | NULL((void*)0), | |||
714 | "CanonicalizationMethod", | |||
715 | XMLSEC_ERRORS_R_INVALID_NODE21, | |||
716 | "expected=%s", | |||
717 | xmlSecErrorsSafeString(xmlSecNodeCanonicalizationMethod)(((xmlSecNodeCanonicalizationMethod) != ((void*)0)) ? ((char* )(xmlSecNodeCanonicalizationMethod)) : (char*)"NULL")); | |||
718 | return(-1); | |||
719 | } | |||
720 | ||||
721 | /* insert membuf if requested */ | |||
722 | if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE0x00000008) != 0) { | |||
723 | xmlSecAssert2(dsigCtx->preSignMemBufMethod == NULL, -1)if(!( dsigCtx->preSignMemBufMethod == ((void*)0) ) ) { xmlSecError ("xmldsig.c",723,__FUNCTION__, ((void*)0), "dsigCtx->preSignMemBufMethod == NULL" , 100, " "); return(-1); }; | |||
724 | dsigCtx->preSignMemBufMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), | |||
725 | xmlSecTransformMemBufIdxmlSecTransformMemBufGetKlass()); | |||
726 | if(dsigCtx->preSignMemBufMethod == NULL((void*)0)) { | |||
727 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",727,__FUNCTION__, | |||
728 | NULL((void*)0), | |||
729 | "xmlSecTransformCtxCreateAndAppend", | |||
730 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
731 | "transform=%s", | |||
732 | xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecTransformMemBufId))((((((xmlSecTransformMemBufGetKlass())) ? ((xmlSecTransformMemBufGetKlass ())->name) : ((void*)0))) != ((void*)0)) ? ((char*)((((xmlSecTransformMemBufGetKlass ())) ? ((xmlSecTransformMemBufGetKlass())->name) : ((void* )0)))) : (char*)"NULL")); | |||
733 | } | |||
734 | } | |||
735 | ||||
736 | /* next node is required SignatureMethod. */ | |||
737 | cur = xmlSecGetNextElementNode( ((cur != NULL((void*)0)) ? cur->next : node->children) ); | |||
738 | if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeSignatureMethod, xmlSecDSigNs))) { | |||
739 | dsigCtx->signMethod = xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx), | |||
740 | cur, xmlSecTransformUsageSignatureMethod0x0008); | |||
741 | if(dsigCtx->signMethod == NULL((void*)0)) { | |||
742 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",742,__FUNCTION__, | |||
743 | NULL((void*)0), | |||
744 | "xmlSecTransformCtxNodeRead", | |||
745 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
746 | "node=%s", | |||
747 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL")); | |||
748 | return(-1); | |||
749 | } | |||
750 | } else if(dsigCtx->defSignMethodId != xmlSecTransformIdUnknown((xmlSecTransformId)((void*)0))) { | |||
751 | /* the dsig spec does require SignatureMethod node | |||
752 | * to be present but in some case it application might decide to | |||
753 | * minimize traffic */ | |||
754 | dsigCtx->signMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), | |||
755 | dsigCtx->defSignMethodId); | |||
756 | if(dsigCtx->signMethod == NULL((void*)0)) { | |||
757 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",757,__FUNCTION__, | |||
758 | NULL((void*)0), | |||
759 | "xmlSecTransformCtxAppend", | |||
760 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
761 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
762 | return(-1); | |||
763 | } | |||
764 | } else { | |||
765 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",765,__FUNCTION__, | |||
766 | NULL((void*)0), | |||
767 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
768 | XMLSEC_ERRORS_R_INVALID_NODE21, | |||
769 | "expected=%s", | |||
770 | xmlSecErrorsSafeString(xmlSecNodeSignatureMethod)(((xmlSecNodeSignatureMethod) != ((void*)0)) ? ((char*)(xmlSecNodeSignatureMethod )) : (char*)"NULL")); | |||
771 | return(-1); | |||
772 | } | |||
773 | dsigCtx->signMethod->operation = dsigCtx->operation; | |||
774 | ||||
775 | /* calculate references */ | |||
776 | cur = xmlSecGetNextElementNode(cur->next); | |||
| ||||
777 | while((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs))) { | |||
778 | /* create reference */ | |||
779 | dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginSignedInfo); | |||
780 | if(dsigRefCtx == NULL((void*)0)) { | |||
781 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",781,__FUNCTION__, | |||
782 | NULL((void*)0), | |||
783 | "xmlSecDSigReferenceCtxCreate", | |||
784 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
785 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
786 | return(-1); | |||
787 | } | |||
788 | ||||
789 | /* add to the list */ | |||
790 | ret = xmlSecPtrListAdd(&(dsigCtx->signedInfoReferences), dsigRefCtx); | |||
791 | if(ret < 0) { | |||
792 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",792,__FUNCTION__, | |||
793 | NULL((void*)0), | |||
794 | "xmlSecPtrListAdd", | |||
795 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
796 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
797 | xmlSecDSigReferenceCtxDestroy(dsigRefCtx); | |||
798 | return(-1); | |||
799 | } | |||
800 | ||||
801 | /* process */ | |||
802 | ret = xmlSecDSigReferenceCtxProcessNode(dsigRefCtx, cur); | |||
803 | if(ret < 0) { | |||
804 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",804,__FUNCTION__, | |||
805 | NULL((void*)0), | |||
806 | "xmlSecDSigReferenceCtxProcessNode", | |||
807 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
808 | "node=%s", | |||
809 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL")); | |||
810 | return(-1); | |||
811 | } | |||
812 | ||||
813 | /* bail out if next Reference processing failed */ | |||
814 | if(dsigRefCtx->status != xmlSecDSigStatusSucceeded) { | |||
815 | dsigCtx->status = xmlSecDSigStatusInvalid; | |||
816 | return(0); | |||
817 | } | |||
818 | cur = xmlSecGetNextElementNode(cur->next); | |||
819 | } | |||
820 | ||||
821 | /* check that we have at least one Reference */ | |||
822 | if(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0) { | |||
823 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",823,__FUNCTION__, | |||
824 | NULL((void*)0), | |||
825 | NULL((void*)0), | |||
826 | XMLSEC_ERRORS_R_DSIG_NO_REFERENCES81, | |||
827 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
828 | return(-1); | |||
829 | } | |||
830 | ||||
831 | /* if there is something left than it's an error */ | |||
832 | if(cur != NULL((void*)0)) { | |||
833 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",833,__FUNCTION__, | |||
834 | NULL((void*)0), | |||
835 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
836 | XMLSEC_ERRORS_R_UNEXPECTED_NODE27, | |||
837 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
838 | return(-1); | |||
839 | } | |||
840 | return(0); | |||
841 | } | |||
842 | ||||
843 | static int | |||
844 | xmlSecDSigCtxProcessKeyInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) { | |||
845 | int ret; | |||
846 | ||||
847 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",847 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
848 | xmlSecAssert2(dsigCtx->signMethod != NULL, -1)if(!( dsigCtx->signMethod != ((void*)0) ) ) { xmlSecError( "xmldsig.c",848,__FUNCTION__, ((void*)0), "dsigCtx->signMethod != NULL" , 100, " "); return(-1); }; | |||
849 | ||||
850 | /* set key requirements */ | |||
851 | ret = xmlSecTransformSetKeyReq(dsigCtx->signMethod, &(dsigCtx->keyInfoReadCtx.keyReq)); | |||
852 | if(ret < 0) { | |||
853 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",853,__FUNCTION__, | |||
854 | NULL((void*)0), | |||
855 | "xmlSecTransformSetKeyReq", | |||
856 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
857 | "transform=%s", | |||
858 | xmlSecErrorsSafeString(xmlSecTransformGetName(dsigCtx->signMethod))(((((((( (dsigCtx->signMethod) ) != ((void*)0)) && (( (dsigCtx->signMethod) )->id != ((void*)0)) && (( (dsigCtx->signMethod) )->id->klassSize >= sizeof (xmlSecTransformKlass)) && (( (dsigCtx->signMethod ) )->id->objSize >= sizeof(xmlSecTransform)) && (( (dsigCtx->signMethod) )->id->name != ((void*)0)) )) ? ((((dsigCtx->signMethod)->id)) ? (((dsigCtx->signMethod )->id)->name) : ((void*)0)) : ((void*)0))) != ((void*)0 )) ? ((char*)(((((( (dsigCtx->signMethod) ) != ((void*)0)) && (( (dsigCtx->signMethod) )->id != ((void*)0 )) && (( (dsigCtx->signMethod) )->id->klassSize >= sizeof(xmlSecTransformKlass)) && (( (dsigCtx-> signMethod) )->id->objSize >= sizeof(xmlSecTransform )) && (( (dsigCtx->signMethod) )->id->name != ((void*)0)))) ? ((((dsigCtx->signMethod)->id)) ? (((dsigCtx ->signMethod)->id)->name) : ((void*)0)) : ((void*)0) ))) : (char*)"NULL")); | |||
859 | return(-1); | |||
860 | } | |||
861 | ||||
862 | /* ignore <dsig:KeyInfo /> if there is the key is already set */ | |||
863 | /* todo: throw an error if key is set and node != NULL? */ | |||
864 | if((dsigCtx->signKey == NULL((void*)0)) && (dsigCtx->keyInfoReadCtx.keysMngr != NULL((void*)0)) | |||
865 | && (dsigCtx->keyInfoReadCtx.keysMngr->getKey != NULL((void*)0))) { | |||
866 | dsigCtx->signKey = (dsigCtx->keyInfoReadCtx.keysMngr->getKey)(node, &(dsigCtx->keyInfoReadCtx)); | |||
867 | } | |||
868 | ||||
869 | /* check that we have exactly what we want */ | |||
870 | if((dsigCtx->signKey == NULL((void*)0)) || (!xmlSecKeyMatch(dsigCtx->signKey, NULL((void*)0), &(dsigCtx->keyInfoReadCtx.keyReq)))) { | |||
871 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",871,__FUNCTION__, | |||
872 | NULL((void*)0), | |||
873 | NULL((void*)0), | |||
874 | XMLSEC_ERRORS_R_KEY_NOT_FOUND45, | |||
875 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
876 | return(-1); | |||
877 | } | |||
878 | ||||
879 | /* set the key to the transform */ | |||
880 | ret = xmlSecTransformSetKey(dsigCtx->signMethod, dsigCtx->signKey); | |||
881 | if(ret < 0) { | |||
882 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",882,__FUNCTION__, | |||
883 | NULL((void*)0), | |||
884 | "xmlSecTransformSetKey", | |||
885 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
886 | "transform=%s", | |||
887 | xmlSecErrorsSafeString(xmlSecTransformGetName(dsigCtx->signMethod))(((((((( (dsigCtx->signMethod) ) != ((void*)0)) && (( (dsigCtx->signMethod) )->id != ((void*)0)) && (( (dsigCtx->signMethod) )->id->klassSize >= sizeof (xmlSecTransformKlass)) && (( (dsigCtx->signMethod ) )->id->objSize >= sizeof(xmlSecTransform)) && (( (dsigCtx->signMethod) )->id->name != ((void*)0)) )) ? ((((dsigCtx->signMethod)->id)) ? (((dsigCtx->signMethod )->id)->name) : ((void*)0)) : ((void*)0))) != ((void*)0 )) ? ((char*)(((((( (dsigCtx->signMethod) ) != ((void*)0)) && (( (dsigCtx->signMethod) )->id != ((void*)0 )) && (( (dsigCtx->signMethod) )->id->klassSize >= sizeof(xmlSecTransformKlass)) && (( (dsigCtx-> signMethod) )->id->objSize >= sizeof(xmlSecTransform )) && (( (dsigCtx->signMethod) )->id->name != ((void*)0)))) ? ((((dsigCtx->signMethod)->id)) ? (((dsigCtx ->signMethod)->id)->name) : ((void*)0)) : ((void*)0) ))) : (char*)"NULL")); | |||
888 | return(-1); | |||
889 | } | |||
890 | ||||
891 | /* if we are signing document, update <dsig:KeyInfo/> node */ | |||
892 | if((node != NULL((void*)0)) && (dsigCtx->operation == xmlSecTransformOperationSign)) { | |||
893 | ret = xmlSecKeyInfoNodeWrite(node, dsigCtx->signKey, &(dsigCtx->keyInfoWriteCtx)); | |||
894 | if(ret < 0) { | |||
895 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",895,__FUNCTION__, | |||
896 | NULL((void*)0), | |||
897 | "xmlSecKeyInfoNodeWrite", | |||
898 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
899 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
900 | return(-1); | |||
901 | } | |||
902 | } | |||
903 | ||||
904 | return(0); | |||
905 | } | |||
906 | ||||
907 | /** | |||
908 | * xmlSecDSigCtxProcessObjectNode: | |||
909 | * | |||
910 | * The Object Element (http://www.w3.org/TR/xmldsig-core/#sec-Object) | |||
911 | * | |||
912 | * Object is an optional element that may occur one or more times. When | |||
913 | * present, this element may contain any data. The Object element may include | |||
914 | * optional MIME type, ID, and encoding attributes. | |||
915 | * | |||
916 | * Schema Definition: | |||
917 | * | |||
918 | * <element name="Object" type="ds:ObjectType"/> | |||
919 | * <complexType name="ObjectType" mixed="true"> | |||
920 | * <sequence minOccurs="0" maxOccurs="unbounded"> | |||
921 | * <any namespace="##any" processContents="lax"/> | |||
922 | * </sequence> | |||
923 | * <attribute name="Id" type="ID" use="optional"/> | |||
924 | * <attribute name="MimeType" type="string" use="optional"/> | |||
925 | * <attribute name="Encoding" type="anyURI" use="optional"/> | |||
926 | * </complexType> | |||
927 | * | |||
928 | * DTD: | |||
929 | * | |||
930 | * <!ELEMENT Object (#PCDATA|Signature|SignatureProperties|Manifest %Object.ANY;)* > | |||
931 | * <!ATTLIST Object Id ID #IMPLIED | |||
932 | * MimeType CDATA #IMPLIED | |||
933 | * Encoding CDATA #IMPLIED > | |||
934 | */ | |||
935 | static int | |||
936 | xmlSecDSigCtxProcessObjectNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) { | |||
937 | xmlNodePtr cur; | |||
938 | int ret; | |||
939 | ||||
940 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",940 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
941 | xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1)if(!( dsigCtx->status == xmlSecDSigStatusUnknown ) ) { xmlSecError ("xmldsig.c",941,__FUNCTION__, ((void*)0), "dsigCtx->status == xmlSecDSigStatusUnknown" , 100, " "); return(-1); }; | |||
942 | xmlSecAssert2(node != NULL, -1)if(!( node != ((void*)0) ) ) { xmlSecError("xmldsig.c",942,__FUNCTION__ , ((void*)0), "node != NULL", 100, " "); return(-1); }; | |||
943 | ||||
944 | /* we care about Manifest nodes only; ignore everything else */ | |||
945 | cur = xmlSecGetNextElementNode(node->children); | |||
946 | while(cur != NULL((void*)0)) { | |||
947 | if(xmlSecCheckNodeName(cur, xmlSecNodeManifest, xmlSecDSigNs)) { | |||
948 | ret = xmlSecDSigCtxProcessManifestNode(dsigCtx, cur); | |||
949 | if(ret < 0){ | |||
950 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",950,__FUNCTION__, | |||
951 | NULL((void*)0), | |||
952 | "xmlSecDSigCtxProcessManifestNode", | |||
953 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
954 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
955 | return(-1); | |||
956 | } | |||
957 | } | |||
958 | cur = xmlSecGetNextElementNode(cur->next); | |||
959 | } | |||
960 | return(0); | |||
961 | } | |||
962 | ||||
963 | /** | |||
964 | * xmlSecDSigCtxProcessManifestNode: | |||
965 | * | |||
966 | * The Manifest Element (http://www.w3.org/TR/xmldsig-core/#sec-Manifest) | |||
967 | * | |||
968 | * The Manifest element provides a list of References. The difference from | |||
969 | * the list in SignedInfo is that it is application defined which, if any, of | |||
970 | * the digests are actually checked against the objects referenced and what to | |||
971 | * do if the object is inaccessible or the digest compare fails. If a Manifest | |||
972 | * is pointed to from SignedInfo, the digest over the Manifest itself will be | |||
973 | * checked by the core result validation behavior. The digests within such | |||
974 | * a Manifest are checked at the application's discretion. If a Manifest is | |||
975 | * referenced from another Manifest, even the overall digest of this two level | |||
976 | * deep Manifest might not be checked. | |||
977 | * | |||
978 | * Schema Definition: | |||
979 | * | |||
980 | * <element name="Manifest" type="ds:ManifestType"/> | |||
981 | * <complexType name="ManifestType"> | |||
982 | * <sequence> | |||
983 | * <element ref="ds:Reference" maxOccurs="unbounded"/> | |||
984 | * </sequence> | |||
985 | * <attribute name="Id" type="ID" use="optional"/> | |||
986 | * </complexType> | |||
987 | * | |||
988 | * DTD: | |||
989 | * | |||
990 | * <!ELEMENT Manifest (Reference+) > | |||
991 | * <!ATTLIST Manifest Id ID #IMPLIED > | |||
992 | */ | |||
993 | static int | |||
994 | xmlSecDSigCtxProcessManifestNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) { | |||
995 | xmlSecDSigReferenceCtxPtr dsigRefCtx; | |||
996 | xmlNodePtr cur; | |||
997 | int ret; | |||
998 | ||||
999 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",999 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
1000 | xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1)if(!( dsigCtx->status == xmlSecDSigStatusUnknown ) ) { xmlSecError ("xmldsig.c",1000,__FUNCTION__, ((void*)0), "dsigCtx->status == xmlSecDSigStatusUnknown" , 100, " "); return(-1); }; | |||
1001 | xmlSecAssert2(node != NULL, -1)if(!( node != ((void*)0) ) ) { xmlSecError("xmldsig.c",1001,__FUNCTION__ , ((void*)0), "node != NULL", 100, " "); return(-1); }; | |||
1002 | ||||
1003 | /* calculate references */ | |||
1004 | cur = xmlSecGetNextElementNode(node->children); | |||
1005 | while((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs))) { | |||
1006 | /* create reference */ | |||
1007 | dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginManifest); | |||
1008 | if(dsigRefCtx == NULL((void*)0)) { | |||
1009 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1009,__FUNCTION__, | |||
1010 | NULL((void*)0), | |||
1011 | "xmlSecDSigReferenceCtxCreate", | |||
1012 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1013 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1014 | return(-1); | |||
1015 | } | |||
1016 | ||||
1017 | /* add to the list */ | |||
1018 | ret = xmlSecPtrListAdd(&(dsigCtx->manifestReferences), dsigRefCtx); | |||
1019 | if(ret < 0) { | |||
1020 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1020,__FUNCTION__, | |||
1021 | NULL((void*)0), | |||
1022 | "xmlSecPtrListAdd", | |||
1023 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1024 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1025 | xmlSecDSigReferenceCtxDestroy(dsigRefCtx); | |||
1026 | return(-1); | |||
1027 | } | |||
1028 | ||||
1029 | /* process */ | |||
1030 | ret = xmlSecDSigReferenceCtxProcessNode(dsigRefCtx, cur); | |||
1031 | if(ret < 0) { | |||
1032 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1032,__FUNCTION__, | |||
1033 | NULL((void*)0), | |||
1034 | "xmlSecDSigReferenceCtxProcessNode", | |||
1035 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1036 | "node=%s", | |||
1037 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL")); | |||
1038 | return(-1); | |||
1039 | } | |||
1040 | ||||
1041 | /* we don;t care if Reference processing failed because | |||
1042 | * it's Manifest node */ | |||
1043 | cur = xmlSecGetNextElementNode(cur->next); | |||
1044 | } | |||
1045 | ||||
1046 | /* we should have nothing else here */ | |||
1047 | if(cur != NULL((void*)0)) { | |||
1048 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1048,__FUNCTION__, | |||
1049 | NULL((void*)0), | |||
1050 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
1051 | XMLSEC_ERRORS_R_UNEXPECTED_NODE27, | |||
1052 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1053 | return(-1); | |||
1054 | } | |||
1055 | return(0); | |||
1056 | } | |||
1057 | ||||
1058 | /** | |||
1059 | * xmlSecDSigCtxDebugDump: | |||
1060 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
1061 | * @output: the pointer to output FILE. | |||
1062 | * | |||
1063 | * Prints the debug information about @dsigCtx to @output. | |||
1064 | */ | |||
1065 | void | |||
1066 | xmlSecDSigCtxDebugDump(xmlSecDSigCtxPtr dsigCtx, FILE* output) { | |||
1067 | xmlSecAssert(dsigCtx != NULL)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",1067 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return ; }; | |||
1068 | xmlSecAssert(output != NULL)if(!( output != ((void*)0) ) ) { xmlSecError("xmldsig.c",1068 ,__FUNCTION__, ((void*)0), "output != NULL", 100, " "); return ; }; | |||
1069 | ||||
1070 | if(dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1071 | fprintf(output, "= SIGNATURE CONTEXT\n"); | |||
1072 | } else { | |||
1073 | fprintf(output, "= VERIFICATION CONTEXT\n"); | |||
1074 | } | |||
1075 | switch(dsigCtx->status) { | |||
1076 | case xmlSecDSigStatusUnknown: | |||
1077 | fprintf(output, "== Status: unknown\n"); | |||
1078 | break; | |||
1079 | case xmlSecDSigStatusSucceeded: | |||
1080 | fprintf(output, "== Status: succeeded\n"); | |||
1081 | break; | |||
1082 | case xmlSecDSigStatusInvalid: | |||
1083 | fprintf(output, "== Status: invalid\n"); | |||
1084 | break; | |||
1085 | } | |||
1086 | fprintf(output, "== flags: 0x%08x\n", dsigCtx->flags); | |||
1087 | fprintf(output, "== flags2: 0x%08x\n", dsigCtx->flags2); | |||
1088 | ||||
1089 | if(dsigCtx->id != NULL((void*)0)) { | |||
1090 | fprintf(output, "== Id: \"%s\"\n", dsigCtx->id); | |||
1091 | } | |||
1092 | ||||
1093 | fprintf(output, "== Key Info Read Ctx:\n"); | |||
1094 | xmlSecKeyInfoCtxDebugDump(&(dsigCtx->keyInfoReadCtx), output); | |||
1095 | fprintf(output, "== Key Info Write Ctx:\n"); | |||
1096 | xmlSecKeyInfoCtxDebugDump(&(dsigCtx->keyInfoWriteCtx), output); | |||
1097 | ||||
1098 | fprintf(output, "== Signature Transform Ctx:\n"); | |||
1099 | xmlSecTransformCtxDebugDump(&(dsigCtx->transformCtx), output); | |||
1100 | ||||
1101 | if(dsigCtx->signMethod != NULL((void*)0)) { | |||
1102 | fprintf(output, "== Signature Method:\n"); | |||
1103 | xmlSecTransformDebugDump(dsigCtx->signMethod, output); | |||
1104 | } | |||
1105 | ||||
1106 | if(dsigCtx->signKey != NULL((void*)0)) { | |||
1107 | fprintf(output, "== Signature Key:\n"); | |||
1108 | xmlSecKeyDebugDump(dsigCtx->signKey, output); | |||
1109 | } | |||
1110 | ||||
1111 | fprintf(output, "== SignedInfo References List:\n"); | |||
1112 | xmlSecPtrListDebugDump(&(dsigCtx->signedInfoReferences), output); | |||
1113 | ||||
1114 | fprintf(output, "== Manifest References List:\n"); | |||
1115 | xmlSecPtrListDebugDump(&(dsigCtx->manifestReferences), output); | |||
1116 | ||||
1117 | if((dsigCtx->result != NULL((void*)0)) && | |||
1118 | (xmlSecBufferGetData(dsigCtx->result) != NULL((void*)0))) { | |||
1119 | ||||
1120 | fprintf(output, "== Result - start buffer:\n"); | |||
1121 | fwrite(xmlSecBufferGetData(dsigCtx->result), | |||
1122 | xmlSecBufferGetSize(dsigCtx->result), | |||
1123 | 1, output); | |||
1124 | fprintf(output, "\n== Result - end buffer\n"); | |||
1125 | } | |||
1126 | if(((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE0x00000008) != 0) && | |||
1127 | (xmlSecDSigCtxGetPreSignBuffer(dsigCtx) != NULL((void*)0)) && | |||
1128 | (xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)) != NULL((void*)0))) { | |||
1129 | ||||
1130 | fprintf(output, "== PreSigned data - start buffer:\n"); | |||
1131 | fwrite(xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), | |||
1132 | xmlSecBufferGetSize(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), | |||
1133 | 1, output); | |||
1134 | fprintf(output, "\n== PreSigned data - end buffer\n"); | |||
1135 | } | |||
1136 | } | |||
1137 | ||||
1138 | /** | |||
1139 | * xmlSecDSigCtxDebugXmlDump: | |||
1140 | * @dsigCtx: the pointer to <dsig:Signature/> processing context. | |||
1141 | * @output: the pointer to output FILE. | |||
1142 | * | |||
1143 | * Prints the debug information about @dsigCtx to @output in XML format. | |||
1144 | */ | |||
1145 | void | |||
1146 | xmlSecDSigCtxDebugXmlDump(xmlSecDSigCtxPtr dsigCtx, FILE* output) { | |||
1147 | xmlSecAssert(dsigCtx != NULL)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",1147 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return ; }; | |||
1148 | xmlSecAssert(output != NULL)if(!( output != ((void*)0) ) ) { xmlSecError("xmldsig.c",1148 ,__FUNCTION__, ((void*)0), "output != NULL", 100, " "); return ; }; | |||
1149 | ||||
1150 | if(dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1151 | fprintf(output, "<SignatureContext \n"); | |||
1152 | } else { | |||
1153 | fprintf(output, "<VerificationContext \n"); | |||
1154 | } | |||
1155 | switch(dsigCtx->status) { | |||
1156 | case xmlSecDSigStatusUnknown: | |||
1157 | fprintf(output, "status=\"unknown\" >\n"); | |||
1158 | break; | |||
1159 | case xmlSecDSigStatusSucceeded: | |||
1160 | fprintf(output, "status=\"succeeded\" >\n"); | |||
1161 | break; | |||
1162 | case xmlSecDSigStatusInvalid: | |||
1163 | fprintf(output, "status=\"invalid\" >\n"); | |||
1164 | break; | |||
1165 | } | |||
1166 | ||||
1167 | fprintf(output, "<Flags>%08x</Flags>\n", dsigCtx->flags); | |||
1168 | fprintf(output, "<Flags2>%08x</Flags2>\n", dsigCtx->flags2); | |||
1169 | ||||
1170 | fprintf(output, "<Id>"); | |||
1171 | xmlSecPrintXmlString(output, dsigCtx->id); | |||
1172 | fprintf(output, "</Id>\n"); | |||
1173 | ||||
1174 | fprintf(output, "<KeyInfoReadCtx>\n"); | |||
1175 | xmlSecKeyInfoCtxDebugXmlDump(&(dsigCtx->keyInfoReadCtx), output); | |||
1176 | fprintf(output, "</KeyInfoReadCtx>\n"); | |||
1177 | ||||
1178 | fprintf(output, "<KeyInfoWriteCtx>\n"); | |||
1179 | xmlSecKeyInfoCtxDebugXmlDump(&(dsigCtx->keyInfoWriteCtx), output); | |||
1180 | fprintf(output, "</KeyInfoWriteCtx>\n"); | |||
1181 | ||||
1182 | fprintf(output, "<SignatureTransformCtx>\n"); | |||
1183 | xmlSecTransformCtxDebugXmlDump(&(dsigCtx->transformCtx), output); | |||
1184 | fprintf(output, "</SignatureTransformCtx>\n"); | |||
1185 | ||||
1186 | if(dsigCtx->signMethod != NULL((void*)0)) { | |||
1187 | fprintf(output, "<SignatureMethod>\n"); | |||
1188 | xmlSecTransformDebugXmlDump(dsigCtx->signMethod, output); | |||
1189 | fprintf(output, "</SignatureMethod>\n"); | |||
1190 | } | |||
1191 | ||||
1192 | if(dsigCtx->signKey != NULL((void*)0)) { | |||
1193 | fprintf(output, "<SignatureKey>\n"); | |||
1194 | xmlSecKeyDebugXmlDump(dsigCtx->signKey, output); | |||
1195 | fprintf(output, "</SignatureKey>\n"); | |||
1196 | } | |||
1197 | ||||
1198 | fprintf(output, "<SignedInfoReferences>\n"); | |||
1199 | xmlSecPtrListDebugXmlDump(&(dsigCtx->signedInfoReferences), output); | |||
1200 | fprintf(output, "</SignedInfoReferences>\n"); | |||
1201 | ||||
1202 | fprintf(output, "<ManifestReferences>\n"); | |||
1203 | xmlSecPtrListDebugXmlDump(&(dsigCtx->manifestReferences), output); | |||
1204 | fprintf(output, "</ManifestReferences>\n"); | |||
1205 | ||||
1206 | if((dsigCtx->result != NULL((void*)0)) && | |||
1207 | (xmlSecBufferGetData(dsigCtx->result) != NULL((void*)0))) { | |||
1208 | ||||
1209 | fprintf(output, "<Result>"); | |||
1210 | fwrite(xmlSecBufferGetData(dsigCtx->result), | |||
1211 | xmlSecBufferGetSize(dsigCtx->result), | |||
1212 | 1, output); | |||
1213 | fprintf(output, "</Result>\n"); | |||
1214 | } | |||
1215 | if(((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE0x00000008) != 0) && | |||
1216 | (xmlSecDSigCtxGetPreSignBuffer(dsigCtx) != NULL((void*)0)) && | |||
1217 | (xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)) != NULL((void*)0))) { | |||
1218 | ||||
1219 | fprintf(output, "<PreSignedData>"); | |||
1220 | fwrite(xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), | |||
1221 | xmlSecBufferGetSize(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), | |||
1222 | 1, output); | |||
1223 | fprintf(output, "</PreSignedData>\n"); | |||
1224 | } | |||
1225 | ||||
1226 | if(dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1227 | fprintf(output, "</SignatureContext>\n"); | |||
1228 | } else { | |||
1229 | fprintf(output, "</VerificationContext>\n"); | |||
1230 | } | |||
1231 | } | |||
1232 | ||||
1233 | /************************************************************************** | |||
1234 | * | |||
1235 | * xmlSecDSigReferenceCtx | |||
1236 | * | |||
1237 | *************************************************************************/ | |||
1238 | /** | |||
1239 | * xmlSecDSigReferenceCtxCreate: | |||
1240 | * @dsigCtx: the pointer to parent <dsig:Signature/> node processing context. | |||
1241 | * @origin: the reference origin (<dsig:SignedInfo/> or <dsig:Manifest/> node). | |||
1242 | * | |||
1243 | * Creates new <dsig:Reference/> element processing context. Caller is responsible | |||
1244 | * for destroying the returned context by calling #xmlSecDSigReferenceCtxDestroy | |||
1245 | * function. | |||
1246 | * | |||
1247 | * Returns: pointer to newly created context or NULL if an error occurs. | |||
1248 | */ | |||
1249 | xmlSecDSigReferenceCtxPtr | |||
1250 | xmlSecDSigReferenceCtxCreate(xmlSecDSigCtxPtr dsigCtx, xmlSecDSigReferenceOrigin origin) { | |||
1251 | xmlSecDSigReferenceCtxPtr dsigRefCtx; | |||
1252 | int ret; | |||
1253 | ||||
1254 | xmlSecAssert2(dsigCtx != NULL, NULL)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",1254 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (((void*)0)); }; | |||
1255 | ||||
1256 | dsigRefCtx = (xmlSecDSigReferenceCtxPtr) xmlMalloc(sizeof(xmlSecDSigReferenceCtx)); | |||
1257 | if(dsigRefCtx == NULL((void*)0)) { | |||
1258 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1258,__FUNCTION__, | |||
1259 | NULL((void*)0), | |||
1260 | NULL((void*)0), | |||
1261 | XMLSEC_ERRORS_R_MALLOC_FAILED2, | |||
1262 | "sizeof(xmlSecDSigReferenceCtx)=%d", | |||
1263 | sizeof(xmlSecDSigReferenceCtx)); | |||
1264 | return(NULL((void*)0)); | |||
1265 | } | |||
1266 | ||||
1267 | ret = xmlSecDSigReferenceCtxInitialize(dsigRefCtx, dsigCtx, origin); | |||
1268 | if(ret < 0) { | |||
1269 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1269,__FUNCTION__, | |||
1270 | NULL((void*)0), | |||
1271 | "xmlSecDSigReferenceCtxInitialize", | |||
1272 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1273 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1274 | xmlSecDSigReferenceCtxDestroy(dsigRefCtx); | |||
1275 | return(NULL((void*)0)); | |||
1276 | } | |||
1277 | return(dsigRefCtx); | |||
1278 | } | |||
1279 | ||||
1280 | /** | |||
1281 | * xmlSecDSigReferenceCtxDestroy: | |||
1282 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1283 | * | |||
1284 | * Destroy context object created with #xmlSecDSigReferenceCtxCreate function. | |||
1285 | */ | |||
1286 | void | |||
1287 | xmlSecDSigReferenceCtxDestroy(xmlSecDSigReferenceCtxPtr dsigRefCtx) { | |||
1288 | xmlSecAssert(dsigRefCtx != NULL)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1288,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return; }; | |||
1289 | ||||
1290 | xmlSecDSigReferenceCtxFinalize(dsigRefCtx); | |||
1291 | xmlFree(dsigRefCtx); | |||
1292 | } | |||
1293 | ||||
1294 | /** | |||
1295 | * xmlSecDSigReferenceCtxInitialize: | |||
1296 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1297 | * @dsigCtx: the pointer to parent <dsig:Signature/> node processing context. | |||
1298 | * @origin: the reference origin (<dsig:SignedInfo/> or <dsig:Manifest/> node). | |||
1299 | * | |||
1300 | * Initializes new <dsig:Reference/> element processing context. Caller is responsible | |||
1301 | * for cleaning up the returned context by calling #xmlSecDSigReferenceCtxFinalize | |||
1302 | * function. | |||
1303 | * | |||
1304 | * Returns: 0 on succes or aa negative value otherwise. | |||
1305 | */ | |||
1306 | int | |||
1307 | xmlSecDSigReferenceCtxInitialize(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlSecDSigCtxPtr dsigCtx, | |||
1308 | xmlSecDSigReferenceOrigin origin) { | |||
1309 | int ret; | |||
1310 | ||||
1311 | xmlSecAssert2(dsigCtx != NULL, -1)if(!( dsigCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c",1311 ,__FUNCTION__, ((void*)0), "dsigCtx != NULL", 100, " "); return (-1); }; | |||
1312 | xmlSecAssert2(dsigRefCtx != NULL, -1)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1312,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return(-1); }; | |||
1313 | ||||
1314 | memset(dsigRefCtx, 0, sizeof(xmlSecDSigReferenceCtx)); | |||
1315 | ||||
1316 | dsigRefCtx->dsigCtx = dsigCtx; | |||
1317 | dsigRefCtx->origin = origin; | |||
1318 | ||||
1319 | /* initializes transforms dsigRefCtx */ | |||
1320 | ret = xmlSecTransformCtxInitialize(&(dsigRefCtx->transformCtx)); | |||
1321 | if(ret < 0) { | |||
1322 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1322,__FUNCTION__, | |||
1323 | NULL((void*)0), | |||
1324 | "xmlSecTransformCtxInitialize", | |||
1325 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1326 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1327 | return(-1); | |||
1328 | } | |||
1329 | ||||
1330 | /* copy enabled transforms */ | |||
1331 | if(dsigCtx->enabledReferenceTransforms != NULL((void*)0)) { | |||
1332 | ret = xmlSecPtrListCopy(&(dsigRefCtx->transformCtx.enabledTransforms), | |||
1333 | dsigCtx->enabledReferenceTransforms); | |||
1334 | if(ret < 0) { | |||
1335 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1335,__FUNCTION__, | |||
1336 | NULL((void*)0), | |||
1337 | "xmlSecPtrListCopy", | |||
1338 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1339 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1340 | return(-1); | |||
1341 | } | |||
1342 | } | |||
1343 | dsigRefCtx->transformCtx.preExecCallback = dsigCtx->referencePreExecuteCallback; | |||
1344 | dsigRefCtx->transformCtx.enabledUris = dsigCtx->enabledReferenceUris; | |||
1345 | ||||
1346 | if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_USE_VISA3D_HACK0x00000010) != 0) { | |||
1347 | dsigRefCtx->transformCtx.flags |= XMLSEC_TRANSFORMCTX_FLAGS_USE_VISA3D_HACK0x00000001; | |||
1348 | } | |||
1349 | return(0); | |||
1350 | } | |||
1351 | ||||
1352 | /** | |||
1353 | * xmlSecDSigReferenceCtxFinalize: | |||
1354 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1355 | * | |||
1356 | * Cleans up context object created with #xmlSecDSigReferenceCtxInitialize function. | |||
1357 | */ | |||
1358 | void | |||
1359 | xmlSecDSigReferenceCtxFinalize(xmlSecDSigReferenceCtxPtr dsigRefCtx) { | |||
1360 | xmlSecAssert(dsigRefCtx != NULL)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1360,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return; }; | |||
1361 | ||||
1362 | xmlSecTransformCtxFinalize(&(dsigRefCtx->transformCtx)); | |||
1363 | if(dsigRefCtx->id != NULL((void*)0)) { | |||
1364 | xmlFree(dsigRefCtx->id); | |||
1365 | } | |||
1366 | if(dsigRefCtx->uri != NULL((void*)0)) { | |||
1367 | xmlFree(dsigRefCtx->uri); | |||
1368 | } | |||
1369 | if(dsigRefCtx->type != NULL((void*)0)) { | |||
1370 | xmlFree(dsigRefCtx->type); | |||
1371 | } | |||
1372 | memset(dsigRefCtx, 0, sizeof(xmlSecDSigReferenceCtx)); | |||
1373 | } | |||
1374 | ||||
1375 | /** | |||
1376 | * xmlSecDSigReferenceCtxGetPreDigestBuffer: | |||
1377 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1378 | * | |||
1379 | * Gets the results of <dsig:Reference/> node processing just before digesting | |||
1380 | * (valid only if #XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES or | |||
1381 | * #XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES flas of signature context | |||
1382 | * is set). | |||
1383 | * | |||
1384 | * Returns: pointer to the buffer or NULL if an error occurs. | |||
1385 | */ | |||
1386 | xmlSecBufferPtr | |||
1387 | xmlSecDSigReferenceCtxGetPreDigestBuffer(xmlSecDSigReferenceCtxPtr dsigRefCtx) { | |||
1388 | xmlSecAssert2(dsigRefCtx != NULL, NULL)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1388,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return(((void*)0)); }; | |||
1389 | ||||
1390 | return((dsigRefCtx->preDigestMemBufMethod != NULL((void*)0)) ? | |||
1391 | xmlSecTransformMemBufGetBuffer(dsigRefCtx->preDigestMemBufMethod) : NULL((void*)0)); | |||
1392 | } | |||
1393 | ||||
1394 | /** | |||
1395 | * xmlSecDSigReferenceCtxProcessNode: | |||
1396 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1397 | * @node: the pointer to <dsig:Reference/> node. | |||
1398 | ||||
1399 | * The Reference Element (http://www.w3.org/TR/xmldsig-core/#sec-Reference) | |||
1400 | * | |||
1401 | * Reference is an element that may occur one or more times. It specifies | |||
1402 | * a digest algorithm and digest value, and optionally an identifier of the | |||
1403 | * object being signed, the type of the object, and/or a list of transforms | |||
1404 | * to be applied prior to digesting. The identification (URI) and transforms | |||
1405 | * describe how the digested content (i.e., the input to the digest method) | |||
1406 | * was created. The Type attribute facilitates the processing of referenced | |||
1407 | * data. For example, while this specification makes no requirements over | |||
1408 | * external data, an application may wish to signal that the referent is a | |||
1409 | * Manifest. An optional ID attribute permits a Reference to be referenced | |||
1410 | * from elsewhere. | |||
1411 | * | |||
1412 | * Returns: 0 on succes or aa negative value otherwise. | |||
1413 | */ | |||
1414 | int | |||
1415 | xmlSecDSigReferenceCtxProcessNode(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodePtr node) { | |||
1416 | xmlSecTransformCtxPtr transformCtx; | |||
1417 | xmlNodePtr digestValueNode; | |||
1418 | xmlNodePtr cur; | |||
1419 | int ret; | |||
1420 | ||||
1421 | xmlSecAssert2(dsigRefCtx != NULL, -1)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1421,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return(-1); }; | |||
1422 | xmlSecAssert2(dsigRefCtx->dsigCtx != NULL, -1)if(!( dsigRefCtx->dsigCtx != ((void*)0) ) ) { xmlSecError( "xmldsig.c",1422,__FUNCTION__, ((void*)0), "dsigRefCtx->dsigCtx != NULL" , 100, " "); return(-1); }; | |||
1423 | xmlSecAssert2(dsigRefCtx->digestMethod == NULL, -1)if(!( dsigRefCtx->digestMethod == ((void*)0) ) ) { xmlSecError ("xmldsig.c",1423,__FUNCTION__, ((void*)0), "dsigRefCtx->digestMethod == NULL" , 100, " "); return(-1); }; | |||
1424 | xmlSecAssert2(dsigRefCtx->digestMethod == NULL, -1)if(!( dsigRefCtx->digestMethod == ((void*)0) ) ) { xmlSecError ("xmldsig.c",1424,__FUNCTION__, ((void*)0), "dsigRefCtx->digestMethod == NULL" , 100, " "); return(-1); }; | |||
1425 | xmlSecAssert2(dsigRefCtx->preDigestMemBufMethod == NULL, -1)if(!( dsigRefCtx->preDigestMemBufMethod == ((void*)0) ) ) { xmlSecError("xmldsig.c",1425,__FUNCTION__, ((void*)0), "dsigRefCtx->preDigestMemBufMethod == NULL" , 100, " "); return(-1); }; | |||
1426 | xmlSecAssert2(node != NULL, -1)if(!( node != ((void*)0) ) ) { xmlSecError("xmldsig.c",1426,__FUNCTION__ , ((void*)0), "node != NULL", 100, " "); return(-1); }; | |||
1427 | xmlSecAssert2(node->doc != NULL, -1)if(!( node->doc != ((void*)0) ) ) { xmlSecError("xmldsig.c" ,1427,__FUNCTION__, ((void*)0), "node->doc != NULL", 100, " " ); return(-1); }; | |||
1428 | ||||
1429 | transformCtx = &(dsigRefCtx->transformCtx); | |||
1430 | ||||
1431 | /* read attributes first */ | |||
1432 | dsigRefCtx->uri = xmlGetProp(node, xmlSecAttrURI); | |||
1433 | dsigRefCtx->id = xmlGetProp(node, xmlSecAttrId); | |||
1434 | dsigRefCtx->type= xmlGetProp(node, xmlSecAttrType); | |||
1435 | ||||
1436 | /* set start URI (and check that it is enabled!) */ | |||
1437 | ret = xmlSecTransformCtxSetUri(transformCtx, dsigRefCtx->uri, node); | |||
1438 | if(ret < 0) { | |||
1439 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1439,__FUNCTION__, | |||
1440 | NULL((void*)0), | |||
1441 | "xmlSecTransformCtxSetUri", | |||
1442 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1443 | "uri=%s", | |||
1444 | xmlSecErrorsSafeString(dsigRefCtx->uri)(((dsigRefCtx->uri) != ((void*)0)) ? ((char*)(dsigRefCtx-> uri)) : (char*)"NULL")); | |||
1445 | return(-1); | |||
1446 | } | |||
1447 | ||||
1448 | /* first is optional Transforms node */ | |||
1449 | cur = xmlSecGetNextElementNode(node->children); | |||
1450 | if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeTransforms, xmlSecDSigNs))) { | |||
1451 | ret = xmlSecTransformCtxNodesListRead(transformCtx, | |||
1452 | cur, xmlSecTransformUsageDSigTransform0x0001); | |||
1453 | if(ret < 0) { | |||
1454 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1454,__FUNCTION__, | |||
1455 | NULL((void*)0), | |||
1456 | "xmlSecTransformCtxNodesListRead", | |||
1457 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1458 | "node=%s", | |||
1459 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL")); | |||
1460 | return(-1); | |||
1461 | } | |||
1462 | ||||
1463 | cur = xmlSecGetNextElementNode(cur->next); | |||
1464 | } | |||
1465 | ||||
1466 | /* insert membuf if requested */ | |||
1467 | if(((dsigRefCtx->origin == xmlSecDSigReferenceOriginSignedInfo) && | |||
1468 | ((dsigRefCtx->dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES0x00000002) != 0)) || | |||
1469 | ((dsigRefCtx->origin == xmlSecDSigReferenceOriginManifest) && | |||
1470 | ((dsigRefCtx->dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES0x00000004) != 0))) { | |||
1471 | ||||
1472 | xmlSecAssert2(dsigRefCtx->preDigestMemBufMethod == NULL, -1)if(!( dsigRefCtx->preDigestMemBufMethod == ((void*)0) ) ) { xmlSecError("xmldsig.c",1472,__FUNCTION__, ((void*)0), "dsigRefCtx->preDigestMemBufMethod == NULL" , 100, " "); return(-1); }; | |||
1473 | dsigRefCtx->preDigestMemBufMethod = xmlSecTransformCtxCreateAndAppend( | |||
1474 | transformCtx, | |||
1475 | xmlSecTransformMemBufIdxmlSecTransformMemBufGetKlass()); | |||
1476 | if(dsigRefCtx->preDigestMemBufMethod == NULL((void*)0)) { | |||
1477 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1477,__FUNCTION__, | |||
1478 | NULL((void*)0), | |||
1479 | "xmlSecTransformCtxCreateAndAppend", | |||
1480 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1481 | "transform=%s", | |||
1482 | xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecTransformMemBufId))((((((xmlSecTransformMemBufGetKlass())) ? ((xmlSecTransformMemBufGetKlass ())->name) : ((void*)0))) != ((void*)0)) ? ((char*)((((xmlSecTransformMemBufGetKlass ())) ? ((xmlSecTransformMemBufGetKlass())->name) : ((void* )0)))) : (char*)"NULL")); | |||
1483 | return(-1); | |||
1484 | } | |||
1485 | } | |||
1486 | ||||
1487 | /* next node is required DigestMethod. */ | |||
1488 | if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeDigestMethod, xmlSecDSigNs))) { | |||
1489 | dsigRefCtx->digestMethod = xmlSecTransformCtxNodeRead(&(dsigRefCtx->transformCtx), | |||
1490 | cur, xmlSecTransformUsageDigestMethod0x0004); | |||
1491 | if(dsigRefCtx->digestMethod == NULL((void*)0)) { | |||
1492 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1492,__FUNCTION__, | |||
1493 | NULL((void*)0), | |||
1494 | "xmlSecTransformCtxNodeRead", | |||
1495 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1496 | "node=%s", | |||
1497 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL")); | |||
1498 | return(-1); | |||
1499 | } | |||
1500 | ||||
1501 | cur = xmlSecGetNextElementNode(cur->next); | |||
1502 | } else if(dsigRefCtx->dsigCtx->defSignMethodId != xmlSecTransformIdUnknown((xmlSecTransformId)((void*)0))) { | |||
1503 | /* the dsig spec does require DigestMethod node | |||
1504 | * to be present but in some case it application might decide to | |||
1505 | * minimize traffic */ | |||
1506 | dsigRefCtx->digestMethod = xmlSecTransformCtxCreateAndAppend(&(dsigRefCtx->transformCtx), | |||
1507 | dsigRefCtx->dsigCtx->defSignMethodId); | |||
1508 | if(dsigRefCtx->digestMethod == NULL((void*)0)) { | |||
1509 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1509,__FUNCTION__, | |||
1510 | NULL((void*)0), | |||
1511 | "xmlSecTransformCtxAppend", | |||
1512 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1513 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1514 | return(-1); | |||
1515 | } | |||
1516 | } else { | |||
1517 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1517,__FUNCTION__, | |||
1518 | NULL((void*)0), | |||
1519 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
1520 | XMLSEC_ERRORS_R_INVALID_NODE21, | |||
1521 | "expected=%s", | |||
1522 | xmlSecErrorsSafeString(xmlSecNodeDigestMethod)(((xmlSecNodeDigestMethod) != ((void*)0)) ? ((char*)(xmlSecNodeDigestMethod )) : (char*)"NULL")); | |||
1523 | return(-1); | |||
1524 | } | |||
1525 | dsigRefCtx->digestMethod->operation = dsigRefCtx->dsigCtx->operation; | |||
1526 | ||||
1527 | /* last node is required DigestValue */ | |||
1528 | if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeDigestValue, xmlSecDSigNs))) { | |||
1529 | digestValueNode = cur; | |||
1530 | cur = xmlSecGetNextElementNode(cur->next); | |||
1531 | } else { | |||
1532 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1532,__FUNCTION__, | |||
1533 | NULL((void*)0), | |||
1534 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
1535 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1536 | "node=%s", | |||
1537 | xmlSecErrorsSafeString(xmlSecNodeDigestValue)(((xmlSecNodeDigestValue) != ((void*)0)) ? ((char*)(xmlSecNodeDigestValue )) : (char*)"NULL")); | |||
1538 | return(-1); | |||
1539 | } | |||
1540 | ||||
1541 | /* if we have something else then it's an error */ | |||
1542 | if(cur != NULL((void*)0)) { | |||
1543 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1543,__FUNCTION__, | |||
1544 | NULL((void*)0), | |||
1545 | xmlSecErrorsSafeString(xmlSecNodeGetName(cur))((((((cur)) ? ((const char*)((cur)->name)) : ((void*)0))) != ((void*)0)) ? ((char*)((((cur)) ? ((const char*)((cur)->name )) : ((void*)0)))) : (char*)"NULL"), | |||
1546 | XMLSEC_ERRORS_R_UNEXPECTED_NODE27, | |||
1547 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1548 | return(-1); | |||
1549 | } | |||
1550 | ||||
1551 | /* if we need to write result to xml node then we need base64 encode result */ | |||
1552 | if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1553 | xmlSecTransformPtr base64Encode; | |||
1554 | ||||
1555 | /* we need to add base64 encode transform */ | |||
1556 | base64Encode = xmlSecTransformCtxCreateAndAppend(transformCtx, xmlSecTransformBase64IdxmlSecTransformBase64GetKlass()); | |||
1557 | if(base64Encode == NULL((void*)0)) { | |||
1558 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1558,__FUNCTION__, | |||
1559 | NULL((void*)0), | |||
1560 | "xmlSecTransformCtxCreateAndAppend", | |||
1561 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1562 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1563 | return(-1); | |||
1564 | } | |||
1565 | base64Encode->operation = xmlSecTransformOperationEncode; | |||
1566 | } | |||
1567 | ||||
1568 | /* finally get transforms results */ | |||
1569 | ret = xmlSecTransformCtxExecute(transformCtx, node->doc); | |||
1570 | if(ret < 0) { | |||
1571 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1571,__FUNCTION__, | |||
1572 | NULL((void*)0), | |||
1573 | "xmlSecTransformCtxExecute", | |||
1574 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1575 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1576 | return(-1); | |||
1577 | } | |||
1578 | dsigRefCtx->result = transformCtx->result; | |||
1579 | ||||
1580 | if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1581 | if((dsigRefCtx->result == NULL((void*)0)) || (xmlSecBufferGetData(dsigRefCtx->result) == NULL((void*)0))) { | |||
1582 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1582,__FUNCTION__, | |||
1583 | NULL((void*)0), | |||
1584 | "xmlSecTransformCtxExecute", | |||
1585 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1586 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1587 | return(-1); | |||
1588 | } | |||
1589 | ||||
1590 | /* write signed data to xml */ | |||
1591 | xmlNodeSetContentLen(digestValueNode, | |||
1592 | xmlSecBufferGetData(dsigRefCtx->result), | |||
1593 | xmlSecBufferGetSize(dsigRefCtx->result)); | |||
1594 | ||||
1595 | /* set success status and we are done */ | |||
1596 | dsigRefCtx->status = xmlSecDSigStatusSucceeded; | |||
1597 | } else { | |||
1598 | /* verify SignatureValue node content */ | |||
1599 | ret = xmlSecTransformVerifyNodeContent(dsigRefCtx->digestMethod, | |||
1600 | digestValueNode, transformCtx); | |||
1601 | if(ret < 0) { | |||
1602 | xmlSecError(XMLSEC_ERRORS_HERE"xmldsig.c",1602,__FUNCTION__, | |||
1603 | NULL((void*)0), | |||
1604 | "xmlSecTransformVerifyNodeContent", | |||
1605 | XMLSEC_ERRORS_R_XMLSEC_FAILED1, | |||
1606 | XMLSEC_ERRORS_NO_MESSAGE" "); | |||
1607 | return(-1); | |||
1608 | } | |||
1609 | ||||
1610 | /* set status and we are done */ | |||
1611 | if(dsigRefCtx->digestMethod->status == xmlSecTransformStatusOk) { | |||
1612 | dsigRefCtx->status = xmlSecDSigStatusSucceeded; | |||
1613 | } else { | |||
1614 | dsigRefCtx->status = xmlSecDSigStatusInvalid; | |||
1615 | } | |||
1616 | } | |||
1617 | ||||
1618 | return(0); | |||
1619 | } | |||
1620 | ||||
1621 | /** | |||
1622 | * xmlSecDSigReferenceCtxDebugDump: | |||
1623 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1624 | * @output: the pointer to output FILE. | |||
1625 | * | |||
1626 | * Prints debug information about @dsigRefCtx to @output. | |||
1627 | */ | |||
1628 | void | |||
1629 | xmlSecDSigReferenceCtxDebugDump(xmlSecDSigReferenceCtxPtr dsigRefCtx, FILE* output) { | |||
1630 | xmlSecAssert(dsigRefCtx != NULL)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1630,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return; }; | |||
1631 | xmlSecAssert(dsigRefCtx->dsigCtx != NULL)if(!( dsigRefCtx->dsigCtx != ((void*)0) ) ) { xmlSecError( "xmldsig.c",1631,__FUNCTION__, ((void*)0), "dsigRefCtx->dsigCtx != NULL" , 100, " "); return; }; | |||
1632 | xmlSecAssert(output != NULL)if(!( output != ((void*)0) ) ) { xmlSecError("xmldsig.c",1632 ,__FUNCTION__, ((void*)0), "output != NULL", 100, " "); return ; }; | |||
1633 | ||||
1634 | if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1635 | fprintf(output, "= REFERENCE CALCULATION CONTEXT\n"); | |||
1636 | } else { | |||
1637 | fprintf(output, "= REFERENCE VERIFICATION CONTEXT\n"); | |||
1638 | } | |||
1639 | switch(dsigRefCtx->status) { | |||
1640 | case xmlSecDSigStatusUnknown: | |||
1641 | fprintf(output, "== Status: unknown\n"); | |||
1642 | break; | |||
1643 | case xmlSecDSigStatusSucceeded: | |||
1644 | fprintf(output, "== Status: succeeded\n"); | |||
1645 | break; | |||
1646 | case xmlSecDSigStatusInvalid: | |||
1647 | fprintf(output, "== Status: invalid\n"); | |||
1648 | break; | |||
1649 | } | |||
1650 | if(dsigRefCtx->id != NULL((void*)0)) { | |||
1651 | fprintf(output, "== Id: \"%s\"\n", dsigRefCtx->id); | |||
1652 | } | |||
1653 | if(dsigRefCtx->uri != NULL((void*)0)) { | |||
1654 | fprintf(output, "== URI: \"%s\"\n", dsigRefCtx->uri); | |||
1655 | } | |||
1656 | if(dsigRefCtx->type != NULL((void*)0)) { | |||
1657 | fprintf(output, "== Type: \"%s\"\n", dsigRefCtx->type); | |||
1658 | } | |||
1659 | ||||
1660 | fprintf(output, "== Reference Transform Ctx:\n"); | |||
1661 | xmlSecTransformCtxDebugDump(&(dsigRefCtx->transformCtx), output); | |||
1662 | ||||
1663 | if(dsigRefCtx->digestMethod != NULL((void*)0)) { | |||
1664 | fprintf(output, "== Digest Method:\n"); | |||
1665 | xmlSecTransformDebugDump(dsigRefCtx->digestMethod, output); | |||
1666 | } | |||
1667 | ||||
1668 | if((xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx) != NULL((void*)0)) && | |||
1669 | (xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)) != NULL((void*)0))) { | |||
1670 | ||||
1671 | fprintf(output, "== PreDigest data - start buffer:\n"); | |||
1672 | fwrite(xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), | |||
1673 | xmlSecBufferGetSize(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), | |||
1674 | 1, output); | |||
1675 | fprintf(output, "\n== PreDigest data - end buffer\n"); | |||
1676 | } | |||
1677 | ||||
1678 | if((dsigRefCtx->result != NULL((void*)0)) && | |||
1679 | (xmlSecBufferGetData(dsigRefCtx->result) != NULL((void*)0))) { | |||
1680 | ||||
1681 | fprintf(output, "== Result - start buffer:\n"); | |||
1682 | fwrite(xmlSecBufferGetData(dsigRefCtx->result), | |||
1683 | xmlSecBufferGetSize(dsigRefCtx->result), 1, | |||
1684 | output); | |||
1685 | fprintf(output, "\n== Result - end buffer\n"); | |||
1686 | } | |||
1687 | } | |||
1688 | ||||
1689 | /** | |||
1690 | * xmlSecDSigReferenceCtxDebugXmlDump: | |||
1691 | * @dsigRefCtx: the pointer to <dsig:Reference/> element processing context. | |||
1692 | * @output: the pointer to output FILE. | |||
1693 | * | |||
1694 | * Prints debug information about @dsigRefCtx to @output in output format. | |||
1695 | */ | |||
1696 | void | |||
1697 | xmlSecDSigReferenceCtxDebugXmlDump(xmlSecDSigReferenceCtxPtr dsigRefCtx, FILE* output) { | |||
1698 | xmlSecAssert(dsigRefCtx != NULL)if(!( dsigRefCtx != ((void*)0) ) ) { xmlSecError("xmldsig.c", 1698,__FUNCTION__, ((void*)0), "dsigRefCtx != NULL", 100, " " ); return; }; | |||
1699 | xmlSecAssert(dsigRefCtx->dsigCtx != NULL)if(!( dsigRefCtx->dsigCtx != ((void*)0) ) ) { xmlSecError( "xmldsig.c",1699,__FUNCTION__, ((void*)0), "dsigRefCtx->dsigCtx != NULL" , 100, " "); return; }; | |||
1700 | xmlSecAssert(output != NULL)if(!( output != ((void*)0) ) ) { xmlSecError("xmldsig.c",1700 ,__FUNCTION__, ((void*)0), "output != NULL", 100, " "); return ; }; | |||
1701 | ||||
1702 | if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1703 | fprintf(output, "<ReferenceCalculationContext "); | |||
1704 | } else { | |||
1705 | fprintf(output, "<ReferenceVerificationContext "); | |||
1706 | } | |||
1707 | switch(dsigRefCtx->status) { | |||
1708 | case xmlSecDSigStatusUnknown: | |||
1709 | fprintf(output, "status=\"unknown\" >\n"); | |||
1710 | break; | |||
1711 | case xmlSecDSigStatusSucceeded: | |||
1712 | fprintf(output, "status=\"succeeded\" >\n"); | |||
1713 | break; | |||
1714 | case xmlSecDSigStatusInvalid: | |||
1715 | fprintf(output, "status=\"invalid\" >\n"); | |||
1716 | break; | |||
1717 | } | |||
1718 | ||||
1719 | fprintf(output, "<Id>"); | |||
1720 | xmlSecPrintXmlString(output, dsigRefCtx->id); | |||
1721 | fprintf(output, "</Id>\n"); | |||
1722 | ||||
1723 | fprintf(output, "<URI>"); | |||
1724 | xmlSecPrintXmlString(output, dsigRefCtx->uri); | |||
1725 | fprintf(output, "</URI>\n"); | |||
1726 | ||||
1727 | fprintf(output, "<Type>"); | |||
1728 | xmlSecPrintXmlString(output, dsigRefCtx->type); | |||
1729 | fprintf(output, "</Type>\n"); | |||
1730 | ||||
1731 | fprintf(output, "<ReferenceTransformCtx>\n"); | |||
1732 | xmlSecTransformCtxDebugXmlDump(&(dsigRefCtx->transformCtx), output); | |||
1733 | fprintf(output, "</ReferenceTransformCtx>\n"); | |||
1734 | ||||
1735 | if(dsigRefCtx->digestMethod != NULL((void*)0)) { | |||
1736 | fprintf(output, "<DigestMethod>\n"); | |||
1737 | xmlSecTransformDebugXmlDump(dsigRefCtx->digestMethod, output); | |||
1738 | fprintf(output, "</DigestMethod>\n"); | |||
1739 | } | |||
1740 | ||||
1741 | if((dsigRefCtx->result != NULL((void*)0)) && | |||
1742 | (xmlSecBufferGetData(dsigRefCtx->result) != NULL((void*)0))) { | |||
1743 | ||||
1744 | fprintf(output, "<Result>"); | |||
1745 | fwrite(xmlSecBufferGetData(dsigRefCtx->result), | |||
1746 | xmlSecBufferGetSize(dsigRefCtx->result), 1, | |||
1747 | output); | |||
1748 | fprintf(output, "</Result>\n"); | |||
1749 | } | |||
1750 | ||||
1751 | if((xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx) != NULL((void*)0)) && | |||
1752 | (xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)) != NULL((void*)0))) { | |||
1753 | ||||
1754 | fprintf(output, "<PreDigestData>"); | |||
1755 | fwrite(xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), | |||
1756 | xmlSecBufferGetSize(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), | |||
1757 | 1, output); | |||
1758 | fprintf(output, "</PreDigestData>\n"); | |||
1759 | } | |||
1760 | if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) { | |||
1761 | fprintf(output, "</ReferenceCalculationContext>\n"); | |||
1762 | } else { | |||
1763 | fprintf(output, "</ReferenceVerificationContext>\n"); | |||
1764 | } | |||
1765 | } | |||
1766 | ||||
1767 | ||||
1768 | /************************************************************************** | |||
1769 | * | |||
1770 | * xmlSecDSigReferenceCtxListKlass | |||
1771 | * | |||
1772 | *************************************************************************/ | |||
1773 | static xmlSecPtrListKlass xmlSecDSigReferenceCtxListKlass = { | |||
1774 | BAD_CAST(xmlChar *) "dsig-reference-list", | |||
1775 | NULL((void*)0), /* xmlSecPtrDuplicateItemMethod duplicateItem; */ | |||
1776 | (xmlSecPtrDestroyItemMethod)xmlSecDSigReferenceCtxDestroy, /* xmlSecPtrDestroyItemMethod destroyItem; */ | |||
1777 | (xmlSecPtrDebugDumpItemMethod)xmlSecDSigReferenceCtxDebugDump, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */ | |||
1778 | (xmlSecPtrDebugDumpItemMethod)xmlSecDSigReferenceCtxDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */ | |||
1779 | }; | |||
1780 | ||||
1781 | /** | |||
1782 | * xmlSecDSigReferenceCtxListGetKlass: | |||
1783 | * | |||
1784 | * The <dsig:Reference/> element processing contexts list klass. | |||
1785 | * | |||
1786 | * Returns: <dsig:Reference/> element processing context list klass. | |||
1787 | */ | |||
1788 | xmlSecPtrListId | |||
1789 | xmlSecDSigReferenceCtxListGetKlass(void) { | |||
1790 | return(&xmlSecDSigReferenceCtxListKlass); | |||
1791 | } | |||
1792 | ||||
1793 | #endif /* XMLSEC_NO_XMLDSIG */ | |||
1794 | ||||
1795 |