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

          Line data    Source code
       1             : /** 
       2             :  * XML Security Library (http://www.aleksey.com/xmlsec).
       3             :  *
       4             :  * <dsig:KeyInfo/> element processing 
       5             :  * (http://www.w3.org/TR/xmlSec-core/#sec-KeyInfo:
       6             :  *
       7             :  * The KeyInfo Element
       8             :  *
       9             :  * KeyInfo is an optional element that enables the recipient(s) to obtain 
      10             :  * the key needed to validate the signature.  KeyInfo may contain keys, 
      11             :  * names, certificates and other public key management information, such as 
      12             :  * in-band key distribution or key agreement data. 
      13             :  * 
      14             :  *  Schema Definition:
      15             :  *
      16             :  *  <element name="KeyInfo" type="ds:KeyInfoType"/> 
      17             :  *  <complexType name="KeyInfoType" mixed="true">
      18             :  *    <choice maxOccurs="unbounded"> 
      19             :  *       <element ref="ds:KeyName"/> 
      20             :  *       <element ref="ds:KeyValue"/> 
      21             :  *       <element ref="ds:RetrievalMethod"/> 
      22             :  *       <element ref="ds:X509Data"/> 
      23             :  *       <element ref="ds:PGPData"/> 
      24             :  *       <element ref="ds:SPKIData"/>
      25             :  *       <element ref="ds:MgmtData"/>
      26             :  *       <any processContents="lax" namespace="##other"/>
      27             :  *       <!-- (1,1) elements from (0,unbounded) namespaces -->
      28             :  *    </choice>
      29             :  *    <attribute name="Id" type="ID" use="optional"/>
      30             :  *  </complexType>
      31             :  *    
      32             :  * DTD:
      33             :  *    
      34             :  * <!ELEMENT KeyInfo (#PCDATA|KeyName|KeyValue|RetrievalMethod|
      35             :  *                    X509Data|PGPData|SPKIData|MgmtData %KeyInfo.ANY;)* >      
      36             :  * <!ATTLIST KeyInfo  Id  ID   #IMPLIED >
      37             :  *  
      38             :  *
      39             :  * This is free software; see Copyright file in the source
      40             :  * distribution for preciese wording.
      41             :  * 
      42             :  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
      43             :  */
      44             : #include "globals.h"
      45             : 
      46             : #include <stdlib.h>
      47             : #include <string.h>
      48             :  
      49             : #include <libxml/tree.h>
      50             : 
      51             : #include <xmlsec/xmlsec.h>
      52             : #include <xmlsec/xmltree.h>
      53             : #include <xmlsec/base64.h>
      54             : #include <xmlsec/keys.h>
      55             : #include <xmlsec/keysmngr.h>
      56             : #include <xmlsec/transforms.h>
      57             : #include <xmlsec/xmlenc.h>
      58             : #include <xmlsec/keyinfo.h>
      59             : #include <xmlsec/errors.h>
      60             : 
      61             : 
      62             : /**************************************************************************
      63             :  *
      64             :  * Hi level functions
      65             :  *
      66             :  *************************************************************************/
      67             : /**
      68             :  * xmlSecKeyInfoNodeRead:
      69             :  * @keyInfoNode:        the pointer to <dsig:KeyInfo/> node.
      70             :  * @key:                the pointer to result key object.
      71             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
      72             :  *
      73             :  * Parses the <dsig:KeyInfo/> element @keyInfoNode, extracts the key data
      74             :  * and stores into @key.
      75             :  *
      76             :  * Returns: 0 on success or -1 if an error occurs.
      77             :  */
      78             : int
      79           0 : xmlSecKeyInfoNodeRead(xmlNodePtr keyInfoNode, xmlSecKeyPtr key, xmlSecKeyInfoCtxPtr keyInfoCtx) {
      80             :     const xmlChar* nodeName;
      81             :     const xmlChar* nodeNs;
      82             :     xmlSecKeyDataId dataId;
      83             :     xmlNodePtr cur;
      84             :     int ret;
      85             :     
      86           0 :     xmlSecAssert2(keyInfoNode != NULL, -1);
      87           0 :     xmlSecAssert2(key != NULL, -1);
      88           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
      89           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1);
      90             : 
      91           0 :     for(cur = xmlSecGetNextElementNode(keyInfoNode->children); 
      92           0 :         (cur != NULL) && 
      93           0 :         (((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_DONT_STOP_ON_KEY_FOUND) != 0) || 
      94           0 :          (xmlSecKeyIsValid(key) == 0) || 
      95           0 :          (xmlSecKeyMatch(key, NULL, &(keyInfoCtx->keyReq)) == 0));
      96           0 :         cur = xmlSecGetNextElementNode(cur->next)) {
      97             :     
      98             :         /* find data id */
      99           0 :         nodeName = cur->name;
     100           0 :         nodeNs = xmlSecGetNodeNsHref(cur);
     101             :         
     102             :         /* use global list only if we don't have a local one */
     103           0 :         if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
     104           0 :             dataId = xmlSecKeyDataIdListFindByNode(&(keyInfoCtx->enabledKeyData),
     105             :                             nodeName, nodeNs, xmlSecKeyDataUsageKeyInfoNodeRead);
     106             :         } else {        
     107           0 :             dataId = xmlSecKeyDataIdListFindByNode(xmlSecKeyDataIdsGet(),
     108             :                             nodeName, nodeNs, xmlSecKeyDataUsageKeyInfoNodeRead);
     109             :         }
     110           0 :         if(dataId != xmlSecKeyDataIdUnknown) {
     111             :             /* read data node */
     112           0 :             ret = xmlSecKeyDataXmlRead(dataId, key, cur, keyInfoCtx);
     113           0 :             if(ret < 0) {
     114           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     115           0 :                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
     116             :                             "xmlSecKeyDataXmlRead",
     117             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     118             :                             "node=%s", 
     119           0 :                             xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     120           0 :                 return(-1);
     121             :             }
     122           0 :         } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_UNKNOWN_CHILD) != 0) {
     123             :             /* there is a laxi schema validation but application may
     124             :              * desire to disable unknown nodes*/
     125           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     126             :                         NULL,
     127           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     128             :                         XMLSEC_ERRORS_R_INVALID_NODE,
     129             :                         XMLSEC_ERRORS_NO_MESSAGE);
     130           0 :             return(-1);
     131             :         }
     132             :     }
     133             :     
     134           0 :     return(0);    
     135             : }
     136             : 
     137             : /**
     138             :  * xmlSecKeyInfoNodeWrite:
     139             :  * @keyInfoNode:        the pointer to <dsig:KeyInfo/> node.
     140             :  * @key:                the pointer to key object.
     141             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     142             :  *
     143             :  * Writes the @key into the <dsig:KeyInfo/> element template @keyInfoNode.
     144             :  *
     145             :  * Returns: 0 on success or -1 if an error occurs.
     146             :  */
     147             : int 
     148           0 : xmlSecKeyInfoNodeWrite(xmlNodePtr keyInfoNode, xmlSecKeyPtr key, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     149             :     const xmlChar* nodeName;
     150             :     const xmlChar* nodeNs;
     151             :     xmlSecKeyDataId dataId;
     152             :     xmlNodePtr cur;
     153             :     int ret;
     154             :     
     155           0 :     xmlSecAssert2(keyInfoNode != NULL, -1);
     156           0 :     xmlSecAssert2(key != NULL, -1);
     157           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     158           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeWrite, -1);
     159             : 
     160           0 :     for(cur = xmlSecGetNextElementNode(keyInfoNode->children); 
     161             :         cur != NULL;
     162           0 :         cur = xmlSecGetNextElementNode(cur->next)) {
     163             :     
     164             :         /* find data id */
     165           0 :         nodeName = cur->name;
     166           0 :         nodeNs = xmlSecGetNodeNsHref(cur);
     167             : 
     168             :         /* use global list only if we don't have a local one */
     169           0 :         if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
     170           0 :                 dataId = xmlSecKeyDataIdListFindByNode(&(keyInfoCtx->enabledKeyData),
     171             :                             nodeName, nodeNs, 
     172             :                             xmlSecKeyDataUsageKeyInfoNodeWrite);
     173             :         } else {
     174           0 :                 dataId = xmlSecKeyDataIdListFindByNode(xmlSecKeyDataIdsGet(),
     175             :                             nodeName, nodeNs, 
     176             :                             xmlSecKeyDataUsageKeyInfoNodeWrite);
     177             :         }
     178           0 :         if(dataId != xmlSecKeyDataIdUnknown) {
     179           0 :             ret = xmlSecKeyDataXmlWrite(dataId, key, cur, keyInfoCtx);
     180           0 :             if(ret < 0) {
     181           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     182           0 :                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),
     183             :                             "xmlSecKeyDataXmlWrite",
     184             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     185             :                             "node=%s", 
     186           0 :                             xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     187           0 :                 return(-1);
     188             :             }
     189           0 :         } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_STOP_ON_UNKNOWN_CHILD) != 0) {
     190             :             /* laxi schema validation but application can disable it*/
     191           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     192             :                         NULL,
     193           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     194             :                         XMLSEC_ERRORS_R_INVALID_NODE,
     195             :                         XMLSEC_ERRORS_NO_MESSAGE);
     196           0 :             return(-1);
     197             :         }
     198             :     }
     199             :     
     200           0 :     return(0);
     201             : } 
     202             : 
     203             : /**************************************************************************
     204             :  *
     205             :  * KeyInfo context
     206             :  *
     207             :  *************************************************************************/
     208             : /**
     209             :  * xmlSecKeyInfoCtxCreate:
     210             :  * @keysMngr:           the pointer to keys manager (may be NULL).
     211             :  *
     212             :  * Allocates and initializes <dsig:KeyInfo/> element processing context.
     213             :  * Caller is responsible for freeing it by calling #xmlSecKeyInfoCtxDestroy 
     214             :  * function.
     215             :  *
     216             :  * Returns: pointer to newly allocated object or NULL if an error occurs.
     217             :  */
     218             : xmlSecKeyInfoCtxPtr 
     219           0 : xmlSecKeyInfoCtxCreate(xmlSecKeysMngrPtr keysMngr) {
     220             :     xmlSecKeyInfoCtxPtr keyInfoCtx;
     221             :     int ret;
     222             :     
     223             :     /* Allocate a new xmlSecKeyInfoCtx and fill the fields. */
     224           0 :     keyInfoCtx = (xmlSecKeyInfoCtxPtr)xmlMalloc(sizeof(xmlSecKeyInfoCtx));
     225           0 :     if(keyInfoCtx == NULL) {
     226           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     227             :                     NULL,
     228             :                     NULL,
     229             :                     XMLSEC_ERRORS_R_MALLOC_FAILED,
     230             :                     "size=%d", sizeof(xmlSecKeyInfoCtx)); 
     231           0 :         return(NULL);
     232             :     }
     233             :     
     234           0 :     ret = xmlSecKeyInfoCtxInitialize(keyInfoCtx, keysMngr);
     235           0 :     if(ret < 0) {
     236           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     237             :                     NULL,
     238             :                     "xmlSecKeyInfoCtxInitialize",
     239             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     240             :                     XMLSEC_ERRORS_NO_MESSAGE);
     241           0 :         xmlSecKeyInfoCtxDestroy(keyInfoCtx);
     242           0 :         return(NULL);
     243             :     }
     244             :     
     245           0 :     return(keyInfoCtx);
     246             : }
     247             : 
     248             : /** 
     249             :  * xmlSecKeyInfoCtxDestroy:
     250             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     251             :  *
     252             :  * Destroys @keyInfoCtx object created with #xmlSecKeyInfoCtxCreate function.
     253             :  */
     254             : void 
     255           0 : xmlSecKeyInfoCtxDestroy(xmlSecKeyInfoCtxPtr keyInfoCtx) {
     256           0 :     xmlSecAssert(keyInfoCtx != NULL);
     257             :     
     258           0 :     xmlSecKeyInfoCtxFinalize(keyInfoCtx);
     259           0 :     xmlFree(keyInfoCtx);
     260             : }
     261             : 
     262             : /** 
     263             :  * xmlSecKeyInfoCtxInitialize:
     264             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     265             :  * @keysMngr:           the pointer to keys manager (may be NULL).
     266             :  *
     267             :  * Initializes <dsig:KeyInfo/> element processing context. Caller is 
     268             :  * responsible for cleaning it up by #xmlSecKeyInfoCtxFinalize function.
     269             :  * 
     270             :  * Returns: 0 on success and a negative value if an error occurs.
     271             :  */
     272             : int 
     273           0 : xmlSecKeyInfoCtxInitialize(xmlSecKeyInfoCtxPtr keyInfoCtx, xmlSecKeysMngrPtr keysMngr) {
     274             :     int ret;
     275             :     
     276           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     277             :     
     278           0 :     memset(keyInfoCtx, 0, sizeof(xmlSecKeyInfoCtx));
     279           0 :     keyInfoCtx->keysMngr = keysMngr;
     280           0 :     keyInfoCtx->base64LineSize = xmlSecBase64GetDefaultLineSize();    
     281           0 :     ret = xmlSecPtrListInitialize(&(keyInfoCtx->enabledKeyData), xmlSecKeyDataIdListId);
     282           0 :     if(ret < 0) {
     283           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     284             :                     NULL,
     285             :                     "xmlSecPtrListInitialize",
     286             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     287             :                     XMLSEC_ERRORS_NO_MESSAGE);
     288           0 :         return(-1);
     289             :     }
     290             : 
     291           0 :     keyInfoCtx->maxRetrievalMethodLevel = 1;
     292           0 :     ret = xmlSecTransformCtxInitialize(&(keyInfoCtx->retrievalMethodCtx));
     293           0 :     if(ret < 0) {
     294           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     295             :                     NULL,
     296             :                     "xmlSecTransformCtxInitialize",
     297             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     298             :                     XMLSEC_ERRORS_NO_MESSAGE);
     299           0 :         return(-1);
     300             :     }
     301             : 
     302             : #ifndef XMLSEC_NO_XMLENC
     303           0 :     keyInfoCtx->maxEncryptedKeyLevel = 1;
     304             : #endif /* XMLSEC_NO_XMLENC */
     305             : 
     306             : #ifndef XMLSEC_NO_X509
     307           0 :     keyInfoCtx->certsVerificationDepth= 9;
     308             : #endif /* XMLSEC_NO_X509 */
     309             : 
     310           0 :     ret = xmlSecKeyReqInitialize(&(keyInfoCtx->keyReq));
     311           0 :     if(ret < 0) {
     312           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     313             :                     NULL,
     314             :                     "xmlSecKeyReqInitialize",
     315             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     316             :                     XMLSEC_ERRORS_NO_MESSAGE);
     317           0 :         return(-1);
     318             :     }
     319             :         
     320           0 :     return(0);
     321             : }
     322             : 
     323             : /** 
     324             :  * xmlSecKeyInfoCtxFinalize:
     325             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     326             :  *
     327             :  * Cleans up the @keyInfoCtx initialized with #xmlSecKeyInfoCtxInitialize
     328             :  * function.
     329             :  */
     330             : void 
     331           0 : xmlSecKeyInfoCtxFinalize(xmlSecKeyInfoCtxPtr keyInfoCtx) {
     332           0 :     xmlSecAssert(keyInfoCtx != NULL);
     333             :     
     334           0 :     xmlSecPtrListFinalize(&(keyInfoCtx->enabledKeyData));
     335           0 :     xmlSecTransformCtxFinalize(&(keyInfoCtx->retrievalMethodCtx));
     336           0 :     xmlSecKeyReqFinalize(&(keyInfoCtx->keyReq));
     337             : 
     338             : #ifndef XMLSEC_NO_XMLENC
     339           0 :     if(keyInfoCtx->encCtx != NULL) {
     340           0 :         xmlSecEncCtxDestroy(keyInfoCtx->encCtx);
     341             :     }
     342             : #endif /* XMLSEC_NO_XMLENC */
     343             : 
     344           0 :     memset(keyInfoCtx, 0, sizeof(xmlSecKeyInfoCtx));
     345             : }
     346             : 
     347             : /** 
     348             :  * xmlSecKeyInfoCtxReset:
     349             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     350             :  * 
     351             :  * Resets the @keyInfoCtx state. User settings are not changed.
     352             :  */
     353             : void 
     354           0 : xmlSecKeyInfoCtxReset(xmlSecKeyInfoCtxPtr keyInfoCtx) {
     355           0 :     xmlSecAssert(keyInfoCtx != NULL);
     356             :     
     357           0 :     xmlSecTransformCtxReset(&(keyInfoCtx->retrievalMethodCtx));
     358           0 :     keyInfoCtx->curRetrievalMethodLevel = 0;
     359             : 
     360             : #ifndef XMLSEC_NO_XMLENC
     361           0 :     if(keyInfoCtx->encCtx != NULL) {            
     362           0 :         xmlSecEncCtxReset(keyInfoCtx->encCtx);
     363             :     }
     364           0 :     keyInfoCtx->curEncryptedKeyLevel = 0;
     365             : #endif /* XMLSEC_NO_XMLENC */
     366             :     
     367           0 :     xmlSecKeyReqReset(&(keyInfoCtx->keyReq));
     368             : }
     369             : 
     370             : /** 
     371             :  * xmlSecKeyInfoCtxCreateEncCtx:
     372             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     373             :  * 
     374             :  * Creates encryption context form processing <enc:EncryptedKey/> child
     375             :  * of <dsig:KeyInfo/> element.
     376             :  * 
     377             :  * Returns: 0 on success and a negative value if an error occurs.
     378             :  */
     379             : int 
     380           0 : xmlSecKeyInfoCtxCreateEncCtx(xmlSecKeyInfoCtxPtr keyInfoCtx) {
     381             : #ifndef XMLSEC_NO_XMLENC
     382             :     xmlSecEncCtxPtr tmp;
     383             :     int ret;
     384             :     
     385           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     386           0 :     xmlSecAssert2(keyInfoCtx->encCtx == NULL, -1);
     387             : 
     388             :     /* we have to use tmp variable to avoid a recursive loop */ 
     389           0 :     tmp = xmlSecEncCtxCreate(keyInfoCtx->keysMngr);
     390           0 :     if(tmp == NULL) {
     391           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     392             :                     NULL,
     393             :                     "xmlSecEncCtxCreate",
     394             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     395             :                     XMLSEC_ERRORS_NO_MESSAGE);
     396           0 :         return(-1);
     397             :     }
     398           0 :     tmp->mode = xmlEncCtxModeEncryptedKey;
     399             :         
     400             :     /* copy user preferences from our current ctx */
     401           0 :     switch(keyInfoCtx->mode) {
     402             :         case xmlSecKeyInfoModeRead:
     403           0 :             ret = xmlSecKeyInfoCtxCopyUserPref(&(tmp->keyInfoReadCtx), keyInfoCtx);
     404           0 :             if(ret < 0) {
     405           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     406             :                             NULL,
     407             :                             "xmlSecKeyInfoCtxCopyUserPref",
     408             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     409             :                             XMLSEC_ERRORS_NO_MESSAGE);
     410           0 :                 xmlSecEncCtxDestroy(tmp);
     411           0 :                 return(-1);
     412             :             }    
     413           0 :             break;
     414             :         case xmlSecKeyInfoModeWrite:
     415           0 :             ret = xmlSecKeyInfoCtxCopyUserPref(&(tmp->keyInfoWriteCtx), keyInfoCtx);
     416           0 :             if(ret < 0) {
     417           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     418             :                             NULL,
     419             :                             "xmlSecKeyInfoCtxCopyUserPref",
     420             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     421             :                             XMLSEC_ERRORS_NO_MESSAGE);
     422           0 :                 xmlSecEncCtxDestroy(tmp);
     423           0 :                 return(-1);
     424             :             }
     425           0 :             break;
     426             :     }    
     427           0 :     keyInfoCtx->encCtx = tmp;
     428             :         
     429           0 :     return(0);
     430             : #else /* XMLSEC_NO_XMLENC */    
     431             :     xmlSecError(XMLSEC_ERRORS_HERE,
     432             :                 NULL,
     433             :                 "xml encryption",
     434             :                 XMLSEC_ERRORS_R_DISABLED,
     435             :                 XMLSEC_ERRORS_NO_MESSAGE);
     436             :     return(-1);
     437             : #endif /* XMLSEC_NO_XMLENC */    
     438             : }
     439             : 
     440             : /** 
     441             :  * xmlSecKeyInfoCtxCopyUserPref:
     442             :  * @dst:                the pointer to destination context object.
     443             :  * @src:                the pointer to source context object.
     444             :  *
     445             :  * Copies user preferences from @src context to @dst context.
     446             :  *  
     447             :  * Returns: 0 on success and a negative value if an error occurs.
     448             :  */
     449             : int 
     450           0 : xmlSecKeyInfoCtxCopyUserPref(xmlSecKeyInfoCtxPtr dst, xmlSecKeyInfoCtxPtr src) {
     451             :     int ret;
     452             :     
     453           0 :     xmlSecAssert2(dst != NULL, -1);
     454           0 :     xmlSecAssert2(src != NULL, -1);
     455             :     
     456           0 :     dst->userData    = src->userData;
     457           0 :     dst->flags               = src->flags;
     458           0 :     dst->flags2              = src->flags2;
     459           0 :     dst->keysMngr    = src->keysMngr;
     460           0 :     dst->mode                = src->mode;
     461           0 :     dst->base64LineSize      = src->base64LineSize;
     462             : 
     463           0 :     ret = xmlSecPtrListCopy(&(dst->enabledKeyData), &(src->enabledKeyData));
     464           0 :     if(ret < 0) {
     465           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     466             :                     NULL,
     467             :                     "xmlSecPtrListCopy",
     468             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     469             :                     "enabledKeyData");    
     470           0 :         return(-1);
     471             :     }
     472             :     
     473             :     /* <dsig:RetrievalMethod/> */
     474           0 :     dst->maxRetrievalMethodLevel= src->maxRetrievalMethodLevel;
     475           0 :     ret = xmlSecTransformCtxCopyUserPref(&(dst->retrievalMethodCtx), 
     476           0 :                                          &(src->retrievalMethodCtx));
     477           0 :     if(ret < 0) {
     478           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     479             :                     NULL,
     480             :                     "xmlSecTransformCtxCopyUserPref",
     481             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     482             :                     "enabledKeyData");    
     483           0 :         return(-1);
     484             :     }
     485             : 
     486             :     /* <enc:EncryptedContext /> */    
     487             : #ifndef XMLSEC_NO_XMLENC
     488           0 :     xmlSecAssert2(dst->encCtx == NULL, -1);
     489           0 :     if(src->encCtx != NULL) {                
     490           0 :         dst->encCtx = xmlSecEncCtxCreate(dst->keysMngr);
     491           0 :         if(dst->encCtx == NULL) {
     492           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     493             :                         NULL,
     494             :                         "xmlSecEncCtxCreate",
     495             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     496             :                         XMLSEC_ERRORS_NO_MESSAGE);
     497           0 :             return(-1);
     498             :         }
     499             :         
     500           0 :         dst->encCtx->mode = xmlEncCtxModeEncryptedKey;
     501           0 :         ret = xmlSecEncCtxCopyUserPref(dst->encCtx, src->encCtx);
     502           0 :         if(ret < 0) {
     503           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     504             :                         NULL,
     505             :                         "xmlSecEncCtxCopyUserPref",
     506             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     507             :                         XMLSEC_ERRORS_NO_MESSAGE);
     508           0 :             return(-1);
     509             :         }
     510             :     }
     511           0 :     dst->maxEncryptedKeyLevel        = src->maxEncryptedKeyLevel;
     512             : #endif /* XMLSEC_NO_XMLENC */
     513             : 
     514             :     /* <dsig:X509Data /> */    
     515             : #ifndef XMLSEC_NO_X509
     516           0 :     dst->certsVerificationTime       = src->certsVerificationTime;
     517           0 :     dst->certsVerificationDepth      = src->certsVerificationDepth;
     518             : #endif /* XMLSEC_NO_X509 */
     519             :     
     520           0 :     return(0);
     521             : }
     522             : 
     523             : /** 
     524             :  * xmlSecKeyInfoCtxDebugDump:
     525             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     526             :  * @output:             the output file pointer.
     527             :  *
     528             :  * Prints user settings and current context state to @output.
     529             :  */
     530             : void 
     531           0 : xmlSecKeyInfoCtxDebugDump(xmlSecKeyInfoCtxPtr keyInfoCtx, FILE* output) {
     532           0 :     xmlSecAssert(keyInfoCtx != NULL);
     533           0 :     xmlSecAssert(output != NULL);
     534             : 
     535           0 :     switch(keyInfoCtx->mode) {
     536             :         case xmlSecKeyInfoModeRead:
     537           0 :             fprintf(output, "= KEY INFO READ CONTEXT\n");
     538           0 :             break;
     539             :         case xmlSecKeyInfoModeWrite:
     540           0 :             fprintf(output, "= KEY INFO WRITE CONTEXT\n");
     541           0 :             break;
     542             :     }
     543             :     
     544           0 :     fprintf(output, "== flags: 0x%08x\n", keyInfoCtx->flags);
     545           0 :     fprintf(output, "== flags2: 0x%08x\n", keyInfoCtx->flags2);
     546           0 :     if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
     547           0 :         fprintf(output, "== enabled key data: ");
     548           0 :         xmlSecKeyDataIdListDebugDump(&(keyInfoCtx->enabledKeyData), output);
     549             :     } else {
     550           0 :         fprintf(output, "== enabled key data: all\n");
     551             :     }
     552           0 :     fprintf(output, "== RetrievalMethod level (cur/max): %d/%d\n",
     553             :             keyInfoCtx->curRetrievalMethodLevel, 
     554             :             keyInfoCtx->maxRetrievalMethodLevel);
     555           0 :     xmlSecTransformCtxDebugDump(&(keyInfoCtx->retrievalMethodCtx), output);
     556             :     
     557             : #ifndef XMLSEC_NO_XMLENC
     558           0 :     fprintf(output, "== EncryptedKey level (cur/max): %d/%d\n",
     559             :             keyInfoCtx->curEncryptedKeyLevel, 
     560             :             keyInfoCtx->maxEncryptedKeyLevel);
     561           0 :     if(keyInfoCtx->encCtx != NULL) {
     562           0 :         xmlSecEncCtxDebugDump(keyInfoCtx->encCtx, output);
     563             :     }
     564             : #endif /* XMLSEC_NO_XMLENC */
     565             : 
     566           0 :     xmlSecKeyReqDebugDump(&(keyInfoCtx->keyReq), output);
     567             : }
     568             : 
     569             : /** 
     570             :  * xmlSecKeyInfoCtxDebugXmlDump:
     571             :  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> element processing context.
     572             :  * @output:             the output file pointer.
     573             :  *
     574             :  * Prints user settings and current context state in XML format to @output. 
     575             :  */
     576             : void 
     577           0 : xmlSecKeyInfoCtxDebugXmlDump(xmlSecKeyInfoCtxPtr keyInfoCtx, FILE* output) {
     578           0 :     xmlSecAssert(keyInfoCtx != NULL);
     579           0 :     xmlSecAssert(output != NULL);
     580             : 
     581           0 :     switch(keyInfoCtx->mode) {
     582             :         case xmlSecKeyInfoModeRead:
     583           0 :             fprintf(output, "<KeyInfoReadContext>\n");
     584           0 :             break;
     585             :         case xmlSecKeyInfoModeWrite:
     586           0 :             fprintf(output, "<KeyInfoWriteContext>\n");
     587           0 :             break;
     588             :     }
     589             :             
     590           0 :     fprintf(output, "<Flags>%08x</Flags>\n", keyInfoCtx->flags);
     591           0 :     fprintf(output, "<Flags2>%08x</Flags2>\n", keyInfoCtx->flags2);
     592           0 :     if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
     593           0 :         fprintf(output, "<EnabledKeyData>\n");
     594           0 :         xmlSecKeyDataIdListDebugXmlDump(&(keyInfoCtx->enabledKeyData), output);
     595           0 :         fprintf(output, "</EnabledKeyData>\n");
     596             :     } else {
     597           0 :         fprintf(output, "<EnabledKeyData>all</EnabledKeyData>\n");
     598             :     }
     599             : 
     600           0 :     fprintf(output, "<RetrievalMethodLevel cur=\"%d\" max=\"%d\" />\n",
     601             :             keyInfoCtx->curRetrievalMethodLevel, 
     602             :             keyInfoCtx->maxRetrievalMethodLevel);
     603           0 :     xmlSecTransformCtxDebugXmlDump(&(keyInfoCtx->retrievalMethodCtx), output);
     604             : 
     605             : #ifndef XMLSEC_NO_XMLENC
     606           0 :     fprintf(output, "<EncryptedKeyLevel cur=\"%d\" max=\"%d\" />\n",
     607             :             keyInfoCtx->curEncryptedKeyLevel, 
     608             :             keyInfoCtx->maxEncryptedKeyLevel);
     609           0 :     if(keyInfoCtx->encCtx != NULL) {
     610           0 :         xmlSecEncCtxDebugXmlDump(keyInfoCtx->encCtx, output);
     611             :     }
     612             : #endif /* XMLSEC_NO_XMLENC */
     613             :     
     614           0 :     xmlSecKeyReqDebugXmlDump(&(keyInfoCtx->keyReq), output);
     615           0 :     switch(keyInfoCtx->mode) {
     616             :         case xmlSecKeyInfoModeRead:
     617           0 :             fprintf(output, "</KeyInfoReadContext>\n");
     618           0 :             break;
     619             :         case xmlSecKeyInfoModeWrite:
     620           0 :             fprintf(output, "</KeyInfoWriteContext>\n");
     621           0 :             break;
     622             :     }
     623             : }
     624             : 
     625             : /**************************************************************************
     626             :  *
     627             :  * <dsig:KeyName/> processing
     628             :  *
     629             :  *************************************************************************/
     630             : static int                      xmlSecKeyDataNameXmlRead        (xmlSecKeyDataId id,
     631             :                                                                  xmlSecKeyPtr key,
     632             :                                                                  xmlNodePtr node,
     633             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
     634             : static int                      xmlSecKeyDataNameXmlWrite       (xmlSecKeyDataId id,
     635             :                                                                  xmlSecKeyPtr key,
     636             :                                                                  xmlNodePtr node,
     637             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
     638             : 
     639             : static xmlSecKeyDataKlass xmlSecKeyDataNameKlass = {
     640             :     sizeof(xmlSecKeyDataKlass),
     641             :     sizeof(xmlSecKeyData),
     642             : 
     643             :     /* data */
     644             :     xmlSecNameKeyName,
     645             :     xmlSecKeyDataUsageKeyInfoNode,              /* xmlSecKeyDataUsage usage; */
     646             :     NULL,                                       /* const xmlChar* href; */
     647             :     xmlSecNodeKeyName,                          /* const xmlChar* dataNodeName; */
     648             :     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
     649             :     
     650             :     /* constructors/destructor */
     651             :     NULL,                                       /* xmlSecKeyDataInitializeMethod initialize; */
     652             :     NULL,                                       /* xmlSecKeyDataDuplicateMethod duplicate; */
     653             :     NULL,                                       /* xmlSecKeyDataFinalizeMethod finalize; */
     654             :     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
     655             :     
     656             :     /* get info */
     657             :     NULL,                                       /* xmlSecKeyDataGetTypeMethod getType; */
     658             :     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
     659             :     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */    
     660             : 
     661             :     /* read/write */
     662             :     xmlSecKeyDataNameXmlRead,                   /* xmlSecKeyDataXmlReadMethod xmlRead; */
     663             :     xmlSecKeyDataNameXmlWrite,                  /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
     664             :     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
     665             :     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
     666             : 
     667             :     /* debug */
     668             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugDump; */
     669             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
     670             : 
     671             :     /* reserved for the future */
     672             :     NULL,                                       /* void* reserved0; */
     673             :     NULL,                                       /* void* reserved1; */
     674             : };
     675             : 
     676             : /** 
     677             :  * xmlSecKeyDataNameGetKlass:
     678             :  *
     679             :  * The <dsig:KeyName/> element key data klass 
     680             :  * (http://www.w3.org/TR/xmldsig-core/#sec-KeyName):
     681             :  *
     682             :  * The KeyName element contains a string value (in which white space is 
     683             :  * significant) which may be used by the signer to communicate a key 
     684             :  * identifier to the recipient. Typically, KeyName contains an identifier 
     685             :  * related to the key pair used to sign the message, but it may contain 
     686             :  * other protocol-related information that indirectly identifies a key pair. 
     687             :  * (Common uses of KeyName include simple string names for keys, a key index, 
     688             :  * a distinguished name (DN), an email address, etc.) 
     689             :  *
     690             :  * Returns: the <dsig:KeyName/> element processing key data klass.
     691             :  */
     692             : xmlSecKeyDataId 
     693           0 : xmlSecKeyDataNameGetKlass(void) {
     694           0 :     return(&xmlSecKeyDataNameKlass);
     695             : }
     696             : 
     697             : static int 
     698           0 : xmlSecKeyDataNameXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     699             :     const xmlChar* oldName;
     700             :     xmlChar* newName;
     701             :     int ret;
     702             : 
     703           0 :     xmlSecAssert2(id == xmlSecKeyDataNameId, -1);
     704           0 :     xmlSecAssert2(key != NULL, -1);
     705           0 :     xmlSecAssert2(node != NULL, -1);
     706           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     707           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1);
     708             : 
     709           0 :     oldName = xmlSecKeyGetName(key);
     710           0 :     newName = xmlNodeGetContent(node);
     711           0 :     if(newName == NULL) {
     712           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     713           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     714           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
     715             :                     XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
     716             :                     XMLSEC_ERRORS_NO_MESSAGE);
     717           0 :         return(-1);
     718             :     }
     719             :     /* TODO: do we need to decode the name? */
     720             :     
     721             :     /* compare name values */
     722           0 :     if((oldName != NULL) && !xmlStrEqual(oldName, newName)) {
     723           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     724           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     725             :                     "key name is already specified",
     726             :                     XMLSEC_ERRORS_R_INVALID_KEY_DATA,
     727             :                     XMLSEC_ERRORS_NO_MESSAGE);
     728           0 :         xmlFree(newName);
     729           0 :         return(-1);
     730             :     }
     731             : 
     732             :     /* try to find key in the manager */
     733           0 :     if((xmlSecKeyGetValue(key) == NULL) && (keyInfoCtx->keysMngr != NULL)) {
     734             :         xmlSecKeyPtr tmpKey;
     735             : 
     736           0 :         tmpKey = xmlSecKeysMngrFindKey(keyInfoCtx->keysMngr, newName, keyInfoCtx);
     737           0 :         if(tmpKey != NULL) {
     738             :             /* erase any current information in the key */
     739           0 :             xmlSecKeyEmpty(key);
     740             : 
     741             :             /* TODO: since we will destroy tmpKey anyway, we can easily
     742             :              * just re-assign key data values. It'll save use some memory
     743             :              * malloc/free 
     744             :              */
     745             :              
     746             :             /* and copy what we've found */
     747           0 :             ret = xmlSecKeyCopy(key, tmpKey);
     748           0 :             if(ret < 0) {
     749           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     750           0 :                             xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     751             :                             "xmlSecKeyCopy",
     752             :                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     753             :                             XMLSEC_ERRORS_NO_MESSAGE); 
     754           0 :                 xmlSecKeyDestroy(tmpKey);
     755           0 :                 xmlFree(newName);
     756           0 :                 return(-1);
     757             :             }
     758           0 :             xmlSecKeyDestroy(tmpKey);
     759             :         }
     760             :     }           
     761             :     
     762             :     /* finally set key name if it is not there */
     763           0 :     if(xmlSecKeyGetName(key) == NULL) {
     764           0 :         xmlSecKeySetName(key, newName);
     765             :     }
     766           0 :     xmlFree(newName);
     767           0 :     return(0);
     768             : }
     769             : 
     770             : static int 
     771           0 : xmlSecKeyDataNameXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     772             :     const xmlChar* name;
     773             : 
     774           0 :     xmlSecAssert2(id == xmlSecKeyDataNameId, -1);
     775           0 :     xmlSecAssert2(key != NULL, -1);
     776           0 :     xmlSecAssert2(node != NULL, -1);
     777           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     778           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeWrite, -1);
     779             : 
     780           0 :     name = xmlSecKeyGetName(key);
     781           0 :     if(name != NULL) {
     782           0 :             xmlSecNodeEncodeAndSetContent(node, name);
     783             :     }
     784           0 :     return(0);
     785             : }
     786             : 
     787             : /**************************************************************************
     788             :  *
     789             :  * <dsig:KeyValue/> processing
     790             :  *
     791             :  *************************************************************************/
     792             : static int                      xmlSecKeyDataValueXmlRead       (xmlSecKeyDataId id,
     793             :                                                                  xmlSecKeyPtr key,
     794             :                                                                  xmlNodePtr node,
     795             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
     796             : static int                      xmlSecKeyDataValueXmlWrite      (xmlSecKeyDataId id,
     797             :                                                                  xmlSecKeyPtr key,
     798             :                                                                  xmlNodePtr node,
     799             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
     800             : 
     801             : static xmlSecKeyDataKlass xmlSecKeyDataValueKlass = {
     802             :     sizeof(xmlSecKeyDataKlass),
     803             :     sizeof(xmlSecKeyData),
     804             : 
     805             :     /* data */
     806             :     xmlSecNameKeyValue,
     807             :     xmlSecKeyDataUsageKeyInfoNode,              /* xmlSecKeyDataUsage usage; */
     808             :     NULL,                                       /* const xmlChar* href; */
     809             :     xmlSecNodeKeyValue,                         /* const xmlChar* dataNodeName; */
     810             :     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
     811             :     
     812             :     /* constructors/destructor */
     813             :     NULL,                                       /* xmlSecKeyDataInitializeMethod initialize; */
     814             :     NULL,                                       /* xmlSecKeyDataDuplicateMethod duplicate; */
     815             :     NULL,                                       /* xmlSecKeyDataFinalizeMethod finalize; */
     816             :     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
     817             :     
     818             :     /* get info */
     819             :     NULL,                                       /* xmlSecKeyDataGetTypeMethod getType; */
     820             :     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
     821             :     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */    
     822             : 
     823             :     /* read/write */
     824             :     xmlSecKeyDataValueXmlRead,                  /* xmlSecKeyDataXmlReadMethod xmlRead; */
     825             :     xmlSecKeyDataValueXmlWrite,                 /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
     826             :     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
     827             :     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
     828             : 
     829             :     /* debug */
     830             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugDump; */
     831             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
     832             : 
     833             :     /* reserved for the future */
     834             :     NULL,                                       /* void* reserved0; */
     835             :     NULL,                                       /* void* reserved1; */
     836             : };
     837             : 
     838             : /** 
     839             :  * xmlSecKeyDataValueGetKlass:
     840             :  *
     841             :  * The <dsig:KeyValue/> element key data klass 
     842             :  * (http://www.w3.org/TR/xmldsig-core/#sec-KeyValue):
     843             :  *
     844             :  * The KeyValue element contains a single public key that may be useful in 
     845             :  * validating the signature. 
     846             :  * 
     847             :  * Returns: the <dsig:KeyValue/> element processing key data klass.
     848             :  */
     849             : xmlSecKeyDataId 
     850           0 : xmlSecKeyDataValueGetKlass(void) {
     851           0 :     return(&xmlSecKeyDataValueKlass);
     852             : }
     853             : 
     854             : static int 
     855           0 : xmlSecKeyDataValueXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     856             :     const xmlChar* nodeName;
     857             :     const xmlChar* nodeNs;
     858             :     xmlSecKeyDataId dataId;
     859             :     xmlNodePtr cur;
     860             :     int ret;
     861             : 
     862           0 :     xmlSecAssert2(id == xmlSecKeyDataValueId, -1);
     863           0 :     xmlSecAssert2(key != NULL, -1);
     864           0 :     xmlSecAssert2(node != NULL, -1);
     865           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     866           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1);
     867             : 
     868           0 :     cur = xmlSecGetNextElementNode(node->children);
     869           0 :     if(cur == NULL) {
     870             :         /* just an empty node */
     871           0 :         return(0);
     872             :     }
     873             : 
     874             :     /* find data id */
     875           0 :     nodeName = cur->name;
     876           0 :     nodeNs = xmlSecGetNodeNsHref(cur);
     877             : 
     878             :     /* use global list only if we don't have a local one */
     879           0 :     if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
     880           0 :         dataId = xmlSecKeyDataIdListFindByNode(&(keyInfoCtx->enabledKeyData),
     881             :                             nodeName, nodeNs, xmlSecKeyDataUsageKeyValueNodeRead);
     882             :     } else {    
     883           0 :         dataId = xmlSecKeyDataIdListFindByNode(xmlSecKeyDataIdsGet(),
     884             :                             nodeName, nodeNs, xmlSecKeyDataUsageKeyValueNodeRead);
     885             :     }
     886           0 :     if(dataId != xmlSecKeyDataIdUnknown) {
     887             :         /* read data node */
     888           0 :         ret = xmlSecKeyDataXmlRead(dataId, key, cur, keyInfoCtx);
     889           0 :         if(ret < 0) {
     890           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     891           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     892             :                         "xmlSecKeyDataXmlRead",
     893             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     894             :                         "node=%s",
     895           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     896           0 :             return(-1);
     897             :         }
     898           0 :     } else if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_KEYVALUE_STOP_ON_UNKNOWN_CHILD) != 0) {
     899             :         /* laxi schema validation but application can disable it */
     900           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     901           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     902           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     903             :                     XMLSEC_ERRORS_R_INVALID_NODE,
     904             :                     XMLSEC_ERRORS_NO_MESSAGE);
     905           0 :         return(-1);     
     906             :     }
     907             : 
     908             :     /* <dsig:KeyValue/> might have only one node */
     909           0 :     cur = xmlSecGetNextElementNode(cur->next);  
     910           0 :     if(cur != NULL) {
     911           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     912           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     913           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
     914             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
     915             :                     XMLSEC_ERRORS_NO_MESSAGE);
     916           0 :         return(-1);
     917             :     }
     918             :     
     919           0 :     return(0);
     920             : }
     921             : 
     922             : static int 
     923           0 : xmlSecKeyDataValueXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
     924             :     const xmlChar* nodeName;
     925             :     const xmlChar* nodeNs;  
     926             :     xmlNodePtr cur;
     927             :     int ret;
     928             :     
     929           0 :     xmlSecAssert2(id == xmlSecKeyDataValueId, -1);
     930           0 :     xmlSecAssert2(key != NULL, -1);
     931           0 :     xmlSecAssert2(node != NULL, -1);
     932           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
     933           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeWrite, -1);
     934             : 
     935           0 :     if(!xmlSecKeyDataIsValid(key->value) || 
     936           0 :        !xmlSecKeyDataCheckUsage(key->value, xmlSecKeyDataUsageKeyValueNodeWrite)){
     937             :         /* nothing to write */
     938           0 :         return(0);
     939             :     }
     940           0 :     if((xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) && 
     941           0 :         (xmlSecKeyDataIdListFind(&(keyInfoCtx->enabledKeyData), id) != 1)) {
     942             : 
     943             :         /* we are not enabled to write out key data with this id */
     944           0 :         return(0);
     945             :     }
     946           0 :     if(xmlSecKeyReqMatchKey(&(keyInfoCtx->keyReq), key) != 1) {
     947             :         /* we are not allowed to write out this key */
     948           0 :         return(0);
     949             :     }
     950             : 
     951           0 :     nodeName = key->value->id->dataNodeName;
     952           0 :     nodeNs = key->value->id->dataNodeNs;
     953           0 :     xmlSecAssert2(nodeName != NULL, -1);
     954             :     
     955             :     /* remove all existing key value */
     956           0 :     xmlNodeSetContent(node, NULL);
     957             :     
     958             :     /* create key node */
     959           0 :     cur = xmlSecAddChild(node, nodeName, nodeNs);
     960           0 :     if(cur == NULL) {
     961           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     962           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     963             :                     "xmlSecAddChild",
     964             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     965             :                     "node=%s",
     966           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
     967           0 :         return(-1);     
     968             :     }
     969             : 
     970           0 :     ret = xmlSecKeyDataXmlWrite(key->value->id, key, cur, keyInfoCtx);
     971           0 :     if(ret < 0) {
     972           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     973           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
     974             :                     "xmlSecKeyDataXmlWrite",
     975             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
     976             :                     "node=%s",
     977           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
     978           0 :         return(-1);     
     979             :     }
     980             : 
     981           0 :     return(0);
     982             : }
     983             : 
     984             : /**************************************************************************
     985             :  *
     986             :  * <dsig:RetrievalMethod/> processing
     987             :  *
     988             :  *************************************************************************/
     989             : static int                      xmlSecKeyDataRetrievalMethodXmlRead(xmlSecKeyDataId id,
     990             :                                                                  xmlSecKeyPtr key,
     991             :                                                                  xmlNodePtr node,
     992             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
     993             : static int                      xmlSecKeyDataRetrievalMethodXmlWrite(xmlSecKeyDataId id,
     994             :                                                                  xmlSecKeyPtr key,
     995             :                                                                  xmlNodePtr node,
     996             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
     997             : 
     998             : 
     999             : 
    1000             : static xmlSecKeyDataKlass xmlSecKeyDataRetrievalMethodKlass = {
    1001             :     sizeof(xmlSecKeyDataKlass),
    1002             :     sizeof(xmlSecKeyData),
    1003             : 
    1004             :     /* data */
    1005             :     xmlSecNameRetrievalMethod,
    1006             :     xmlSecKeyDataUsageKeyInfoNode,              /* xmlSecKeyDataUsage usage; */
    1007             :     NULL,                                       /* const xmlChar* href; */
    1008             :     xmlSecNodeRetrievalMethod,                  /* const xmlChar* dataNodeName; */
    1009             :     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
    1010             :     
    1011             :     /* constructors/destructor */
    1012             :     NULL,                                       /* xmlSecKeyDataInitializeMethod initialize; */
    1013             :     NULL,                                       /* xmlSecKeyDataDuplicateMethod duplicate; */
    1014             :     NULL,                                       /* xmlSecKeyDataFinalizeMethod finalize; */
    1015             :     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
    1016             :     
    1017             :     /* get info */
    1018             :     NULL,                                       /* xmlSecKeyDataGetTypeMethod getType; */
    1019             :     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
    1020             :     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */    
    1021             : 
    1022             :     /* read/write */
    1023             :     xmlSecKeyDataRetrievalMethodXmlRead,        /* xmlSecKeyDataXmlReadMethod xmlRead; */
    1024             :     xmlSecKeyDataRetrievalMethodXmlWrite,       /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
    1025             :     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
    1026             :     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
    1027             : 
    1028             :     /* debug */
    1029             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugDump; */
    1030             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
    1031             : 
    1032             :     /* reserved for the future */
    1033             :     NULL,                                       /* void* reserved0; */
    1034             :     NULL,                                       /* void* reserved1; */
    1035             : };
    1036             : 
    1037             : static int                      xmlSecKeyDataRetrievalMethodReadXmlResult(xmlSecKeyDataId typeId,
    1038             :                                                                  xmlSecKeyPtr key,
    1039             :                                                                  const xmlChar* buffer,
    1040             :                                                                  xmlSecSize bufferSize,
    1041             :                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
    1042             : 
    1043             : /** 
    1044             :  * xmlSecKeyDataRetrievalMethodGetKlass:
    1045             :  *
    1046             :  * The <dsig:RetrievalMethod/> element key data klass 
    1047             :  * (http://www.w3.org/TR/xmldsig-core/#sec-RetrievalMethod):
    1048             :  * A RetrievalMethod element within KeyInfo is used to convey a reference to 
    1049             :  * KeyInfo information that is stored at another location. For example, 
    1050             :  * several signatures in a document might use a key verified by an X.509v3 
    1051             :  * certificate chain appearing once in the document or remotely outside the 
    1052             :  * document; each signature's KeyInfo can reference this chain using a single 
    1053             :  * RetrievalMethod element instead of including the entire chain with a 
    1054             :  * sequence of X509Certificate elements.
    1055             :  *
    1056             :  * RetrievalMethod uses the same syntax and dereferencing behavior as 
    1057             :  * Reference's URI and The Reference Processing Model.
    1058             :  * 
    1059             :  * Returns: the <dsig:RetrievalMethod/> element processing key data klass.
    1060             :  */
    1061             : xmlSecKeyDataId 
    1062           0 : xmlSecKeyDataRetrievalMethodGetKlass(void) {
    1063           0 :     return(&xmlSecKeyDataRetrievalMethodKlass);
    1064             : }
    1065             : 
    1066             : static int 
    1067           0 : xmlSecKeyDataRetrievalMethodXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
    1068           0 :     xmlSecKeyDataId dataId = xmlSecKeyDataIdUnknown;
    1069           0 :     xmlChar *retrType = NULL;
    1070           0 :     xmlChar *uri = NULL;
    1071             :     xmlNodePtr cur;
    1072           0 :     int res = -1;
    1073             :     int ret;
    1074             :     
    1075           0 :     xmlSecAssert2(id == xmlSecKeyDataRetrievalMethodId, -1);
    1076           0 :     xmlSecAssert2(key != NULL, -1);
    1077           0 :     xmlSecAssert2(node != NULL, -1);
    1078           0 :     xmlSecAssert2(node->doc != NULL, -1);
    1079           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
    1080           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1);
    1081             : 
    1082             :     /* check retrieval level */
    1083           0 :     if(keyInfoCtx->curRetrievalMethodLevel >= keyInfoCtx->maxRetrievalMethodLevel) {
    1084           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1085           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1086             :                     NULL,
    1087             :                     XMLSEC_ERRORS_R_MAX_RETRIEVALS_LEVEL,
    1088             :                     "cur=%d;max=%d", 
    1089             :                     keyInfoCtx->curRetrievalMethodLevel,
    1090             :                     keyInfoCtx->maxRetrievalMethodLevel);
    1091           0 :         goto done;
    1092             :     }
    1093           0 :     ++keyInfoCtx->curRetrievalMethodLevel;
    1094             : 
    1095           0 :     retrType = xmlGetProp(node, xmlSecAttrType);
    1096           0 :     if(retrType != NULL) {
    1097             :         /* use global list only if we don't have a local one */
    1098           0 :         if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
    1099           0 :             dataId = xmlSecKeyDataIdListFindByHref(&(keyInfoCtx->enabledKeyData),
    1100             :                             retrType, xmlSecKeyDataUsageRetrievalMethodNode);
    1101             :         } else {        
    1102           0 :             dataId = xmlSecKeyDataIdListFindByHref(xmlSecKeyDataIdsGet(),
    1103             :                             retrType, xmlSecKeyDataUsageRetrievalMethodNode);
    1104             :         }
    1105             :     }
    1106             : 
    1107             :     /* laxi schema validation but aplication can disable it */
    1108           0 :     if(dataId == xmlSecKeyDataIdUnknown) {
    1109           0 :         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_RETRMETHOD_STOP_ON_UNKNOWN_HREF) != 0) {
    1110           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1111           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1112             :                         xmlSecErrorsSafeString(xmlSecAttrType),
    1113             :                         XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
    1114             :                         "value=%s", xmlSecErrorsSafeString(retrType));
    1115             :         } else {
    1116           0 :             res = 0;
    1117             :         }
    1118           0 :         goto done;
    1119             :     }
    1120             : 
    1121             :     /* destroy prev retrieval method context */
    1122           0 :     xmlSecTransformCtxReset(&(keyInfoCtx->retrievalMethodCtx));
    1123             : 
    1124             :     /* set start URI and check that it is enabled */
    1125           0 :     uri = xmlGetProp(node, xmlSecAttrURI);
    1126           0 :     ret = xmlSecTransformCtxSetUri(&(keyInfoCtx->retrievalMethodCtx), uri, node);
    1127           0 :     if(ret < 0) {
    1128           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1129           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1130             :                     "xmlSecTransformCtxSetUri",
    1131             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1132             :                     "uri=%s",
    1133             :                     xmlSecErrorsSafeString(uri));
    1134           0 :         goto done;
    1135             :     }
    1136             : 
    1137             :     /* the only one node is optional Transforms node */
    1138           0 :     cur = xmlSecGetNextElementNode(node->children);
    1139           0 :     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeTransforms, xmlSecDSigNs))) {
    1140           0 :         ret = xmlSecTransformCtxNodesListRead(&(keyInfoCtx->retrievalMethodCtx), 
    1141             :                                             cur, xmlSecTransformUsageDSigTransform);
    1142           0 :         if(ret < 0) {
    1143           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1144           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1145             :                         "xmlSecTransformCtxNodesListRead",
    1146             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1147             :                         "node=%s",
    1148           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
    1149           0 :             goto done;
    1150             :         }       
    1151           0 :         cur = xmlSecGetNextElementNode(cur->next);
    1152             :     }
    1153             : 
    1154           0 :     if(cur != NULL) {
    1155           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1156           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1157           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
    1158             :                     XMLSEC_ERRORS_R_UNEXPECTED_NODE,
    1159             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1160           0 :         goto done;
    1161             :     }
    1162             : 
    1163             :     /* finally get transforms results */
    1164           0 :     ret = xmlSecTransformCtxExecute(&(keyInfoCtx->retrievalMethodCtx), node->doc);
    1165           0 :     if((ret < 0) || 
    1166           0 :        (keyInfoCtx->retrievalMethodCtx.result == NULL) ||
    1167           0 :        (xmlSecBufferGetData(keyInfoCtx->retrievalMethodCtx.result) == NULL)) {
    1168             : 
    1169           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1170           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1171             :                     "xmlSecTransformCtxExecute",
    1172             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1173             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1174           0 :         goto done;
    1175             :     }
    1176             : 
    1177             : 
    1178             :     /* assume that the data is in XML if we could not find id */    
    1179           0 :     if((dataId == xmlSecKeyDataIdUnknown) || 
    1180           0 :        ((dataId->usage & xmlSecKeyDataUsageRetrievalMethodNodeXml) != 0)) {
    1181             : 
    1182           0 :         ret = xmlSecKeyDataRetrievalMethodReadXmlResult(dataId, key,
    1183           0 :                     xmlSecBufferGetData(keyInfoCtx->retrievalMethodCtx.result),
    1184             :                     xmlSecBufferGetSize(keyInfoCtx->retrievalMethodCtx.result),
    1185             :                     keyInfoCtx);
    1186           0 :         if(ret < 0) {
    1187           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1188           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1189             :                         "xmlSecKeyDataRetrievalMethodReadXmlResult",
    1190             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1191             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1192           0 :             goto done;
    1193             :         }    
    1194             :     } else {
    1195           0 :         ret = xmlSecKeyDataBinRead(dataId, key, 
    1196           0 :                     xmlSecBufferGetData(keyInfoCtx->retrievalMethodCtx.result),
    1197             :                     xmlSecBufferGetSize(keyInfoCtx->retrievalMethodCtx.result),
    1198             :                     keyInfoCtx);
    1199           0 :         if(ret < 0) {
    1200           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1201           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1202             :                         "xmlSecKeyDataBinRead",
    1203             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1204             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1205           0 :             goto done;
    1206             :         }    
    1207             :     }
    1208           0 :     --keyInfoCtx->curRetrievalMethodLevel;
    1209             :     
    1210           0 :     res = 0;    
    1211             : done:
    1212           0 :     if(uri != NULL) {
    1213           0 :         xmlFree(uri);
    1214             :     }
    1215           0 :     if(retrType != NULL) {
    1216           0 :         xmlFree(retrType);
    1217             :     }
    1218           0 :     return(res);
    1219             : }
    1220             : 
    1221             : static int 
    1222           0 : xmlSecKeyDataRetrievalMethodXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
    1223           0 :     xmlSecAssert2(id == xmlSecKeyDataRetrievalMethodId, -1);
    1224           0 :     xmlSecAssert2(key != NULL, -1);
    1225           0 :     xmlSecAssert2(node != NULL, -1);
    1226           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
    1227           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeWrite, -1);
    1228             : 
    1229             :     /* just do nothing */
    1230           0 :     return(0);
    1231             : }
    1232             : 
    1233             : static int
    1234           0 : xmlSecKeyDataRetrievalMethodReadXmlResult(xmlSecKeyDataId typeId, xmlSecKeyPtr key,
    1235             :                                           const xmlChar* buffer, xmlSecSize bufferSize,
    1236             :                                           xmlSecKeyInfoCtxPtr keyInfoCtx) {
    1237             :     xmlDocPtr doc;
    1238             :     xmlNodePtr cur;
    1239             :     const xmlChar* nodeName;
    1240             :     const xmlChar* nodeNs;
    1241             :     xmlSecKeyDataId dataId;
    1242             :     int ret;
    1243             :     
    1244           0 :     xmlSecAssert2(key != NULL, -1);
    1245           0 :     xmlSecAssert2(buffer != NULL, -1);
    1246           0 :     xmlSecAssert2(bufferSize > 0, -1); 
    1247           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
    1248           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1);
    1249             : 
    1250           0 :     doc = xmlRecoverMemory((const char*)buffer, bufferSize);
    1251           0 :     if(doc == NULL) {
    1252           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1253           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(typeId)),
    1254             :                     "xmlRecoverMemory",
    1255             :                     XMLSEC_ERRORS_R_XML_FAILED,
    1256             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1257           0 :         return(-1);
    1258             :     }
    1259             :         
    1260           0 :     cur = xmlDocGetRootElement(doc);
    1261           0 :     if(cur == NULL) {
    1262           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1263           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(typeId)),
    1264             :                     "xmlDocGetRootElement",
    1265             :                     XMLSEC_ERRORS_R_XML_FAILED,
    1266             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1267           0 :         xmlFreeDoc(doc);
    1268           0 :         return(-1);     
    1269             :     }
    1270             : 
    1271           0 :     nodeName = cur->name;
    1272           0 :     nodeNs = xmlSecGetNodeNsHref(cur);
    1273             : 
    1274             :     /* use global list only if we don't have a local one */
    1275           0 :     if(xmlSecPtrListGetSize(&(keyInfoCtx->enabledKeyData)) > 0) {
    1276           0 :         dataId = xmlSecKeyDataIdListFindByNode(&(keyInfoCtx->enabledKeyData),
    1277             :                             nodeName, nodeNs, xmlSecKeyDataUsageRetrievalMethodNodeXml);
    1278             :     } else {    
    1279           0 :         dataId = xmlSecKeyDataIdListFindByNode(xmlSecKeyDataIdsGet(),
    1280             :                             nodeName, nodeNs, xmlSecKeyDataUsageRetrievalMethodNodeXml);
    1281             :     }
    1282           0 :     if(dataId == xmlSecKeyDataIdUnknown) {
    1283           0 :         xmlFreeDoc(doc);
    1284             : 
    1285             :         /* laxi schema validation but application can disable it */
    1286           0 :         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_KEYVALUE_STOP_ON_UNKNOWN_CHILD) != 0) {
    1287           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1288           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(typeId)),
    1289           0 :                         xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
    1290             :                         XMLSEC_ERRORS_R_INVALID_NODE,
    1291             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1292           0 :             return(-1);
    1293             :         }
    1294           0 :         return(0);
    1295           0 :     } else if((typeId != xmlSecKeyDataIdUnknown) && (typeId != dataId) &&
    1296           0 :               ((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_RETRMETHOD_STOP_ON_MISMATCH_HREF) != 0)) {
    1297             :         
    1298           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1299           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(typeId)),
    1300           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)),              
    1301             :                     XMLSEC_ERRORS_R_MAX_RETRIEVAL_TYPE_MISMATCH,
    1302             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1303           0 :         xmlFreeDoc(doc);
    1304           0 :         return(-1);
    1305             :     }
    1306             : 
    1307             :     /* read data node */
    1308           0 :     ret = xmlSecKeyDataXmlRead(dataId, key, cur, keyInfoCtx);
    1309           0 :     if(ret < 0) {
    1310           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1311           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(typeId)),
    1312             :                     "xmlSecKeyDataXmlRead",
    1313             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1314             :                     "node=%s",
    1315           0 :                     xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
    1316           0 :         xmlFreeDoc(doc);
    1317           0 :         return(-1);
    1318             :     }
    1319             :     
    1320           0 :     xmlFreeDoc(doc);
    1321           0 :     return(0);
    1322             : }
    1323             : 
    1324             : 
    1325             : #ifndef XMLSEC_NO_XMLENC
    1326             : /**************************************************************************
    1327             :  *
    1328             :  * <enc:EncryptedKey/> processing
    1329             :  *
    1330             :  *************************************************************************/
    1331             : static int      xmlSecKeyDataEncryptedKeyXmlRead        (xmlSecKeyDataId id,
    1332             :                                                          xmlSecKeyPtr key,
    1333             :                                                          xmlNodePtr node,
    1334             :                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
    1335             : static int      xmlSecKeyDataEncryptedKeyXmlWrite       (xmlSecKeyDataId id,
    1336             :                                                          xmlSecKeyPtr key,
    1337             :                                                          xmlNodePtr node,
    1338             :                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
    1339             : 
    1340             : 
    1341             : 
    1342             : static xmlSecKeyDataKlass xmlSecKeyDataEncryptedKeyKlass = {
    1343             :     sizeof(xmlSecKeyDataKlass),
    1344             :     sizeof(xmlSecKeyData),
    1345             : 
    1346             :     /* data */
    1347             :     xmlSecNameEncryptedKey,
    1348             :     xmlSecKeyDataUsageKeyInfoNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,           
    1349             :                                                 /* xmlSecKeyDataUsage usage; */
    1350             :     xmlSecHrefEncryptedKey,                     /* const xmlChar* href; */
    1351             :     xmlSecNodeEncryptedKey,                     /* const xmlChar* dataNodeName; */
    1352             :     xmlSecEncNs,                                /* const xmlChar* dataNodeNs; */
    1353             :     
    1354             :     /* constructors/destructor */
    1355             :     NULL,                                       /* xmlSecKeyDataInitializeMethod initialize; */
    1356             :     NULL,                                       /* xmlSecKeyDataDuplicateMethod duplicate; */
    1357             :     NULL,                                       /* xmlSecKeyDataFinalizeMethod finalize; */
    1358             :     NULL,                                       /* xmlSecKeyDataGenerateMethod generate; */
    1359             :     
    1360             :     /* get info */
    1361             :     NULL,                                       /* xmlSecKeyDataGetTypeMethod getType; */
    1362             :     NULL,                                       /* xmlSecKeyDataGetSizeMethod getSize; */
    1363             :     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */    
    1364             : 
    1365             :     /* read/write */
    1366             :     xmlSecKeyDataEncryptedKeyXmlRead,           /* xmlSecKeyDataXmlReadMethod xmlRead; */
    1367             :     xmlSecKeyDataEncryptedKeyXmlWrite,          /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
    1368             :     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
    1369             :     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
    1370             : 
    1371             :     /* debug */
    1372             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugDump; */
    1373             :     NULL,                                       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
    1374             : 
    1375             :     /* reserved for the future */
    1376             :     NULL,                                       /* void* reserved0; */
    1377             :     NULL,                                       /* void* reserved1; */
    1378             : };
    1379             : 
    1380             : /** 
    1381             :  * xmlSecKeyDataEncryptedKeyGetKlass:
    1382             :  *
    1383             :  * The <enc:EncryptedKey/> element key data klass 
    1384             :  * (http://www.w3.org/TR/xmlenc-core/#sec-EncryptedKey):
    1385             :  *
    1386             :  * The EncryptedKey element is used to transport encryption keys from 
    1387             :  * the originator to a known recipient(s). It may be used as a stand-alone 
    1388             :  * XML document, be placed within an application document, or appear inside 
    1389             :  * an EncryptedData element as a child of a ds:KeyInfo element. The key value 
    1390             :  * is always encrypted to the recipient(s). When EncryptedKey is decrypted the 
    1391             :  * resulting octets are made available to the EncryptionMethod algorithm 
    1392             :  * without any additional processing.
    1393             :  * 
    1394             :  * Returns: the <enc:EncryptedKey/> element processing key data klass.
    1395             :  */
    1396             : xmlSecKeyDataId 
    1397           0 : xmlSecKeyDataEncryptedKeyGetKlass(void) {
    1398           0 :     return(&xmlSecKeyDataEncryptedKeyKlass);
    1399             : }
    1400             : 
    1401             : static int 
    1402           0 : xmlSecKeyDataEncryptedKeyXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
    1403             :     xmlSecBufferPtr result;
    1404             :     int ret;
    1405             : 
    1406           0 :     xmlSecAssert2(id == xmlSecKeyDataEncryptedKeyId, -1);
    1407           0 :     xmlSecAssert2(key != NULL, -1);
    1408           0 :     xmlSecAssert2(node != NULL, -1);
    1409           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
    1410           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeRead, -1);
    1411             : 
    1412             :     /* check the enc level */    
    1413           0 :     if(keyInfoCtx->curEncryptedKeyLevel >= keyInfoCtx->maxEncryptedKeyLevel) {
    1414           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1415           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1416             :                     NULL,
    1417             :                     XMLSEC_ERRORS_R_MAX_ENCKEY_LEVEL,
    1418             :                     "cur=%d;max=%d", 
    1419             :                     keyInfoCtx->curEncryptedKeyLevel,
    1420             :                     keyInfoCtx->maxEncryptedKeyLevel);
    1421           0 :         return(-1);
    1422             :     }
    1423           0 :     ++keyInfoCtx->curEncryptedKeyLevel;
    1424             : 
    1425             :     /* init Enc context */    
    1426           0 :     if(keyInfoCtx->encCtx != NULL) {
    1427           0 :         xmlSecEncCtxReset(keyInfoCtx->encCtx);
    1428             :     } else {
    1429           0 :         ret = xmlSecKeyInfoCtxCreateEncCtx(keyInfoCtx);
    1430           0 :         if(ret < 0) {
    1431           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1432           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1433             :                         "xmlSecKeyInfoCtxCreateEncCtx",
    1434             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1435             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1436           0 :             return(-1);         
    1437             :         }
    1438             :     }
    1439           0 :     xmlSecAssert2(keyInfoCtx->encCtx != NULL, -1);
    1440             :     
    1441           0 :     result = xmlSecEncCtxDecryptToBuffer(keyInfoCtx->encCtx, node);
    1442           0 :     if((result == NULL) || (xmlSecBufferGetData(result) == NULL)) {
    1443             :         /* We might have multiple EncryptedKey elements, encrypted 
    1444             :          * for different receipints but application can enforce
    1445             :          * correct enc key.
    1446             :          */
    1447           0 :         if((keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_ENCKEY_DONT_STOP_ON_FAILED_DECRYPTION) != 0) {
    1448           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1449           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1450             :                         "xmlSecEncCtxDecryptToBuffer",
    1451             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1452             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1453           0 :             return(-1);
    1454             :         }
    1455           0 :         return(0);
    1456             :     }
    1457             :          
    1458           0 :     ret = xmlSecKeyDataBinRead(keyInfoCtx->keyReq.keyId, key,
    1459           0 :                            xmlSecBufferGetData(result),
    1460             :                            xmlSecBufferGetSize(result),
    1461             :                            keyInfoCtx);
    1462           0 :     if(ret < 0) {
    1463           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1464           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1465             :                     "xmlSecKeyDataBinRead",
    1466             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1467             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1468           0 :         return(-1);
    1469             :     }                      
    1470           0 :     --keyInfoCtx->curEncryptedKeyLevel;
    1471             : 
    1472           0 :     return(0);
    1473             : }
    1474             : 
    1475             : static int 
    1476           0 : xmlSecKeyDataEncryptedKeyXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key, xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
    1477             :     xmlSecKeyInfoCtx keyInfoCtx2;
    1478           0 :     xmlSecByte *keyBuf = NULL;
    1479           0 :     xmlSecSize keySize = 0;
    1480           0 :     int res = -1;
    1481             :     int ret;
    1482             : 
    1483           0 :     xmlSecAssert2(id == xmlSecKeyDataEncryptedKeyId, -1);
    1484           0 :     xmlSecAssert2(key != NULL, -1);
    1485           0 :     xmlSecAssert2(xmlSecKeyIsValid(key), -1);
    1486           0 :     xmlSecAssert2(node != NULL, -1);
    1487           0 :     xmlSecAssert2(keyInfoCtx != NULL, -1);
    1488           0 :     xmlSecAssert2(keyInfoCtx->mode == xmlSecKeyInfoModeWrite, -1);
    1489             :     
    1490             :     /* dump key to a binary buffer */
    1491           0 :     ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx2, NULL);
    1492           0 :     if(ret < 0) {
    1493           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1494           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1495             :                     "xmlSecKeyInfoCtxInitialize",
    1496             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1497             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1498           0 :         goto done;
    1499             :     }
    1500             :     
    1501           0 :     ret = xmlSecKeyInfoCtxCopyUserPref(&keyInfoCtx2, keyInfoCtx);
    1502           0 :     if(ret < 0) {
    1503           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1504           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1505             :                     "xmlSecKeyInfoCtxCopyUserPref",
    1506             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1507             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1508           0 :         xmlSecKeyInfoCtxFinalize(&keyInfoCtx2);
    1509           0 :         goto done;
    1510             :     }
    1511             : 
    1512           0 :     keyInfoCtx2.keyReq.keyType = xmlSecKeyDataTypeAny;
    1513           0 :     ret = xmlSecKeyDataBinWrite(key->value->id, key, &keyBuf, &keySize, &keyInfoCtx2);
    1514           0 :     if(ret < 0) {
    1515           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1516           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1517             :                     "xmlSecKeyDataBinWrite",
    1518             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1519             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1520           0 :         xmlSecKeyInfoCtxFinalize(&keyInfoCtx2);
    1521           0 :         goto done;
    1522             :     }
    1523           0 :     xmlSecKeyInfoCtxFinalize(&keyInfoCtx2);
    1524             :     
    1525             :     /* init Enc context */    
    1526           0 :     if(keyInfoCtx->encCtx != NULL) {
    1527           0 :         xmlSecEncCtxReset(keyInfoCtx->encCtx);
    1528             :     } else {
    1529           0 :         ret = xmlSecKeyInfoCtxCreateEncCtx(keyInfoCtx);
    1530           0 :         if(ret < 0) {
    1531           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
    1532           0 :                         xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1533             :                         "xmlSecKeyInfoCtxCreateEncCtx",
    1534             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1535             :                         XMLSEC_ERRORS_NO_MESSAGE);
    1536           0 :             goto done;  
    1537             :         }
    1538             :     }
    1539           0 :     xmlSecAssert2(keyInfoCtx->encCtx != NULL, -1);
    1540             : 
    1541           0 :     ret = xmlSecEncCtxBinaryEncrypt(keyInfoCtx->encCtx, node, keyBuf, keySize);
    1542           0 :     if(ret < 0) {
    1543           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1544           0 :                     xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)),
    1545             :                     "xmlSecEncCtxBinaryEncrypt",
    1546             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1547             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1548           0 :         goto done;      
    1549             :     }
    1550             :     
    1551           0 :     res = 0;
    1552             : done:
    1553           0 :     if(keyBuf != NULL) {
    1554           0 :         memset(keyBuf, 0, keySize);
    1555           0 :         xmlFree(keyBuf); keyBuf = NULL;
    1556             :     }
    1557           0 :     return(res);
    1558             : }
    1559             : 
    1560             : #endif /* XMLSEC_NO_XMLENC */
    1561             : 

Generated by: LCOV version 1.10