LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/xmlsec/src - xmldsig.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 659 0.0 %
Date: 2012-12-17 Functions: 0 25 0.0 %
Legend: Lines: hit not hit

          Line data    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             :  *************************************************************************/
      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 };
      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           0 : xmlSecDSigCtxCreate(xmlSecKeysMngrPtr keysMngr) {
      66             :     xmlSecDSigCtxPtr dsigCtx;
      67             :     int ret;
      68             :     
      69           0 :     dsigCtx = (xmlSecDSigCtxPtr) xmlMalloc(sizeof(xmlSecDSigCtx));
      70           0 :     if(dsigCtx == NULL) {
      71           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
      72             :                     NULL,
      73             :                     NULL,
      74             :                     XMLSEC_ERRORS_R_MALLOC_FAILED,
      75             :                     "sizeof(xmlSecDSigCtx)=%d", 
      76             :                     sizeof(xmlSecDSigCtx));
      77           0 :         return(NULL);
      78             :     }
      79             :     
      80           0 :     ret = xmlSecDSigCtxInitialize(dsigCtx, keysMngr);
      81           0 :     if(ret < 0) {
      82           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
      83             :                     NULL,
      84             :                     "xmlSecDSigCtxInitialize",
      85             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
      86             :                     XMLSEC_ERRORS_NO_MESSAGE);
      87           0 :         xmlSecDSigCtxDestroy(dsigCtx);
      88           0 :         return(NULL);   
      89             :     }
      90           0 :     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           0 : xmlSecDSigCtxDestroy(xmlSecDSigCtxPtr dsigCtx) {
     101           0 :     xmlSecAssert(dsigCtx != NULL);
     102             :     
     103           0 :     xmlSecDSigCtxFinalize(dsigCtx);
     104           0 :     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           0 : xmlSecDSigCtxInitialize(xmlSecDSigCtxPtr dsigCtx, xmlSecKeysMngrPtr keysMngr) {
     120             :     int ret;
     121             :     
     122           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     123             :     
     124           0 :     memset(dsigCtx, 0, sizeof(xmlSecDSigCtx));
     125             : 
     126             :     /* initialize key info */
     127           0 :     ret = xmlSecKeyInfoCtxInitialize(&(dsigCtx->keyInfoReadCtx), keysMngr);
     128           0 :     if(ret < 0) {
     129           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     130             :                     NULL,
     131             :                     "xmlSecKeyInfoCtxInitialize",
     132             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     133             :                     XMLSEC_ERRORS_NO_MESSAGE);
     134           0 :         return(-1);   
     135             :     }
     136           0 :     dsigCtx->keyInfoReadCtx.mode = xmlSecKeyInfoModeRead;
     137             :     
     138           0 :     ret = xmlSecKeyInfoCtxInitialize(&(dsigCtx->keyInfoWriteCtx), keysMngr);
     139           0 :     if(ret < 0) {
     140           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     141             :                     NULL,
     142             :                     "xmlSecKeyInfoCtxInitialize",
     143             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     144             :                     XMLSEC_ERRORS_NO_MESSAGE);
     145           0 :         return(-1);   
     146             :     }
     147           0 :     dsigCtx->keyInfoWriteCtx.mode = xmlSecKeyInfoModeWrite;
     148             :     /* it's not wise to write private key :) */
     149           0 :     dsigCtx->keyInfoWriteCtx.keyReq.keyType = xmlSecKeyDataTypePublic;
     150             : 
     151             :     /* initializes transforms dsigCtx */
     152           0 :     ret = xmlSecTransformCtxInitialize(&(dsigCtx->transformCtx));
     153           0 :     if(ret < 0) {
     154           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     155             :                     NULL,
     156             :                     "xmlSecTransformCtxInitialize",
     157             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     158             :                     XMLSEC_ERRORS_NO_MESSAGE);
     159           0 :         return(-1);   
     160             :     }
     161             : 
     162             :     /* references lists from SignedInfo and Manifest elements */
     163           0 :     xmlSecPtrListInitialize(&(dsigCtx->signedInfoReferences), 
     164             :                             xmlSecDSigReferenceCtxListId);
     165           0 :     xmlSecPtrListInitialize(&(dsigCtx->manifestReferences), 
     166             :                             xmlSecDSigReferenceCtxListId);    
     167             : 
     168           0 :     dsigCtx->enabledReferenceUris = xmlSecTransformUriTypeAny;
     169           0 :     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           0 : xmlSecDSigCtxFinalize(xmlSecDSigCtxPtr dsigCtx) {
     180           0 :     xmlSecAssert(dsigCtx != NULL);
     181             : 
     182           0 :     xmlSecTransformCtxFinalize(&(dsigCtx->transformCtx));
     183           0 :     xmlSecKeyInfoCtxFinalize(&(dsigCtx->keyInfoReadCtx));
     184           0 :     xmlSecKeyInfoCtxFinalize(&(dsigCtx->keyInfoWriteCtx));
     185           0 :     xmlSecPtrListFinalize(&(dsigCtx->signedInfoReferences));
     186           0 :     xmlSecPtrListFinalize(&(dsigCtx->manifestReferences));
     187             : 
     188           0 :     if(dsigCtx->enabledReferenceTransforms != NULL) {
     189           0 :         xmlSecPtrListDestroy(dsigCtx->enabledReferenceTransforms);   
     190             :     }
     191           0 :     if(dsigCtx->signKey != NULL) {
     192           0 :         xmlSecKeyDestroy(dsigCtx->signKey);
     193             :     }
     194           0 :     if(dsigCtx->id != NULL) {
     195           0 :         xmlFree(dsigCtx->id);
     196             :     }   
     197           0 :     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           0 : xmlSecDSigCtxEnableReferenceTransform(xmlSecDSigCtxPtr dsigCtx, xmlSecTransformId transformId) {
     211             :     int ret;
     212             :     
     213           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     214           0 :     xmlSecAssert2(dsigCtx->result == NULL, -1);
     215           0 :     xmlSecAssert2(transformId != xmlSecTransformIdUnknown, -1);
     216             : 
     217           0 :     if(dsigCtx->enabledReferenceTransforms == NULL) {
     218           0 :         dsigCtx->enabledReferenceTransforms = xmlSecPtrListCreate(xmlSecTransformIdListId);
     219           0 :         if(dsigCtx->enabledReferenceTransforms == NULL) {
     220           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     221             :                         NULL,
     222             :                         "xmlSecPtrListCreate",
     223             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     224             :                         XMLSEC_ERRORS_NO_MESSAGE);
     225           0 :             return(-1);   
     226             :         }
     227             :     }   
     228             :         
     229           0 :     ret = xmlSecPtrListAdd(dsigCtx->enabledReferenceTransforms, (void*)transformId);
     230           0 :     if(ret < 0) {
     231           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     232             :                     NULL,
     233             :                     "xmlSecPtrListAdd",
     234             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     235             :                     XMLSEC_ERRORS_NO_MESSAGE);
     236           0 :         return(-1);   
     237             :     }
     238           0 :     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           0 : xmlSecDSigCtxEnableSignatureTransform(xmlSecDSigCtxPtr dsigCtx, xmlSecTransformId transformId) {
     252           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     253           0 :     xmlSecAssert2(dsigCtx->result == NULL, -1);
     254           0 :     xmlSecAssert2(transformId != xmlSecTransformIdUnknown, -1);
     255             : 
     256           0 :     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           0 : xmlSecDSigCtxGetPreSignBuffer(xmlSecDSigCtxPtr dsigCtx) {
     271           0 :     xmlSecAssert2(dsigCtx != NULL, NULL);
     272             :     
     273           0 :     return((dsigCtx->preSignMemBufMethod != NULL) ? 
     274           0 :             xmlSecTransformMemBufGetBuffer(dsigCtx->preSignMemBufMethod) : NULL);
     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           0 : xmlSecDSigCtxSign(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr tmpl) {
     288             :     int ret;
     289             :     
     290           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     291           0 :     xmlSecAssert2(dsigCtx->result == NULL, -1);
     292           0 :     xmlSecAssert2(tmpl != NULL, -1);
     293           0 :     xmlSecAssert2(tmpl->doc != NULL, -1);
     294             : 
     295             :     /* add ids for Signature nodes */
     296           0 :     dsigCtx->operation       = xmlSecTransformOperationSign;
     297           0 :     dsigCtx->status  = xmlSecDSigStatusUnknown;
     298           0 :     xmlSecAddIDs(tmpl->doc, tmpl, xmlSecDSigIds);
     299             : 
     300             :     /* read signature template */
     301           0 :     ret = xmlSecDSigCtxProcessSignatureNode(dsigCtx, tmpl);
     302           0 :     if(ret < 0) {
     303           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     304             :                     NULL,
     305             :                     "xmlSecDSigCtxSigantureProcessNode",
     306             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     307             :                     XMLSEC_ERRORS_NO_MESSAGE);
     308           0 :         return(-1);
     309             :     }
     310           0 :     xmlSecAssert2(dsigCtx->signMethod != NULL, -1);
     311           0 :     xmlSecAssert2(dsigCtx->signValueNode != NULL, -1);
     312             : 
     313             :     /* references processing might change the status */
     314           0 :     if(dsigCtx->status != xmlSecDSigStatusUnknown) {
     315           0 :         return(0);
     316             :     }
     317             : 
     318             :     /* check what we've got */
     319           0 :     dsigCtx->result = dsigCtx->transformCtx.result;
     320           0 :     if((dsigCtx->result == NULL) || (xmlSecBufferGetData(dsigCtx->result) == NULL)) {
     321           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     322             :                     NULL,
     323             :                     NULL,
     324             :                     XMLSEC_ERRORS_R_INVALID_RESULT,
     325             :                     XMLSEC_ERRORS_NO_MESSAGE);
     326           0 :         return(-1);
     327             :     }
     328             : 
     329             :     /* write signed data to xml */
     330           0 :     xmlNodeSetContentLen(dsigCtx->signValueNode,
     331           0 :                             xmlSecBufferGetData(dsigCtx->result),
     332           0 :                             xmlSecBufferGetSize(dsigCtx->result));
     333             :     
     334             :     /* set success status and we are done */
     335           0 :     dsigCtx->status = xmlSecDSigStatusSucceeded;
     336           0 :     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           0 : xmlSecDSigCtxVerify(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
     352             :     int ret;
     353             :     
     354           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     355           0 :     xmlSecAssert2(node != NULL, -1);
     356           0 :     xmlSecAssert2(node->doc != NULL, -1);
     357             : 
     358             :     /* add ids for Signature nodes */
     359           0 :     dsigCtx->operation       = xmlSecTransformOperationVerify;
     360           0 :     dsigCtx->status  = xmlSecDSigStatusUnknown;
     361           0 :     xmlSecAddIDs(node->doc, node, xmlSecDSigIds);
     362             :     
     363             :     /* read siganture info */
     364           0 :     ret = xmlSecDSigCtxProcessSignatureNode(dsigCtx, node);
     365           0 :     if(ret < 0) {
     366           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     367             :                     NULL,
     368             :                     "xmlSecDSigCtxSigantureProcessNode",
     369             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     370             :                     XMLSEC_ERRORS_NO_MESSAGE);
     371           0 :         return(-1);
     372             :     }
     373           0 :     xmlSecAssert2(dsigCtx->signMethod != NULL, -1);
     374           0 :     xmlSecAssert2(dsigCtx->signValueNode != NULL, -1);
     375             : 
     376             :     /* references processing might change the status */
     377           0 :     if(dsigCtx->status != xmlSecDSigStatusUnknown) {
     378           0 :         return(0);
     379             :     }
     380             : 
     381             :     /* verify SignatureValue node content */
     382           0 :     ret = xmlSecTransformVerifyNodeContent(dsigCtx->signMethod, dsigCtx->signValueNode,
     383           0 :                                            &(dsigCtx->transformCtx));
     384           0 :     if(ret < 0) {
     385           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     386             :                     NULL,
     387             :                     "xmlSecTransformVerifyNodeContent",
     388             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     389             :                     XMLSEC_ERRORS_NO_MESSAGE);
     390           0 :         return(-1);
     391             :     }
     392             :     
     393             :     /* set status and we are done */
     394           0 :     if(dsigCtx->signMethod->status == xmlSecTransformStatusOk) {
     395           0 :         dsigCtx->status = xmlSecDSigStatusSucceeded;
     396             :     } else {
     397           0 :         dsigCtx->status = xmlSecDSigStatusInvalid;
     398             :     }
     399           0 :     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           0 : xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
     454             :     xmlSecTransformDataType firstType;
     455           0 :     xmlNodePtr signedInfoNode = NULL;
     456           0 :     xmlNodePtr keyInfoNode = NULL;
     457             :     xmlNodePtr cur;
     458             :     int ret;
     459             :     
     460           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     461           0 :     xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify), -1);
     462           0 :     xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
     463           0 :     xmlSecAssert2(dsigCtx->signValueNode == NULL, -1);
     464           0 :     xmlSecAssert2(dsigCtx->signMethod == NULL, -1);
     465           0 :     xmlSecAssert2(dsigCtx->c14nMethod == NULL, -1);
     466           0 :     xmlSecAssert2(node != NULL, -1);
     467             : 
     468           0 :     if(!xmlSecCheckNodeName(node, xmlSecNodeSignature, xmlSecDSigNs)) {
     469           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     470             :                     NULL,
     471           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
     472             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     473             :                     "expected=%s",
     474             :                     xmlSecErrorsSafeString(xmlSecNodeSignature));
     475           0 :         return(-1);         
     476             :     }
     477             : 
     478             :     /* read node data */
     479           0 :     xmlSecAssert2(dsigCtx->id == NULL, -1);
     480           0 :     dsigCtx->id = xmlGetProp(node, xmlSecAttrId);
     481             : 
     482             :     /* first node is required SignedInfo */
     483           0 :     cur = xmlSecGetNextElementNode(node->children);    
     484           0 :     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeSignedInfo, xmlSecDSigNs))) {
     485           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     486             :                     NULL,
     487           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     488             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     489             :                     "expected=%s",
     490             :                     xmlSecErrorsSafeString(xmlSecNodeSignedInfo));
     491           0 :         return(-1);
     492             :     }
     493           0 :     signedInfoNode = cur;
     494           0 :     cur = xmlSecGetNextElementNode(cur->next);
     495             : 
     496             :     /* next node is required SignatureValue */
     497           0 :     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeSignatureValue, xmlSecDSigNs))) {
     498           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     499             :                     NULL,
     500           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     501             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     502             :                     "expected=%s",
     503             :                     xmlSecErrorsSafeString(xmlSecNodeSignatureValue));
     504           0 :         return(-1);
     505             :     }
     506           0 :     dsigCtx->signValueNode = cur;
     507           0 :     cur = xmlSecGetNextElementNode(cur->next);
     508             : 
     509             :     /* next node is optional KeyInfo */
     510           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs))) {
     511           0 :         keyInfoNode = cur;
     512           0 :         cur = xmlSecGetNextElementNode(cur->next);
     513             :     } else {
     514           0 :         keyInfoNode = NULL;
     515             :     }
     516             :     
     517             :     /* next nodes are optional Object nodes */
     518           0 :     while((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeObject, xmlSecDSigNs))) {
     519             :         /* read manifests from objects */
     520           0 :         if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_IGNORE_MANIFESTS) == 0) {
     521           0 :             ret = xmlSecDSigCtxProcessObjectNode(dsigCtx, cur);
     522           0 :             if(ret < 0) {
     523           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     524             :                             NULL,
     525             :                             "xmlSecDSigCtxProcessObjectNode",
     526             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     527             :                             XMLSEC_ERRORS_NO_MESSAGE);
     528           0 :                 return(-1);                 
     529             :             }
     530             :         }
     531           0 :         cur = xmlSecGetNextElementNode(cur->next);
     532             :     }
     533             :     
     534             :     /* if there is something left than it's an error */
     535           0 :     if(cur != NULL) {
     536           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     537             :                     NULL,
     538           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     539             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
     540             :                     XMLSEC_ERRORS_NO_MESSAGE);
     541           0 :         return(-1);
     542             :     }
     543             : 
     544             :     /* now validated all the references and prepare transform */
     545           0 :     ret = xmlSecDSigCtxProcessSignedInfoNode(dsigCtx, signedInfoNode);
     546           0 :     if(ret < 0) {
     547           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     548             :                     NULL,
     549             :                     "xmlSecDSigCtxProcessSignedInfoNode",
     550             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     551             :                     XMLSEC_ERRORS_NO_MESSAGE);
     552           0 :         return(-1);     
     553             :     }                           
     554             :     /* references processing might change the status */
     555           0 :     if(dsigCtx->status != xmlSecDSigStatusUnknown) {
     556           0 :         return(0);
     557             :     }
     558             :     
     559             :     /* as the result, we should have sign and c14n methods set */    
     560           0 :     xmlSecAssert2(dsigCtx->signMethod != NULL, -1);
     561           0 :     xmlSecAssert2(dsigCtx->c14nMethod != NULL, -1);
     562             : 
     563           0 :     ret = xmlSecDSigCtxProcessKeyInfoNode(dsigCtx, keyInfoNode);
     564           0 :     if(ret < 0) {
     565           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     566             :                     NULL,
     567             :                     "xmlSecDSigCtxProcessKeyInfoNode",
     568             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     569             :                     XMLSEC_ERRORS_NO_MESSAGE);
     570           0 :         return(-1);     
     571             :     }                           
     572             :     /* as the result, we should have a key */
     573           0 :     xmlSecAssert2(dsigCtx->signKey != NULL, -1);
     574             : 
     575             :     /* if we need to write result to xml node then we need base64 encode result */
     576           0 :     if(dsigCtx->operation == xmlSecTransformOperationSign) { 
     577             :         xmlSecTransformPtr base64Encode;
     578             :         
     579             :         /* we need to add base64 encode transform */
     580           0 :         base64Encode = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), 
     581             :                                                          xmlSecTransformBase64Id);
     582           0 :         if(base64Encode == NULL) {
     583           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     584             :                         NULL,
     585             :                         "xmlSecTransformCtxCreateAndAppend",
     586             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     587             :                         XMLSEC_ERRORS_NO_MESSAGE);
     588           0 :             return(-1);
     589             :         }
     590           0 :         base64Encode->operation = xmlSecTransformOperationEncode;
     591             :     }
     592             : 
     593           0 :     firstType = xmlSecTransformGetDataType(dsigCtx->transformCtx.first, 
     594             :                                            xmlSecTransformModePush, 
     595           0 :                                            &(dsigCtx->transformCtx));
     596           0 :     if((firstType & xmlSecTransformDataTypeXml) != 0) {
     597           0 :         xmlSecNodeSetPtr nodeset = NULL;
     598             : 
     599           0 :         xmlSecAssert2(signedInfoNode != NULL, -1);
     600           0 :         nodeset = xmlSecNodeSetGetChildren(signedInfoNode->doc, signedInfoNode, 1, 0);
     601           0 :         if(nodeset == NULL) {
     602           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     603             :                         NULL,
     604             :                         "xmlSecNodeSetGetChildren",
     605             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     606             :                         "node=%s",
     607           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(signedInfoNode)));
     608           0 :             return(-1);
     609             :         }
     610             : 
     611             :         /* calculate the signature */
     612           0 :         ret = xmlSecTransformCtxXmlExecute(&(dsigCtx->transformCtx), nodeset);
     613           0 :         if(ret < 0) {
     614           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     615             :                         NULL,
     616             :                         "xmlSecTransformCtxXmlExecute",
     617             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     618             :                         XMLSEC_ERRORS_NO_MESSAGE);
     619           0 :             xmlSecNodeSetDestroy(nodeset);
     620           0 :             return(-1);
     621             :         }
     622           0 :         xmlSecNodeSetDestroy(nodeset);
     623             :     } else {
     624             :         /* TODO */
     625           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     626             :                     NULL,
     627             :                     "the binary c14n transforms are not supported yet",
     628             :                     XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
     629             :                     XMLSEC_ERRORS_NO_MESSAGE);
     630           0 :         return(-1);
     631             :     }
     632           0 :     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           0 : xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
     671             :     xmlSecDSigReferenceCtxPtr dsigRefCtx;
     672             :     xmlNodePtr cur;
     673             :     int ret;
     674             :     
     675           0 :     xmlSecAssert2(dsigCtx != NULL, -1); 
     676           0 :     xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
     677           0 :     xmlSecAssert2(dsigCtx->signMethod == NULL, -1);
     678           0 :     xmlSecAssert2(dsigCtx->c14nMethod == NULL, -1);
     679           0 :     xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify), -1);
     680           0 :     xmlSecAssert2(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0, -1);
     681           0 :     xmlSecAssert2(node != NULL, -1);
     682             :     
     683             :     /* first node is required CanonicalizationMethod. */
     684           0 :     cur = xmlSecGetNextElementNode(node->children);
     685           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs))) {
     686           0 :         dsigCtx->c14nMethod = xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx), 
     687             :                                         cur, xmlSecTransformUsageC14NMethod);
     688           0 :         if(dsigCtx->c14nMethod == NULL) {
     689           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     690             :                         NULL,
     691             :                         "xmlSecTransformCtxNodeRead",
     692             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     693             :                         "node=%s",
     694           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     695           0 :             return(-1); 
     696             :         }       
     697           0 :     } else if(dsigCtx->defC14NMethodId != xmlSecTransformIdUnknown) {
     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           0 :         dsigCtx->c14nMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), 
     702             :                                                               dsigCtx->defC14NMethodId);
     703           0 :         if(dsigCtx->c14nMethod == NULL) {
     704           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     705             :                         NULL,
     706             :                         "xmlSecTransformCtxAppend",
     707             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     708             :                         XMLSEC_ERRORS_NO_MESSAGE);
     709           0 :             return(-1);
     710             :         }
     711             :     } else {
     712           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     713             :                     NULL,
     714             :                     "CanonicalizationMethod",
     715             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     716             :                     "expected=%s",
     717             :                     xmlSecErrorsSafeString(xmlSecNodeCanonicalizationMethod));
     718           0 :         return(-1);
     719             :     }
     720             :     
     721             :     /* insert membuf if requested */
     722           0 :     if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE) != 0) {
     723           0 :         xmlSecAssert2(dsigCtx->preSignMemBufMethod == NULL, -1);
     724           0 :         dsigCtx->preSignMemBufMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), 
     725             :                                                 xmlSecTransformMemBufId);
     726           0 :         if(dsigCtx->preSignMemBufMethod == NULL) {
     727           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     728             :                         NULL,
     729             :                         "xmlSecTransformCtxCreateAndAppend",
     730             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     731             :                         "transform=%s",
     732           0 :                         xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecTransformMemBufId)));
     733             :         }
     734             :     }
     735             :         
     736             :     /* next node is required SignatureMethod. */
     737           0 :     cur = xmlSecGetNextElementNode( ((cur != NULL) ? cur->next : node->children) );
     738           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeSignatureMethod, xmlSecDSigNs))) {
     739           0 :         dsigCtx->signMethod = xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx), 
     740             :                                         cur, xmlSecTransformUsageSignatureMethod);
     741           0 :         if(dsigCtx->signMethod == NULL) {
     742           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     743             :                         NULL,
     744             :                         "xmlSecTransformCtxNodeRead",
     745             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     746             :                         "node=%s",
     747           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     748           0 :             return(-1); 
     749             :         }       
     750           0 :     } else if(dsigCtx->defSignMethodId != xmlSecTransformIdUnknown) {
     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           0 :         dsigCtx->signMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx), 
     755             :                                                               dsigCtx->defSignMethodId);
     756           0 :         if(dsigCtx->signMethod == NULL) {
     757           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     758             :                         NULL,
     759             :                         "xmlSecTransformCtxAppend",
     760             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     761             :                         XMLSEC_ERRORS_NO_MESSAGE);
     762           0 :             return(-1);
     763             :         }
     764             :     } else {
     765           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     766             :                     NULL,
     767           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     768             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     769             :                     "expected=%s",
     770             :                     xmlSecErrorsSafeString(xmlSecNodeSignatureMethod));
     771           0 :         return(-1);
     772             :     }   
     773           0 :     dsigCtx->signMethod->operation = dsigCtx->operation;
     774             :     
     775             :     /* calculate references */
     776           0 :     cur = xmlSecGetNextElementNode(cur->next);
     777           0 :     while((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs))) {
     778             :         /* create reference */
     779           0 :         dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginSignedInfo);
     780           0 :         if(dsigRefCtx == NULL) {
     781           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     782             :                         NULL,
     783             :                         "xmlSecDSigReferenceCtxCreate",
     784             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     785             :                         XMLSEC_ERRORS_NO_MESSAGE);
     786           0 :             return(-1);     
     787             :         }
     788             : 
     789             :         /* add to the list */
     790           0 :         ret = xmlSecPtrListAdd(&(dsigCtx->signedInfoReferences), dsigRefCtx);
     791           0 :         if(ret < 0) {
     792           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     793             :                         NULL,
     794             :                         "xmlSecPtrListAdd",
     795             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     796             :                         XMLSEC_ERRORS_NO_MESSAGE);
     797           0 :             xmlSecDSigReferenceCtxDestroy(dsigRefCtx);
     798           0 :             return(-1);     
     799             :         }
     800             : 
     801             :         /* process */
     802           0 :         ret = xmlSecDSigReferenceCtxProcessNode(dsigRefCtx, cur);
     803           0 :         if(ret < 0) {
     804           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     805             :                         NULL,
     806             :                         "xmlSecDSigReferenceCtxProcessNode",
     807             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     808             :                         "node=%s",
     809           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     810           0 :             return(-1);     
     811             :         }
     812             : 
     813             :         /* bail out if next Reference processing failed */
     814           0 :         if(dsigRefCtx->status != xmlSecDSigStatusSucceeded) {
     815           0 :             dsigCtx->status = xmlSecDSigStatusInvalid;
     816           0 :             return(0); 
     817             :         }
     818           0 :         cur = xmlSecGetNextElementNode(cur->next);
     819             :     }
     820             : 
     821             :     /* check that we have at least one Reference */
     822           0 :     if(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0) {
     823           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     824             :                     NULL,
     825             :                     NULL,
     826             :                     XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,
     827             :                     XMLSEC_ERRORS_NO_MESSAGE);
     828           0 :         return(-1);
     829             :     }
     830             : 
     831             :     /* if there is something left than it's an error */
     832           0 :     if(cur != NULL) {
     833           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     834             :                     NULL,
     835           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     836             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
     837             :                     XMLSEC_ERRORS_NO_MESSAGE);
     838           0 :         return(-1);
     839             :     }
     840           0 :     return(0);
     841             : }
     842             : 
     843             : static int 
     844           0 : xmlSecDSigCtxProcessKeyInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
     845             :     int ret;
     846             :     
     847           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
     848           0 :     xmlSecAssert2(dsigCtx->signMethod != NULL, -1);
     849             : 
     850             :     /* set key requirements */
     851           0 :     ret = xmlSecTransformSetKeyReq(dsigCtx->signMethod, &(dsigCtx->keyInfoReadCtx.keyReq));
     852           0 :     if(ret < 0) {
     853           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     854             :                     NULL,
     855             :                     "xmlSecTransformSetKeyReq",
     856             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     857             :                     "transform=%s",
     858           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(dsigCtx->signMethod)));
     859           0 :         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           0 :     if((dsigCtx->signKey == NULL) && (dsigCtx->keyInfoReadCtx.keysMngr != NULL) 
     865           0 :                         && (dsigCtx->keyInfoReadCtx.keysMngr->getKey != NULL)) {  
     866           0 :         dsigCtx->signKey = (dsigCtx->keyInfoReadCtx.keysMngr->getKey)(node, &(dsigCtx->keyInfoReadCtx));
     867             :     }
     868             :     
     869             :     /* check that we have exactly what we want */
     870           0 :     if((dsigCtx->signKey == NULL) || (!xmlSecKeyMatch(dsigCtx->signKey, NULL, &(dsigCtx->keyInfoReadCtx.keyReq)))) {
     871           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     872             :                     NULL,
     873             :                     NULL,
     874             :                     XMLSEC_ERRORS_R_KEY_NOT_FOUND,
     875             :                     XMLSEC_ERRORS_NO_MESSAGE);
     876           0 :         return(-1);
     877             :     }
     878             :     
     879             :     /* set the key to the transform */
     880           0 :     ret = xmlSecTransformSetKey(dsigCtx->signMethod, dsigCtx->signKey);
     881           0 :     if(ret < 0) {
     882           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     883             :                     NULL,
     884             :                     "xmlSecTransformSetKey",
     885             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     886             :                     "transform=%s",
     887           0 :                     xmlSecErrorsSafeString(xmlSecTransformGetName(dsigCtx->signMethod)));
     888           0 :         return(-1);
     889             :     }
     890             : 
     891             :     /* if we are signing document, update <dsig:KeyInfo/> node */
     892           0 :     if((node != NULL) && (dsigCtx->operation == xmlSecTransformOperationSign)) {     
     893           0 :         ret = xmlSecKeyInfoNodeWrite(node, dsigCtx->signKey, &(dsigCtx->keyInfoWriteCtx));
     894           0 :         if(ret < 0) {
     895           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     896             :                         NULL,
     897             :                         "xmlSecKeyInfoNodeWrite",
     898             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     899             :                         XMLSEC_ERRORS_NO_MESSAGE);
     900           0 :             return(-1);
     901             :         }       
     902             :     }
     903             :     
     904           0 :     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           0 : xmlSecDSigCtxProcessObjectNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
     937             :     xmlNodePtr cur;
     938             :     int ret;
     939             : 
     940           0 :     xmlSecAssert2(dsigCtx != NULL, -1); 
     941           0 :     xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
     942           0 :     xmlSecAssert2(node != NULL, -1);
     943             :     
     944             :     /* we care about Manifest nodes only; ignore everything else */
     945           0 :     cur = xmlSecGetNextElementNode(node->children);
     946           0 :     while(cur != NULL) {
     947           0 :         if(xmlSecCheckNodeName(cur, xmlSecNodeManifest, xmlSecDSigNs)) {
     948           0 :             ret = xmlSecDSigCtxProcessManifestNode(dsigCtx, cur);
     949           0 :             if(ret < 0){
     950           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     951             :                             NULL,
     952             :                             "xmlSecDSigCtxProcessManifestNode",
     953             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     954             :                             XMLSEC_ERRORS_NO_MESSAGE);
     955           0 :                 return(-1);         
     956             :             }
     957             :         }
     958           0 :         cur = xmlSecGetNextElementNode(cur->next);
     959             :     }
     960           0 :     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           0 : xmlSecDSigCtxProcessManifestNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
     995             :     xmlSecDSigReferenceCtxPtr dsigRefCtx;
     996             :     xmlNodePtr cur;
     997             :     int ret;
     998             : 
     999           0 :     xmlSecAssert2(dsigCtx != NULL, -1); 
    1000           0 :     xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
    1001           0 :     xmlSecAssert2(node != NULL, -1);
    1002             : 
    1003             :     /* calculate references */
    1004           0 :     cur = xmlSecGetNextElementNode(node->children);
    1005           0 :     while((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs))) {
    1006             :         /* create reference */
    1007           0 :         dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginManifest);
    1008           0 :         if(dsigRefCtx == NULL) {
    1009           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1010             :                         NULL,
    1011             :                         "xmlSecDSigReferenceCtxCreate",
    1012             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1013             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1014           0 :             return(-1);     
    1015             :         }
    1016             : 
    1017             :         /* add to the list */
    1018           0 :         ret = xmlSecPtrListAdd(&(dsigCtx->manifestReferences), dsigRefCtx);
    1019           0 :         if(ret < 0) {
    1020           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1021             :                         NULL,
    1022             :                         "xmlSecPtrListAdd",
    1023             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1024             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1025           0 :             xmlSecDSigReferenceCtxDestroy(dsigRefCtx);
    1026           0 :             return(-1);     
    1027             :         }
    1028             : 
    1029             :         /* process */
    1030           0 :         ret = xmlSecDSigReferenceCtxProcessNode(dsigRefCtx, cur);
    1031           0 :         if(ret < 0) {
    1032           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1033             :                         NULL,
    1034             :                         "xmlSecDSigReferenceCtxProcessNode",
    1035             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1036             :                         "node=%s",
    1037           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
    1038           0 :             return(-1);     
    1039             :         }
    1040             : 
    1041             :         /* we don;t care if Reference processing failed because
    1042             :          * it's Manifest node */
    1043           0 :         cur = xmlSecGetNextElementNode(cur->next);
    1044             :     }
    1045             : 
    1046             :     /* we should have nothing else here */
    1047           0 :     if(cur != NULL) {
    1048           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1049             :                     NULL,
    1050           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
    1051             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
    1052             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1053           0 :         return(-1);
    1054             :     }    
    1055           0 :     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           0 : xmlSecDSigCtxDebugDump(xmlSecDSigCtxPtr dsigCtx, FILE* output) {
    1067           0 :     xmlSecAssert(dsigCtx != NULL);
    1068           0 :     xmlSecAssert(output != NULL);
    1069             : 
    1070           0 :     if(dsigCtx->operation == xmlSecTransformOperationSign) {    
    1071           0 :         fprintf(output, "= SIGNATURE CONTEXT\n");
    1072             :     } else {
    1073           0 :         fprintf(output, "= VERIFICATION CONTEXT\n");
    1074             :     }
    1075           0 :     switch(dsigCtx->status) {
    1076             :         case xmlSecDSigStatusUnknown:
    1077           0 :             fprintf(output, "== Status: unknown\n");
    1078           0 :             break;
    1079             :         case xmlSecDSigStatusSucceeded:
    1080           0 :             fprintf(output, "== Status: succeeded\n");
    1081           0 :             break;
    1082             :         case xmlSecDSigStatusInvalid:
    1083           0 :             fprintf(output, "== Status: invalid\n");
    1084           0 :             break;
    1085             :     }
    1086           0 :     fprintf(output, "== flags: 0x%08x\n", dsigCtx->flags);
    1087           0 :     fprintf(output, "== flags2: 0x%08x\n", dsigCtx->flags2);
    1088             : 
    1089           0 :     if(dsigCtx->id != NULL) {
    1090           0 :         fprintf(output, "== Id: \"%s\"\n", dsigCtx->id);
    1091             :     }
    1092             :     
    1093           0 :     fprintf(output, "== Key Info Read Ctx:\n");
    1094           0 :     xmlSecKeyInfoCtxDebugDump(&(dsigCtx->keyInfoReadCtx), output);
    1095           0 :     fprintf(output, "== Key Info Write Ctx:\n");
    1096           0 :     xmlSecKeyInfoCtxDebugDump(&(dsigCtx->keyInfoWriteCtx), output);
    1097             : 
    1098           0 :     fprintf(output, "== Signature Transform Ctx:\n");
    1099           0 :     xmlSecTransformCtxDebugDump(&(dsigCtx->transformCtx), output);
    1100             : 
    1101           0 :     if(dsigCtx->signMethod != NULL) {
    1102           0 :         fprintf(output, "== Signature Method:\n");
    1103           0 :         xmlSecTransformDebugDump(dsigCtx->signMethod, output);
    1104             :     }
    1105             : 
    1106           0 :     if(dsigCtx->signKey != NULL) {
    1107           0 :         fprintf(output, "== Signature Key:\n");
    1108           0 :         xmlSecKeyDebugDump(dsigCtx->signKey, output);
    1109             :     }
    1110             :     
    1111           0 :     fprintf(output, "== SignedInfo References List:\n");
    1112           0 :     xmlSecPtrListDebugDump(&(dsigCtx->signedInfoReferences), output);
    1113             : 
    1114           0 :     fprintf(output, "== Manifest References List:\n");
    1115           0 :     xmlSecPtrListDebugDump(&(dsigCtx->manifestReferences), output);
    1116             :     
    1117           0 :     if((dsigCtx->result != NULL) && 
    1118           0 :        (xmlSecBufferGetData(dsigCtx->result) != NULL)) {
    1119             : 
    1120           0 :         fprintf(output, "== Result - start buffer:\n");
    1121           0 :         fwrite(xmlSecBufferGetData(dsigCtx->result), 
    1122             :                xmlSecBufferGetSize(dsigCtx->result), 
    1123             :                1, output);
    1124           0 :         fprintf(output, "\n== Result - end buffer\n");
    1125             :     }
    1126           0 :     if(((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE) != 0) &&
    1127           0 :        (xmlSecDSigCtxGetPreSignBuffer(dsigCtx) != NULL) &&
    1128           0 :        (xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)) != NULL)) {
    1129             :        
    1130           0 :         fprintf(output, "== PreSigned data - start buffer:\n");
    1131           0 :         fwrite(xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), 
    1132             :                xmlSecBufferGetSize(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), 
    1133             :                1, output);
    1134           0 :         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           0 : xmlSecDSigCtxDebugXmlDump(xmlSecDSigCtxPtr dsigCtx, FILE* output) {
    1147           0 :     xmlSecAssert(dsigCtx != NULL);
    1148           0 :     xmlSecAssert(output != NULL);
    1149             : 
    1150           0 :     if(dsigCtx->operation == xmlSecTransformOperationSign) {    
    1151           0 :         fprintf(output, "<SignatureContext \n");
    1152             :     } else {
    1153           0 :         fprintf(output, "<VerificationContext \n");
    1154             :     }
    1155           0 :     switch(dsigCtx->status) {
    1156             :         case xmlSecDSigStatusUnknown:
    1157           0 :             fprintf(output, "status=\"unknown\" >\n");
    1158           0 :             break;
    1159             :         case xmlSecDSigStatusSucceeded:
    1160           0 :             fprintf(output, "status=\"succeeded\" >\n");
    1161           0 :             break;
    1162             :         case xmlSecDSigStatusInvalid:
    1163           0 :             fprintf(output, "status=\"invalid\" >\n");
    1164           0 :             break;
    1165             :     }
    1166             : 
    1167           0 :     fprintf(output, "<Flags>%08x</Flags>\n", dsigCtx->flags);
    1168           0 :     fprintf(output, "<Flags2>%08x</Flags2>\n", dsigCtx->flags2);
    1169             : 
    1170           0 :     fprintf(output, "<Id>");
    1171           0 :     xmlSecPrintXmlString(output, dsigCtx->id);
    1172           0 :     fprintf(output, "</Id>\n");
    1173             : 
    1174           0 :     fprintf(output, "<KeyInfoReadCtx>\n");
    1175           0 :     xmlSecKeyInfoCtxDebugXmlDump(&(dsigCtx->keyInfoReadCtx), output);
    1176           0 :     fprintf(output, "</KeyInfoReadCtx>\n");
    1177             : 
    1178           0 :     fprintf(output, "<KeyInfoWriteCtx>\n");
    1179           0 :     xmlSecKeyInfoCtxDebugXmlDump(&(dsigCtx->keyInfoWriteCtx), output);
    1180           0 :     fprintf(output, "</KeyInfoWriteCtx>\n");
    1181             : 
    1182           0 :     fprintf(output, "<SignatureTransformCtx>\n");
    1183           0 :     xmlSecTransformCtxDebugXmlDump(&(dsigCtx->transformCtx), output);
    1184           0 :     fprintf(output, "</SignatureTransformCtx>\n");
    1185             : 
    1186           0 :     if(dsigCtx->signMethod != NULL) {
    1187           0 :         fprintf(output, "<SignatureMethod>\n");
    1188           0 :         xmlSecTransformDebugXmlDump(dsigCtx->signMethod, output);
    1189           0 :         fprintf(output, "</SignatureMethod>\n");
    1190             :     }
    1191             : 
    1192           0 :     if(dsigCtx->signKey != NULL) {
    1193           0 :         fprintf(output, "<SignatureKey>\n");
    1194           0 :         xmlSecKeyDebugXmlDump(dsigCtx->signKey, output);
    1195           0 :         fprintf(output, "</SignatureKey>\n");
    1196             :     }
    1197             : 
    1198           0 :     fprintf(output, "<SignedInfoReferences>\n");
    1199           0 :     xmlSecPtrListDebugXmlDump(&(dsigCtx->signedInfoReferences), output);
    1200           0 :     fprintf(output, "</SignedInfoReferences>\n");
    1201             : 
    1202           0 :     fprintf(output, "<ManifestReferences>\n");
    1203           0 :     xmlSecPtrListDebugXmlDump(&(dsigCtx->manifestReferences), output);
    1204           0 :     fprintf(output, "</ManifestReferences>\n");
    1205             : 
    1206           0 :     if((dsigCtx->result != NULL) && 
    1207           0 :        (xmlSecBufferGetData(dsigCtx->result) != NULL)) {
    1208             : 
    1209           0 :         fprintf(output, "<Result>");
    1210           0 :         fwrite(xmlSecBufferGetData(dsigCtx->result), 
    1211             :                xmlSecBufferGetSize(dsigCtx->result), 
    1212             :                1, output);
    1213           0 :         fprintf(output, "</Result>\n");
    1214             :     }
    1215           0 :     if(((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE) != 0) &&
    1216           0 :        (xmlSecDSigCtxGetPreSignBuffer(dsigCtx) != NULL) &&
    1217           0 :        (xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)) != NULL)) {
    1218             :        
    1219           0 :         fprintf(output, "<PreSignedData>");
    1220           0 :         fwrite(xmlSecBufferGetData(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), 
    1221             :                xmlSecBufferGetSize(xmlSecDSigCtxGetPreSignBuffer(dsigCtx)), 
    1222             :                1, output);
    1223           0 :         fprintf(output, "</PreSignedData>\n");       
    1224             :     }
    1225             : 
    1226           0 :     if(dsigCtx->operation == xmlSecTransformOperationSign) {    
    1227           0 :         fprintf(output, "</SignatureContext>\n");
    1228             :     } else {
    1229           0 :         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           0 : xmlSecDSigReferenceCtxCreate(xmlSecDSigCtxPtr dsigCtx, xmlSecDSigReferenceOrigin origin) {
    1251             :     xmlSecDSigReferenceCtxPtr dsigRefCtx;
    1252             :     int ret;
    1253             :     
    1254           0 :     xmlSecAssert2(dsigCtx != NULL, NULL);
    1255             :     
    1256           0 :     dsigRefCtx = (xmlSecDSigReferenceCtxPtr) xmlMalloc(sizeof(xmlSecDSigReferenceCtx));
    1257           0 :     if(dsigRefCtx == NULL) {
    1258           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1259             :                     NULL,
    1260             :                     NULL,
    1261             :                     XMLSEC_ERRORS_R_MALLOC_FAILED,
    1262             :                     "sizeof(xmlSecDSigReferenceCtx)=%d", 
    1263             :                     sizeof(xmlSecDSigReferenceCtx));
    1264           0 :         return(NULL);
    1265             :     }
    1266             :     
    1267           0 :     ret = xmlSecDSigReferenceCtxInitialize(dsigRefCtx, dsigCtx, origin);
    1268           0 :     if(ret < 0) {
    1269           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1270             :                     NULL,
    1271             :                     "xmlSecDSigReferenceCtxInitialize",
    1272             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1273             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1274           0 :         xmlSecDSigReferenceCtxDestroy(dsigRefCtx);
    1275           0 :         return(NULL);   
    1276             :     }
    1277           0 :     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           0 : xmlSecDSigReferenceCtxDestroy(xmlSecDSigReferenceCtxPtr dsigRefCtx) {
    1288           0 :     xmlSecAssert(dsigRefCtx != NULL);
    1289             :     
    1290           0 :     xmlSecDSigReferenceCtxFinalize(dsigRefCtx);
    1291           0 :     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           0 : xmlSecDSigReferenceCtxInitialize(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlSecDSigCtxPtr dsigCtx,
    1308             :                                 xmlSecDSigReferenceOrigin origin) {
    1309             :     int ret;
    1310             :     
    1311           0 :     xmlSecAssert2(dsigCtx != NULL, -1);
    1312           0 :     xmlSecAssert2(dsigRefCtx != NULL, -1);
    1313             :     
    1314           0 :     memset(dsigRefCtx, 0, sizeof(xmlSecDSigReferenceCtx));
    1315             :     
    1316           0 :     dsigRefCtx->dsigCtx = dsigCtx;
    1317           0 :     dsigRefCtx->origin = origin;
    1318             :     
    1319             :     /* initializes transforms dsigRefCtx */
    1320           0 :     ret = xmlSecTransformCtxInitialize(&(dsigRefCtx->transformCtx));
    1321           0 :     if(ret < 0) {
    1322           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1323             :                     NULL,
    1324             :                     "xmlSecTransformCtxInitialize",
    1325             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1326             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1327           0 :         return(-1);   
    1328             :     }
    1329             :     
    1330             :     /* copy enabled transforms */
    1331           0 :     if(dsigCtx->enabledReferenceTransforms != NULL) {
    1332           0 :         ret = xmlSecPtrListCopy(&(dsigRefCtx->transformCtx.enabledTransforms), 
    1333             :                                      dsigCtx->enabledReferenceTransforms);
    1334           0 :         if(ret < 0) {
    1335           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1336             :                         NULL,
    1337             :                         "xmlSecPtrListCopy",
    1338             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1339             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1340           0 :             return(-1);   
    1341             :         }
    1342             :     }    
    1343           0 :     dsigRefCtx->transformCtx.preExecCallback = dsigCtx->referencePreExecuteCallback;
    1344           0 :     dsigRefCtx->transformCtx.enabledUris = dsigCtx->enabledReferenceUris;
    1345             : 
    1346           0 :     if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_USE_VISA3D_HACK) != 0) {
    1347           0 :         dsigRefCtx->transformCtx.flags |= XMLSEC_TRANSFORMCTX_FLAGS_USE_VISA3D_HACK;
    1348             :     }
    1349           0 :     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           0 : xmlSecDSigReferenceCtxFinalize(xmlSecDSigReferenceCtxPtr dsigRefCtx) {
    1360           0 :     xmlSecAssert(dsigRefCtx != NULL);
    1361             : 
    1362           0 :     xmlSecTransformCtxFinalize(&(dsigRefCtx->transformCtx));
    1363           0 :     if(dsigRefCtx->id != NULL) {
    1364           0 :         xmlFree(dsigRefCtx->id);
    1365             :     }   
    1366           0 :     if(dsigRefCtx->uri != NULL) {
    1367           0 :         xmlFree(dsigRefCtx->uri);
    1368             :     }   
    1369           0 :     if(dsigRefCtx->type != NULL) {
    1370           0 :         xmlFree(dsigRefCtx->type);
    1371             :     }   
    1372           0 :     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           0 : xmlSecDSigReferenceCtxGetPreDigestBuffer(xmlSecDSigReferenceCtxPtr dsigRefCtx) {
    1388           0 :     xmlSecAssert2(dsigRefCtx != NULL, NULL);
    1389             :     
    1390           0 :     return((dsigRefCtx->preDigestMemBufMethod != NULL) ? 
    1391           0 :             xmlSecTransformMemBufGetBuffer(dsigRefCtx->preDigestMemBufMethod) : NULL);
    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           0 : xmlSecDSigReferenceCtxProcessNode(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodePtr node) {
    1416             :     xmlSecTransformCtxPtr transformCtx;
    1417             :     xmlNodePtr digestValueNode;
    1418             :     xmlNodePtr cur;
    1419             :     int ret;
    1420             :     
    1421           0 :     xmlSecAssert2(dsigRefCtx != NULL, -1);
    1422           0 :     xmlSecAssert2(dsigRefCtx->dsigCtx != NULL, -1);
    1423           0 :     xmlSecAssert2(dsigRefCtx->digestMethod == NULL, -1);
    1424           0 :     xmlSecAssert2(dsigRefCtx->digestMethod == NULL, -1);
    1425           0 :     xmlSecAssert2(dsigRefCtx->preDigestMemBufMethod == NULL, -1);
    1426           0 :     xmlSecAssert2(node != NULL, -1);
    1427           0 :     xmlSecAssert2(node->doc != NULL, -1);
    1428             : 
    1429           0 :     transformCtx = &(dsigRefCtx->transformCtx);
    1430             : 
    1431             :     /* read attributes first */
    1432           0 :     dsigRefCtx->uri = xmlGetProp(node, xmlSecAttrURI);
    1433           0 :     dsigRefCtx->id  = xmlGetProp(node, xmlSecAttrId);
    1434           0 :     dsigRefCtx->type= xmlGetProp(node, xmlSecAttrType);
    1435             : 
    1436             :     /* set start URI (and check that it is enabled!) */
    1437           0 :     ret = xmlSecTransformCtxSetUri(transformCtx, dsigRefCtx->uri, node);
    1438           0 :     if(ret < 0) {
    1439           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1440             :                     NULL,
    1441             :                     "xmlSecTransformCtxSetUri",
    1442             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1443             :                     "uri=%s",
    1444           0 :                     xmlSecErrorsSafeString(dsigRefCtx->uri));
    1445           0 :         return(-1);
    1446             :     }
    1447             : 
    1448             :     /* first is optional Transforms node */
    1449           0 :     cur  = xmlSecGetNextElementNode(node->children);
    1450           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeTransforms, xmlSecDSigNs))) {
    1451           0 :         ret = xmlSecTransformCtxNodesListRead(transformCtx, 
    1452             :                                         cur, xmlSecTransformUsageDSigTransform);
    1453           0 :         if(ret < 0) {
    1454           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1455             :                         NULL,
    1456             :                         "xmlSecTransformCtxNodesListRead",
    1457             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1458             :                         "node=%s",
    1459           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
    1460           0 :             return(-1);
    1461             :         }       
    1462             :         
    1463           0 :         cur = xmlSecGetNextElementNode(cur->next);
    1464             :     }
    1465             : 
    1466             :     /* insert membuf if requested */
    1467           0 :     if(((dsigRefCtx->origin == xmlSecDSigReferenceOriginSignedInfo) &&
    1468           0 :         ((dsigRefCtx->dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES) != 0)) ||
    1469           0 :        ((dsigRefCtx->origin == xmlSecDSigReferenceOriginManifest) &&
    1470           0 :         ((dsigRefCtx->dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES) != 0))) {
    1471             : 
    1472           0 :         xmlSecAssert2(dsigRefCtx->preDigestMemBufMethod == NULL, -1);
    1473           0 :         dsigRefCtx->preDigestMemBufMethod = xmlSecTransformCtxCreateAndAppend(
    1474             :                                                 transformCtx, 
    1475             :                                                 xmlSecTransformMemBufId);
    1476           0 :         if(dsigRefCtx->preDigestMemBufMethod == NULL) {
    1477           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1478             :                         NULL,
    1479             :                         "xmlSecTransformCtxCreateAndAppend",
    1480             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1481             :                         "transform=%s",
    1482           0 :                         xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecTransformMemBufId)));
    1483           0 :             return(-1);
    1484             :         }
    1485             :     }
    1486             :         
    1487             :     /* next node is required DigestMethod. */
    1488           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDigestMethod, xmlSecDSigNs))) {
    1489           0 :         dsigRefCtx->digestMethod = xmlSecTransformCtxNodeRead(&(dsigRefCtx->transformCtx), 
    1490             :                                         cur, xmlSecTransformUsageDigestMethod);
    1491           0 :         if(dsigRefCtx->digestMethod == NULL) {
    1492           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1493             :                         NULL,
    1494             :                         "xmlSecTransformCtxNodeRead",
    1495             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1496             :                         "node=%s",
    1497           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
    1498           0 :             return(-1); 
    1499             :         }       
    1500             :         
    1501           0 :         cur = xmlSecGetNextElementNode(cur->next);     
    1502           0 :     } else if(dsigRefCtx->dsigCtx->defSignMethodId != xmlSecTransformIdUnknown) {
    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           0 :         dsigRefCtx->digestMethod = xmlSecTransformCtxCreateAndAppend(&(dsigRefCtx->transformCtx), 
    1507           0 :                                                               dsigRefCtx->dsigCtx->defSignMethodId);
    1508           0 :         if(dsigRefCtx->digestMethod == NULL) {
    1509           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1510             :                         NULL,
    1511             :                         "xmlSecTransformCtxAppend",
    1512             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1513             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1514           0 :             return(-1);
    1515             :         }
    1516             :     } else {
    1517           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1518             :                     NULL,
    1519           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
    1520             :                     XMLSEC_ERRORS_R_INVALID_NODE,
    1521             :                     "expected=%s",
    1522             :                     xmlSecErrorsSafeString(xmlSecNodeDigestMethod));
    1523           0 :         return(-1);
    1524             :     }   
    1525           0 :     dsigRefCtx->digestMethod->operation = dsigRefCtx->dsigCtx->operation;
    1526             : 
    1527             :     /* last node is required DigestValue */
    1528           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDigestValue, xmlSecDSigNs))) {
    1529           0 :         digestValueNode = cur;
    1530           0 :         cur = xmlSecGetNextElementNode(cur->next);     
    1531             :     } else {
    1532           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1533             :                     NULL,
    1534           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
    1535             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1536             :                     "node=%s",
    1537             :                     xmlSecErrorsSafeString(xmlSecNodeDigestValue));
    1538           0 :         return(-1);
    1539             :     }
    1540             : 
    1541             :     /* if we have something else then it's an error */
    1542           0 :     if(cur != NULL) {
    1543           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1544             :                     NULL,
    1545           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
    1546             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
    1547             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1548           0 :         return(-1);
    1549             :     }
    1550             : 
    1551             :     /* if we need to write result to xml node then we need base64 encode result */
    1552           0 :     if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {  
    1553             :         xmlSecTransformPtr base64Encode;
    1554             :         
    1555             :         /* we need to add base64 encode transform */
    1556           0 :         base64Encode = xmlSecTransformCtxCreateAndAppend(transformCtx, xmlSecTransformBase64Id);
    1557           0 :         if(base64Encode == NULL) {
    1558           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1559             :                         NULL,
    1560             :                         "xmlSecTransformCtxCreateAndAppend",
    1561             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1562             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1563           0 :             return(-1);
    1564             :         }
    1565           0 :         base64Encode->operation = xmlSecTransformOperationEncode;
    1566             :     }
    1567             : 
    1568             :     /* finally get transforms results */
    1569           0 :     ret = xmlSecTransformCtxExecute(transformCtx, node->doc);
    1570           0 :     if(ret < 0) {
    1571           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1572             :                     NULL,
    1573             :                     "xmlSecTransformCtxExecute",
    1574             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1575             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1576           0 :         return(-1);
    1577             :     }    
    1578           0 :     dsigRefCtx->result = transformCtx->result;
    1579             : 
    1580           0 :     if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {  
    1581           0 :         if((dsigRefCtx->result == NULL) || (xmlSecBufferGetData(dsigRefCtx->result) == NULL)) {
    1582           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1583             :                         NULL,
    1584             :                         "xmlSecTransformCtxExecute",
    1585             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1586             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1587           0 :             return(-1);
    1588             :         }
    1589             :         
    1590             :         /* write signed data to xml */
    1591           0 :         xmlNodeSetContentLen(digestValueNode,
    1592           0 :                             xmlSecBufferGetData(dsigRefCtx->result),
    1593           0 :                             xmlSecBufferGetSize(dsigRefCtx->result));
    1594             :     
    1595             :         /* set success status and we are done */
    1596           0 :         dsigRefCtx->status = xmlSecDSigStatusSucceeded;
    1597             :     } else {
    1598             :         /* verify SignatureValue node content */
    1599           0 :         ret = xmlSecTransformVerifyNodeContent(dsigRefCtx->digestMethod, 
    1600             :                             digestValueNode, transformCtx);
    1601           0 :         if(ret < 0) {
    1602           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1603             :                         NULL,
    1604             :                         "xmlSecTransformVerifyNodeContent",
    1605             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1606             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1607           0 :             return(-1);
    1608             :         }
    1609             :     
    1610             :         /* set status and we are done */
    1611           0 :         if(dsigRefCtx->digestMethod->status == xmlSecTransformStatusOk) {
    1612           0 :             dsigRefCtx->status = xmlSecDSigStatusSucceeded;
    1613             :         } else {
    1614           0 :             dsigRefCtx->status = xmlSecDSigStatusInvalid;
    1615             :         }
    1616             :     }
    1617             : 
    1618           0 :     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           0 : xmlSecDSigReferenceCtxDebugDump(xmlSecDSigReferenceCtxPtr dsigRefCtx, FILE* output) {
    1630           0 :     xmlSecAssert(dsigRefCtx != NULL);
    1631           0 :     xmlSecAssert(dsigRefCtx->dsigCtx != NULL);
    1632           0 :     xmlSecAssert(output != NULL);
    1633             : 
    1634           0 :     if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {    
    1635           0 :         fprintf(output, "= REFERENCE CALCULATION CONTEXT\n");
    1636             :     } else {
    1637           0 :         fprintf(output, "= REFERENCE VERIFICATION CONTEXT\n");
    1638             :     }
    1639           0 :     switch(dsigRefCtx->status) {
    1640             :         case xmlSecDSigStatusUnknown:
    1641           0 :             fprintf(output, "== Status: unknown\n");
    1642           0 :             break;
    1643             :         case xmlSecDSigStatusSucceeded:
    1644           0 :             fprintf(output, "== Status: succeeded\n");
    1645           0 :             break;
    1646             :         case xmlSecDSigStatusInvalid:
    1647           0 :             fprintf(output, "== Status: invalid\n");
    1648           0 :             break;
    1649             :     }
    1650           0 :     if(dsigRefCtx->id != NULL) {
    1651           0 :         fprintf(output, "== Id: \"%s\"\n", dsigRefCtx->id);
    1652             :     }
    1653           0 :     if(dsigRefCtx->uri != NULL) {
    1654           0 :         fprintf(output, "== URI: \"%s\"\n", dsigRefCtx->uri);
    1655             :     }
    1656           0 :     if(dsigRefCtx->type != NULL) {
    1657           0 :         fprintf(output, "== Type: \"%s\"\n", dsigRefCtx->type);
    1658             :     }
    1659             : 
    1660           0 :     fprintf(output, "== Reference Transform Ctx:\n");
    1661           0 :     xmlSecTransformCtxDebugDump(&(dsigRefCtx->transformCtx), output);
    1662             : 
    1663           0 :     if(dsigRefCtx->digestMethod != NULL) {
    1664           0 :         fprintf(output, "== Digest Method:\n");
    1665           0 :         xmlSecTransformDebugDump(dsigRefCtx->digestMethod, output);
    1666             :     }
    1667             : 
    1668           0 :     if((xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx) != NULL) &&
    1669           0 :        (xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)) != NULL)) {
    1670             :        
    1671           0 :         fprintf(output, "== PreDigest data - start buffer:\n");
    1672           0 :         fwrite(xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), 
    1673             :                xmlSecBufferGetSize(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), 
    1674             :                1, output);
    1675           0 :         fprintf(output, "\n== PreDigest data - end buffer\n");       
    1676             :     }
    1677             : 
    1678           0 :     if((dsigRefCtx->result != NULL) && 
    1679           0 :        (xmlSecBufferGetData(dsigRefCtx->result) != NULL)) {
    1680             : 
    1681           0 :         fprintf(output, "== Result - start buffer:\n");
    1682           0 :         fwrite(xmlSecBufferGetData(dsigRefCtx->result), 
    1683             :                xmlSecBufferGetSize(dsigRefCtx->result), 1,
    1684             :                output);
    1685           0 :         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           0 : xmlSecDSigReferenceCtxDebugXmlDump(xmlSecDSigReferenceCtxPtr dsigRefCtx, FILE* output) {
    1698           0 :     xmlSecAssert(dsigRefCtx != NULL);
    1699           0 :     xmlSecAssert(dsigRefCtx->dsigCtx != NULL);
    1700           0 :     xmlSecAssert(output != NULL);
    1701             : 
    1702           0 :     if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {    
    1703           0 :         fprintf(output, "<ReferenceCalculationContext ");
    1704             :     } else {
    1705           0 :         fprintf(output, "<ReferenceVerificationContext ");
    1706             :     }
    1707           0 :     switch(dsigRefCtx->status) {
    1708             :         case xmlSecDSigStatusUnknown:
    1709           0 :             fprintf(output, "status=\"unknown\" >\n");
    1710           0 :             break;
    1711             :         case xmlSecDSigStatusSucceeded:
    1712           0 :             fprintf(output, "status=\"succeeded\" >\n");
    1713           0 :             break;
    1714             :         case xmlSecDSigStatusInvalid:
    1715           0 :             fprintf(output, "status=\"invalid\" >\n");
    1716           0 :             break;
    1717             :     }
    1718             : 
    1719           0 :     fprintf(output, "<Id>");
    1720           0 :     xmlSecPrintXmlString(output, dsigRefCtx->id);
    1721           0 :     fprintf(output, "</Id>\n");
    1722             : 
    1723           0 :     fprintf(output, "<URI>");
    1724           0 :     xmlSecPrintXmlString(output, dsigRefCtx->uri);
    1725           0 :     fprintf(output, "</URI>\n");
    1726             : 
    1727           0 :     fprintf(output, "<Type>");
    1728           0 :     xmlSecPrintXmlString(output, dsigRefCtx->type);
    1729           0 :     fprintf(output, "</Type>\n");
    1730             : 
    1731           0 :     fprintf(output, "<ReferenceTransformCtx>\n");
    1732           0 :     xmlSecTransformCtxDebugXmlDump(&(dsigRefCtx->transformCtx), output);
    1733           0 :     fprintf(output, "</ReferenceTransformCtx>\n");
    1734             : 
    1735           0 :     if(dsigRefCtx->digestMethod != NULL) {
    1736           0 :         fprintf(output, "<DigestMethod>\n");
    1737           0 :         xmlSecTransformDebugXmlDump(dsigRefCtx->digestMethod, output);
    1738           0 :         fprintf(output, "</DigestMethod>\n");
    1739             :     }
    1740             : 
    1741           0 :     if((dsigRefCtx->result != NULL) && 
    1742           0 :        (xmlSecBufferGetData(dsigRefCtx->result) != NULL)) {
    1743             : 
    1744           0 :         fprintf(output, "<Result>");
    1745           0 :         fwrite(xmlSecBufferGetData(dsigRefCtx->result), 
    1746             :                xmlSecBufferGetSize(dsigRefCtx->result), 1,
    1747             :                output);
    1748           0 :         fprintf(output, "</Result>\n");
    1749             :     }
    1750             : 
    1751           0 :     if((xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx) != NULL) &&
    1752           0 :        (xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)) != NULL)) {
    1753             :        
    1754           0 :         fprintf(output, "<PreDigestData>");
    1755           0 :         fwrite(xmlSecBufferGetData(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), 
    1756             :                xmlSecBufferGetSize(xmlSecDSigReferenceCtxGetPreDigestBuffer(dsigRefCtx)), 
    1757             :                1, output);
    1758           0 :         fprintf(output, "</PreDigestData>\n");       
    1759             :     }
    1760           0 :     if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {    
    1761           0 :         fprintf(output, "</ReferenceCalculationContext>\n");
    1762             :     } else {
    1763           0 :         fprintf(output, "</ReferenceVerificationContext>\n");
    1764             :     }
    1765             : }
    1766             : 
    1767             : 
    1768             : /**************************************************************************
    1769             :  *
    1770             :  * xmlSecDSigReferenceCtxListKlass
    1771             :  *
    1772             :  *************************************************************************/
    1773             : static xmlSecPtrListKlass xmlSecDSigReferenceCtxListKlass = {
    1774             :     BAD_CAST "dsig-reference-list",
    1775             :     NULL,                                                               /* 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           0 : xmlSecDSigReferenceCtxListGetKlass(void) {
    1790           0 :     return(&xmlSecDSigReferenceCtxListKlass);
    1791             : }
    1792             : 
    1793             : #endif /* XMLSEC_NO_XMLDSIG */
    1794             : 
    1795             : 

Generated by: LCOV version 1.10