Bug Summary

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')

Annotated Source Code

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 *************************************************************************/
39static int xmlSecDSigCtxProcessSignatureNode (xmlSecDSigCtxPtr dsigCtx,
40 xmlNodePtr node);
41static int xmlSecDSigCtxProcessSignedInfoNode (xmlSecDSigCtxPtr dsigCtx,
42 xmlNodePtr node);
43static int xmlSecDSigCtxProcessKeyInfoNode (xmlSecDSigCtxPtr dsigCtx,
44 xmlNodePtr node);
45static int xmlSecDSigCtxProcessObjectNode (xmlSecDSigCtxPtr dsigCtx,
46 xmlNodePtr node);
47static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCtx,
48 xmlNodePtr node);
49
50/* The ID attribute in XMLDSig is 'Id' */
51static 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 */
64xmlSecDSigCtxPtr
65xmlSecDSigCtxCreate(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 */
99void
100xmlSecDSigCtxDestroy(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 */
118int
119xmlSecDSigCtxInitialize(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 */
178void
179xmlSecDSigCtxFinalize(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 */
209int
210xmlSecDSigCtxEnableReferenceTransform(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 */
250int
251xmlSecDSigCtxEnableSignatureTransform(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 */
269xmlSecBufferPtr
270xmlSecDSigCtxGetPreSignBuffer(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 */
286int
287xmlSecDSigCtxSign(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 */
350int
351xmlSecDSigCtxVerify(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 */
452static int
453xmlSecDSigCtxProcessSignatureNode(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 */
669static int
670xmlSecDSigCtxProcessSignedInfoNode(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))) {
1
Assuming 'cur' is equal to null
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))) {
2
Taking true branch
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)) {
3
Taking false branch
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) {
4
Taking false branch
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) );
5
'?' condition is false
738 if((cur != NULL((void*)0)) && (xmlSecCheckNodeName(cur, xmlSecNodeSignatureMethod, xmlSecDSigNs))) {
6
Assuming 'cur' is equal to null
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))) {
7
Taking true branch
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)) {
8
Taking false branch
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);
9
Access to field 'next' results in a dereference of a null pointer (loaded from variable 'cur')
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
843static int
844xmlSecDSigCtxProcessKeyInfoNode(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 */
935static int
936xmlSecDSigCtxProcessObjectNode(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 */
993static int
994xmlSecDSigCtxProcessManifestNode(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 */
1065void
1066xmlSecDSigCtxDebugDump(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 */
1145void
1146xmlSecDSigCtxDebugXmlDump(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 */
1249xmlSecDSigReferenceCtxPtr
1250xmlSecDSigReferenceCtxCreate(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 */
1286void
1287xmlSecDSigReferenceCtxDestroy(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 */
1306int
1307xmlSecDSigReferenceCtxInitialize(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 */
1358void
1359xmlSecDSigReferenceCtxFinalize(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 */
1386xmlSecBufferPtr
1387xmlSecDSigReferenceCtxGetPreDigestBuffer(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 */
1414int
1415xmlSecDSigReferenceCtxProcessNode(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 */
1628void
1629xmlSecDSigReferenceCtxDebugDump(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 */
1696void
1697xmlSecDSigReferenceCtxDebugXmlDump(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 *************************************************************************/
1773static 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 */
1788xmlSecPtrListId
1789xmlSecDSigReferenceCtxListGetKlass(void) {
1790 return(&xmlSecDSigReferenceCtxListKlass);
1791}
1792
1793#endif /* XMLSEC_NO_XMLDSIG */
1794
1795