xmlsecurityengine/xmlsec/src/xmlsec_xmlenc.c
changeset 0 e35f40988205
child 20 889504eac4fb
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 /** 
       
     2  * XML Security Library (http://www.aleksey.com/xmlsec).
       
     3  *
       
     4  * "XML Encryption" implementation
       
     5  *  http://www.w3.org/TR/xmlenc-core
       
     6  * 
       
     7  * This is free software; see Copyright file in the source
       
     8  * distribution for preciese wording.
       
     9  * 
       
    10  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
       
    11  * Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    12  */
       
    13 #include "xmlsec_config.h"
       
    14 #ifndef XMLSEC_NO_XMLENC
       
    15 #include "xmlsec_globals.h"
       
    16  
       
    17 #include <stdlib.h>
       
    18 #include <stdio.h>
       
    19 #include <string.h>
       
    20 
       
    21 #include <libxml2_tree.h>
       
    22 #include <libxml2_parser.h>
       
    23 #include <libxml2_globals.h>
       
    24 
       
    25 #include "xmlsec_xmlsec.h"
       
    26 #include "xmlsec_buffer.h"
       
    27 #include "xmlsec_xmltree.h"
       
    28 #include "xmlsec_keys.h"
       
    29 #include "xmlsec_keysmngr.h"
       
    30 #include "xmlsec_transforms.h"
       
    31 #include "xmlsec_keyinfo.h"
       
    32 #include "xmlsec_xmlenc.h"
       
    33 #include "xmlsec_errors.h"
       
    34 
       
    35 static int 	xmlSecEncCtxEncDataNodeRead		(xmlSecEncCtxPtr encCtx, 
       
    36 							 xmlNodePtr node);
       
    37 static int 	xmlSecEncCtxEncDataNodeWrite		(xmlSecEncCtxPtr encCtx);
       
    38 static int 	xmlSecEncCtxCipherDataNodeRead		(xmlSecEncCtxPtr encCtx, 
       
    39 							 xmlNodePtr node);
       
    40 static int 	xmlSecEncCtxCipherReferenceNodeRead	(xmlSecEncCtxPtr encCtx, 
       
    41 							 xmlNodePtr node);
       
    42 
       
    43 /* The ID attribute in XMLEnc is 'Id' */
       
    44 static const xmlChar*		xmlSecEncIds[] = { BAD_CAST "Id", NULL };
       
    45 
       
    46 
       
    47 /**
       
    48  * xmlSecEncCtxCreate:
       
    49  * @keysMngr: 		the pointer to keys manager.
       
    50  *
       
    51  * Creates <enc:EncryptedData/> element processing context.
       
    52  * The caller is responsible for destroying returend object by calling 
       
    53  * #xmlSecEncCtxDestroy function.
       
    54  *
       
    55  * Returns pointer to newly allocated context object or NULL if an error
       
    56  * occurs.
       
    57  */
       
    58 EXPORT_C
       
    59 xmlSecEncCtxPtr	
       
    60 xmlSecEncCtxCreate(xmlSecKeysMngrPtr keysMngr) {
       
    61     xmlSecEncCtxPtr encCtx;
       
    62     int ret;
       
    63     
       
    64     encCtx = (xmlSecEncCtxPtr) xmlMalloc(sizeof(xmlSecEncCtx));
       
    65     if(encCtx == NULL) {
       
    66 	xmlSecError(XMLSEC_ERRORS_HERE,
       
    67 		    NULL,
       
    68 		    NULL,
       
    69 		    XMLSEC_ERRORS_R_MALLOC_FAILED,
       
    70 		    "sizeof(xmlSecEncCtx)=%d", 
       
    71 		    sizeof(xmlSecEncCtx));
       
    72 	return(NULL);
       
    73     }
       
    74     
       
    75     ret = xmlSecEncCtxInitialize(encCtx, keysMngr);
       
    76     if(ret < 0) {
       
    77 	xmlSecError(XMLSEC_ERRORS_HERE,
       
    78 		    NULL,
       
    79 		    "xmlSecEncCtxInitialize",
       
    80 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
    81 		    XMLSEC_ERRORS_NO_MESSAGE);
       
    82 	xmlSecEncCtxDestroy(encCtx);
       
    83 	return(NULL);   
       
    84     }
       
    85     return(encCtx);    
       
    86 }
       
    87 
       
    88 /**
       
    89  * xmlSecEncCtxDestroy:
       
    90  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
    91  *
       
    92  * Destroy context object created with #xmlSecEncCtxCreate function.
       
    93  */
       
    94 EXPORT_C
       
    95 void  
       
    96 xmlSecEncCtxDestroy(xmlSecEncCtxPtr encCtx) {
       
    97     xmlSecAssert(encCtx != NULL);
       
    98     
       
    99     xmlSecEncCtxFinalize(encCtx);
       
   100     xmlFree(encCtx);
       
   101 }
       
   102 
       
   103 /**
       
   104  * xmlSecEncCtxInitialize:
       
   105  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   106  * @keysMngr: 		the pointer to keys manager.
       
   107  *
       
   108  * Initializes <enc:EncryptedData/> element processing context.
       
   109  * The caller is responsible for cleaing up returend object by calling 
       
   110  * #xmlSecEncCtxFinalize function.
       
   111  *
       
   112  * Returns 0 on success or a negative value if an error occurs.
       
   113  */
       
   114 EXPORT_C
       
   115 int 
       
   116 xmlSecEncCtxInitialize(xmlSecEncCtxPtr encCtx, xmlSecKeysMngrPtr keysMngr) {
       
   117     int ret;
       
   118     
       
   119     xmlSecAssert2(encCtx != NULL, -1);
       
   120     
       
   121     memset(encCtx, 0, sizeof(xmlSecEncCtx));
       
   122 
       
   123     /* initialize key info */
       
   124     ret = xmlSecKeyInfoCtxInitialize(&(encCtx->keyInfoReadCtx), keysMngr);
       
   125     if(ret < 0) {
       
   126 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   127 		    NULL,
       
   128 		    "xmlSecKeyInfoCtxInitialize",
       
   129 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   130 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   131 	return(-1);   
       
   132     }
       
   133     encCtx->keyInfoReadCtx.mode = xmlSecKeyInfoModeRead;
       
   134     
       
   135     ret = xmlSecKeyInfoCtxInitialize(&(encCtx->keyInfoWriteCtx), keysMngr);
       
   136     if(ret < 0) {
       
   137 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   138 		    NULL,
       
   139 		    "xmlSecKeyInfoCtxInitialize",
       
   140 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   141 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   142 	return(-1);   
       
   143     }
       
   144     encCtx->keyInfoWriteCtx.mode = xmlSecKeyInfoModeWrite;
       
   145     /* it's not wise to write private key :) */
       
   146     encCtx->keyInfoWriteCtx.keyReq.keyType = xmlSecKeyDataTypePublic;
       
   147 
       
   148     /* initializes transforms encCtx */
       
   149     ret = xmlSecTransformCtxInitialize(&(encCtx->transformCtx));
       
   150     if(ret < 0) {
       
   151 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   152 		    NULL,
       
   153 		    "xmlSecTransformCtxInitialize",
       
   154 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   155 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   156 	return(-1);   
       
   157     }
       
   158 
       
   159     return(0);
       
   160 }
       
   161 
       
   162 /**
       
   163  * xmlSecEncCtxFinalize:
       
   164  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   165  *
       
   166  * Cleans up @encCtx object.
       
   167  */
       
   168 EXPORT_C
       
   169 void 
       
   170 xmlSecEncCtxFinalize(xmlSecEncCtxPtr encCtx) {
       
   171     xmlSecAssert(encCtx != NULL);
       
   172 
       
   173     xmlSecEncCtxReset(encCtx);
       
   174     
       
   175     xmlSecTransformCtxFinalize(&(encCtx->transformCtx));
       
   176     xmlSecKeyInfoCtxFinalize(&(encCtx->keyInfoReadCtx));
       
   177     xmlSecKeyInfoCtxFinalize(&(encCtx->keyInfoWriteCtx));
       
   178 
       
   179     memset(encCtx, 0, sizeof(xmlSecEncCtx));
       
   180 }
       
   181 
       
   182 /**
       
   183  * xmlSecEncCtxReset:
       
   184  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   185  *
       
   186  * Resets @encCtx object, user settings are not touched.
       
   187  */
       
   188 EXPORT_C
       
   189 void 
       
   190 xmlSecEncCtxReset(xmlSecEncCtxPtr encCtx) {
       
   191     xmlSecAssert(encCtx != NULL);
       
   192     
       
   193     xmlSecTransformCtxReset(&(encCtx->transformCtx));
       
   194     xmlSecKeyInfoCtxReset(&(encCtx->keyInfoReadCtx));
       
   195     xmlSecKeyInfoCtxReset(&(encCtx->keyInfoWriteCtx));
       
   196 
       
   197     encCtx->operation 		= xmlSecTransformOperationNone;
       
   198     encCtx->result		= NULL;
       
   199     encCtx->resultBase64Encoded = 0;
       
   200     encCtx->resultReplaced	= 0;
       
   201     encCtx->encMethod		= NULL;
       
   202     if(encCtx->encKey != NULL) {
       
   203 	xmlSecKeyDestroy(encCtx->encKey);
       
   204 	encCtx->encKey = NULL;
       
   205     }
       
   206     
       
   207     if(encCtx->id != NULL) {
       
   208 	xmlFree(encCtx->id);
       
   209 	encCtx->id = NULL;
       
   210     }	
       
   211     if(encCtx->type != NULL) {
       
   212 	xmlFree(encCtx->type);
       
   213 	encCtx->type = NULL;
       
   214     }
       
   215     if(encCtx->mimeType != NULL) {
       
   216 	xmlFree(encCtx->mimeType);
       
   217 	encCtx->mimeType = NULL;
       
   218     }
       
   219     if(encCtx->encoding != NULL) {
       
   220 	xmlFree(encCtx->encoding);
       
   221 	encCtx->encoding = NULL;
       
   222     }	
       
   223     if(encCtx->recipient != NULL) {
       
   224 	xmlFree(encCtx->recipient);
       
   225 	encCtx->recipient = NULL;
       
   226     }
       
   227     if(encCtx->carriedKeyName != NULL) {
       
   228 	xmlFree(encCtx->carriedKeyName);
       
   229 	encCtx->carriedKeyName = NULL;
       
   230     }
       
   231     
       
   232     encCtx->encDataNode = encCtx->encMethodNode = 
       
   233 	encCtx->keyInfoNode = encCtx->cipherValueNode = NULL;
       
   234 }
       
   235 
       
   236 /**
       
   237  * xmlSecEncCtxCopyUserPref:
       
   238  * @dst:		the pointer to destination context.
       
   239  * @src:		the pointer to source context.
       
   240  * 
       
   241  * Copies user preference from @src context to @dst.
       
   242  *
       
   243  * Returns 0 on success or a negative value if an error occurs.
       
   244  */
       
   245 EXPORT_C
       
   246 int 
       
   247 xmlSecEncCtxCopyUserPref(xmlSecEncCtxPtr dst, xmlSecEncCtxPtr src) {
       
   248     int ret;
       
   249     
       
   250     xmlSecAssert2(dst != NULL, -1);
       
   251     xmlSecAssert2(src != NULL, -1);
       
   252 
       
   253     dst->userData 	= src->userData;
       
   254     dst->flags		= src->flags;
       
   255     dst->flags2		= src->flags2;
       
   256     dst->defEncMethodId = src->defEncMethodId;
       
   257     dst->mode 		= src->mode;
       
   258     
       
   259     ret = xmlSecTransformCtxCopyUserPref(&(dst->transformCtx), &(src->transformCtx));
       
   260     if(ret < 0) {
       
   261     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   262 		    NULL,
       
   263 		    "xmlSecTransformCtxCopyUserPref",
       
   264 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   265 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   266 	return(-1);
       
   267     }
       
   268 
       
   269     ret = xmlSecKeyInfoCtxCopyUserPref(&(dst->keyInfoReadCtx), &(src->keyInfoReadCtx));
       
   270     if(ret < 0) {
       
   271     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   272 		    NULL,
       
   273 		    "xmlSecKeyInfoCtxCopyUserPref",
       
   274 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   275 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   276 	return(-1);
       
   277     }
       
   278 
       
   279     ret = xmlSecKeyInfoCtxCopyUserPref(&(dst->keyInfoWriteCtx), &(src->keyInfoWriteCtx));
       
   280     if(ret < 0) {
       
   281     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   282 		    NULL,
       
   283 		    "xmlSecKeyInfoCtxCopyUserPref",
       
   284 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   285 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   286 	return(-1);
       
   287     }
       
   288 
       
   289     return(0);
       
   290 } 
       
   291 
       
   292 /**
       
   293  * xmlSecEncCtxBinaryEncrypt:
       
   294  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   295  * @tmpl:		the pointer to <enc:EncryptedData/> template node.
       
   296  * @data:		the pointer for binary buffer.
       
   297  * @dataSize:		the @data buffer size.
       
   298  *
       
   299  * Encrypts @data according to template @tmpl.
       
   300  *
       
   301  * Returns 0 on success or a negative value if an error occurs.
       
   302  */
       
   303 EXPORT_C
       
   304 int 
       
   305 xmlSecEncCtxBinaryEncrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr tmpl, 
       
   306 			  const xmlSecByte* data, xmlSecSize dataSize) {
       
   307     int ret;
       
   308     
       
   309     xmlSecAssert2(encCtx != NULL, -1);
       
   310     xmlSecAssert2(encCtx->result == NULL, -1);
       
   311     xmlSecAssert2(tmpl != NULL, -1);
       
   312     xmlSecAssert2(data != NULL, -1);
       
   313 
       
   314     /* initialize context and add ID atributes to the list of known ids */    
       
   315     encCtx->operation = xmlSecTransformOperationEncrypt;
       
   316     xmlSecAddIDs(tmpl->doc, tmpl, xmlSecEncIds);
       
   317 
       
   318     /* read the template and set encryption method, key, etc. */
       
   319     ret = xmlSecEncCtxEncDataNodeRead(encCtx, tmpl);
       
   320     if(ret < 0) {
       
   321     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   322 		    NULL,
       
   323 		    "xmlSecEncCtxEncDataNodeRead",
       
   324 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   325 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   326 	return(-1);
       
   327     }
       
   328 
       
   329     ret = xmlSecTransformCtxBinaryExecute(&(encCtx->transformCtx), data, dataSize);
       
   330     if(ret < 0) {
       
   331     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   332 		    NULL,
       
   333 		    "xmlSecTransformCtxBinaryExecute",
       
   334 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   335 		    "dataSize=%d",
       
   336 		    dataSize);
       
   337 	return(-1);
       
   338     }
       
   339 
       
   340     encCtx->result = encCtx->transformCtx.result;
       
   341     xmlSecAssert2(encCtx->result != NULL, -1);
       
   342     
       
   343     ret = xmlSecEncCtxEncDataNodeWrite(encCtx);
       
   344     if(ret < 0) {
       
   345     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   346 		    NULL,
       
   347 		    "xmlSecEncCtxEncDataNodeWrite",
       
   348 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   349 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   350 	return(-1);
       
   351     }
       
   352     return(0);    
       
   353 }
       
   354 
       
   355 /**
       
   356  * xmlSecEncCtxXmlEncrypt:
       
   357  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   358  * @tmpl:		the pointer to <enc:EncryptedData/> template node.
       
   359  * @node:		the pointer to node for encryption.
       
   360  *
       
   361  * Encrypts @node according to template @tmpl. If requested, @node is replaced
       
   362  * with result <enc:EncryptedData/> node.
       
   363  *
       
   364  * Returns 0 on success or a negative value if an error occurs.
       
   365  */
       
   366 EXPORT_C
       
   367 int 
       
   368 xmlSecEncCtxXmlEncrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr tmpl, xmlNodePtr node) {
       
   369     xmlOutputBufferPtr output;
       
   370     int ret;
       
   371     
       
   372     xmlSecAssert2(encCtx != NULL, -1);
       
   373     xmlSecAssert2(encCtx->result == NULL, -1);
       
   374     xmlSecAssert2(tmpl != NULL, -1);
       
   375     xmlSecAssert2(node != NULL, -1);
       
   376     xmlSecAssert2(node->doc != NULL, -1);
       
   377 
       
   378     /* initialize context and add ID atributes to the list of known ids */    
       
   379     encCtx->operation = xmlSecTransformOperationEncrypt;
       
   380     xmlSecAddIDs(tmpl->doc, tmpl, xmlSecEncIds);
       
   381 
       
   382     /* read the template and set encryption method, key, etc. */
       
   383     ret = xmlSecEncCtxEncDataNodeRead(encCtx, tmpl);
       
   384     if(ret < 0) {
       
   385     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   386 		    NULL,
       
   387 		    "xmlSecEncCtxEncDataNodeRead",
       
   388 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   389 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   390 	return(-1);
       
   391     }
       
   392 
       
   393     ret = xmlSecTransformCtxPrepare(&(encCtx->transformCtx), xmlSecTransformDataTypeBin);
       
   394     if(ret < 0) {
       
   395     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   396 		    NULL,
       
   397 		    "xmlSecTransformCtxPrepare",
       
   398 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   399 		    "type=bin");
       
   400 	return(-1);
       
   401     }
       
   402     
       
   403     xmlSecAssert2(encCtx->transformCtx.first != NULL, -1);
       
   404     output = xmlSecTransformCreateOutputBuffer(encCtx->transformCtx.first, 
       
   405 						&(encCtx->transformCtx));
       
   406     if(output == NULL) {
       
   407 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   408 		    xmlSecErrorsSafeString(xmlSecTransformGetName(encCtx->transformCtx.first)),
       
   409 		    "xmlSecTransformCreateOutputBuffer",
       
   410 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   411 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   412 	return(-1);
       
   413     }
       
   414 
       
   415     /* push data thru */
       
   416     if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
       
   417 	/* get the content of the node */
       
   418 	xmlNodeDumpOutput(output, node->doc, node, 0, 0, NULL);
       
   419     } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
       
   420 	xmlNodePtr cur;
       
   421 
       
   422 	/* get the content of the nodes childs */
       
   423 	for(cur = node->children; cur != NULL; cur = cur->next) {
       
   424 	    xmlNodeDumpOutput(output, node->doc, cur, 0, 0, NULL);
       
   425 	}
       
   426     } else {
       
   427 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   428 		    NULL,
       
   429 		    NULL,
       
   430 		    XMLSEC_ERRORS_R_INVALID_TYPE,
       
   431 		    "type=%s", 
       
   432 		    xmlSecErrorsSafeString(encCtx->type));
       
   433 	xmlOutputBufferClose(output);
       
   434 	return(-1);	    	
       
   435     }
       
   436     
       
   437     /* close the buffer and flush everything */
       
   438     ret = xmlOutputBufferClose(output);
       
   439     if(ret < 0) {
       
   440 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   441 		    NULL,
       
   442 		    "xmlOutputBufferClose",
       
   443 		    XMLSEC_ERRORS_R_XML_FAILED,
       
   444 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   445 	return(-1);
       
   446     }
       
   447 
       
   448     encCtx->result = encCtx->transformCtx.result;
       
   449     xmlSecAssert2(encCtx->result != NULL, -1);
       
   450     
       
   451     ret = xmlSecEncCtxEncDataNodeWrite(encCtx);
       
   452     if(ret < 0) {
       
   453     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   454 		    NULL,
       
   455 		    "xmlSecEncCtxEncDataNodeWrite",
       
   456 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   457 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   458 	return(-1);
       
   459     }
       
   460     
       
   461     /* now we need to update our original document */
       
   462     if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
       
   463 	ret = xmlSecReplaceNode(node, tmpl);
       
   464 	if(ret < 0) {
       
   465 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   466 			NULL,
       
   467 			"xmlSecReplaceNode",
       
   468 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   469 			"node=%s",
       
   470 			xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
       
   471 	    return(-1);
       
   472 	}
       
   473 	encCtx->resultReplaced = 1;			       
       
   474     } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
       
   475 	ret = xmlSecReplaceContent(node, tmpl);
       
   476 	if(ret < 0) {
       
   477 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   478 			NULL,
       
   479 			"xmlSecReplaceContent",
       
   480 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   481 			"node=%s",
       
   482 			xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
       
   483 	    return(-1);
       
   484 	}
       
   485 	encCtx->resultReplaced = 1;			       
       
   486     } else {
       
   487 	/* we should've catached this error before */
       
   488 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   489 		    NULL,
       
   490 		    NULL,
       
   491 		    XMLSEC_ERRORS_R_INVALID_TYPE,
       
   492 		    "type=%s", 
       
   493 		    xmlSecErrorsSafeString(encCtx->type));
       
   494 	return(-1);	    	
       
   495     }
       
   496     return(0);    
       
   497 }
       
   498 
       
   499 /**
       
   500  * xmlSecEncCtxUriEncrypt:
       
   501  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   502  * @tmpl:		the pointer to <enc:EncryptedData/> template node.
       
   503  * @uri:		the URI.
       
   504  *
       
   505  * Encrypts data from @uri according to template @tmpl.
       
   506  *
       
   507  * Returns 0 on success or a negative value if an error occurs.
       
   508  */
       
   509 EXPORT_C
       
   510 int 
       
   511 xmlSecEncCtxUriEncrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr tmpl, const xmlChar *uri) {
       
   512     int ret;
       
   513     
       
   514     xmlSecAssert2(encCtx != NULL, -1);
       
   515     xmlSecAssert2(encCtx->result == NULL, -1);
       
   516     xmlSecAssert2(tmpl != NULL, -1);
       
   517     xmlSecAssert2(uri != NULL, -1);
       
   518 
       
   519     /* initialize context and add ID atributes to the list of known ids */    
       
   520     encCtx->operation = xmlSecTransformOperationEncrypt;
       
   521     xmlSecAddIDs(tmpl->doc, tmpl, xmlSecEncIds);
       
   522 
       
   523     /* we need to add input uri transform first */
       
   524     ret = xmlSecTransformCtxSetUri(&(encCtx->transformCtx), uri, tmpl);
       
   525     if(ret < 0) {
       
   526     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   527 		    NULL,
       
   528 		    "xmlSecTransformCtxSetUri",
       
   529 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   530 		    "uri=%s",
       
   531 		    xmlSecErrorsSafeString(uri));
       
   532 	return(-1);
       
   533     }
       
   534 
       
   535     /* read the template and set encryption method, key, etc. */
       
   536     ret = xmlSecEncCtxEncDataNodeRead(encCtx, tmpl);
       
   537     if(ret < 0) {
       
   538     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   539 		    NULL,
       
   540 		    "xmlSecEncCtxEncDataNodeRead",
       
   541 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   542 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   543 	return(-1);
       
   544     }
       
   545 
       
   546     /* encrypt the data */
       
   547     ret = xmlSecTransformCtxExecute(&(encCtx->transformCtx), tmpl->doc);
       
   548     if(ret < 0) {
       
   549     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   550 		    NULL,
       
   551 		    "xmlSecTransformCtxExecute",
       
   552 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   553 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   554 	return(-1);
       
   555     }
       
   556         
       
   557     encCtx->result = encCtx->transformCtx.result;
       
   558     xmlSecAssert2(encCtx->result != NULL, -1);
       
   559     
       
   560     ret = xmlSecEncCtxEncDataNodeWrite(encCtx);
       
   561     if(ret < 0) {
       
   562     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   563 		    NULL,
       
   564 		    "xmlSecEncCtxEncDataNodeWrite",
       
   565 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   566 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   567 	return(-1);
       
   568     }    
       
   569     
       
   570     return(0);
       
   571 }
       
   572 
       
   573 /**
       
   574  * xmlSecEncCtxDecrypt:
       
   575  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   576  * @node:		the pointer to <enc:EncryptedData/> node.
       
   577  *
       
   578  * Decrypts @node and if necessary replaces @node with decrypted data.
       
   579  *
       
   580  * Returns 0 on success or a negative value if an error occurs.
       
   581  */
       
   582 EXPORT_C
       
   583 int 
       
   584 xmlSecEncCtxDecrypt(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
       
   585     xmlSecBufferPtr buffer;
       
   586     int ret;
       
   587     
       
   588     xmlSecAssert2(encCtx != NULL, -1);
       
   589     xmlSecAssert2(node != NULL, -1);
       
   590     
       
   591     /* decrypt */
       
   592     buffer = xmlSecEncCtxDecryptToBuffer(encCtx, node);
       
   593     if(buffer == NULL) {
       
   594     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   595 		    NULL,
       
   596 		    "xmlSecEncCtxDecryptToBuffer",
       
   597 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   598 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   599 	return(-1);
       
   600     }
       
   601     
       
   602     /* replace original node if requested */
       
   603     if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncElement)) {
       
   604 	ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer),  xmlSecBufferGetSize(buffer));
       
   605 	if(ret < 0) {
       
   606 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   607 			NULL,
       
   608 			"xmlSecReplaceNodeBuffer",
       
   609 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   610 			"node=%s",
       
   611 			xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
       
   612 	    return(-1);	    	
       
   613 	}
       
   614 	encCtx->resultReplaced = 1;			       
       
   615     } else if((encCtx->type != NULL) && xmlStrEqual(encCtx->type, xmlSecTypeEncContent)) {
       
   616 	/* replace the node with the buffer */
       
   617 	ret = xmlSecReplaceNodeBuffer(node, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer));
       
   618 	if(ret < 0) {
       
   619 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   620 			NULL,
       
   621 			"xmlSecReplaceNodeBuffer",
       
   622 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   623 			"node=%s",
       
   624 			xmlSecErrorsSafeString(xmlSecNodeGetName(node)));
       
   625 	    return(-1);	    	
       
   626 	}	
       
   627 	encCtx->resultReplaced = 1;			       
       
   628     }
       
   629     return(0);
       
   630 }
       
   631 
       
   632 /**
       
   633  * xmlSecEncCtxDecryptToBuffer:
       
   634  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
   635  * @node:		the pointer to <enc:EncryptedData/> node.
       
   636  * 
       
   637  * Decrypts @node data to the @encCtx buffer.
       
   638  *
       
   639  * Returns 0 on success or a negative value if an error occurs.
       
   640  */
       
   641 EXPORT_C
       
   642 xmlSecBufferPtr
       
   643 xmlSecEncCtxDecryptToBuffer(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
       
   644     int ret;
       
   645     
       
   646     xmlSecAssert2(encCtx != NULL, NULL);
       
   647     xmlSecAssert2(encCtx->result == NULL, NULL);
       
   648     xmlSecAssert2(node != NULL, NULL);
       
   649 
       
   650     /* initialize context and add ID atributes to the list of known ids */    
       
   651     encCtx->operation = xmlSecTransformOperationDecrypt;
       
   652     xmlSecAddIDs(node->doc, node, xmlSecEncIds);
       
   653 
       
   654     ret = xmlSecEncCtxEncDataNodeRead(encCtx, node);
       
   655     if(ret < 0) {
       
   656     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   657 		    NULL,
       
   658 		    "xmlSecEncCtxEncDataNodeRead",
       
   659 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   660 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   661 	return(NULL);
       
   662     }
       
   663 
       
   664     /* decrypt the data */
       
   665     if(encCtx->cipherValueNode != NULL) {
       
   666         xmlChar* data = NULL;
       
   667         xmlSecSize dataSize = 0;
       
   668 
       
   669 	data = xmlNodeGetContent(encCtx->cipherValueNode);
       
   670 	if(data == NULL) {
       
   671 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   672 			NULL,
       
   673 			xmlSecErrorsSafeString(xmlSecNodeGetName(encCtx->cipherValueNode)),
       
   674 			XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
       
   675 			XMLSEC_ERRORS_NO_MESSAGE);
       
   676 	    return(NULL);
       
   677 	}	
       
   678 	dataSize = xmlStrlen(data);
       
   679 
       
   680         ret = xmlSecTransformCtxBinaryExecute(&(encCtx->transformCtx), data, dataSize);
       
   681 	if(ret < 0) {
       
   682     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   683 			NULL,
       
   684 			"xmlSecTransformCtxBinaryExecute",
       
   685 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   686 			XMLSEC_ERRORS_NO_MESSAGE);
       
   687 	    if(data != NULL) {
       
   688 		xmlFree(data);
       
   689 	    }
       
   690 	    return(NULL);
       
   691 	}
       
   692 	if(data != NULL) {
       
   693 	    xmlFree(data);
       
   694 	}
       
   695     } else {
       
   696         ret = xmlSecTransformCtxExecute(&(encCtx->transformCtx), node->doc);
       
   697 	if(ret < 0) {
       
   698     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   699 			NULL,
       
   700 			"xmlSecTransformCtxBinaryExecute",
       
   701 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   702 			XMLSEC_ERRORS_NO_MESSAGE);
       
   703 	    return(NULL);
       
   704 	}
       
   705     }
       
   706     
       
   707     encCtx->result = encCtx->transformCtx.result;
       
   708     xmlSecAssert2(encCtx->result != NULL, NULL);
       
   709     
       
   710     return(encCtx->result);
       
   711 }
       
   712 
       
   713 static int 
       
   714 xmlSecEncCtxEncDataNodeRead(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
       
   715     xmlNodePtr cur;
       
   716     int ret;
       
   717     
       
   718     xmlSecAssert2(encCtx != NULL, -1);
       
   719     xmlSecAssert2((encCtx->operation == xmlSecTransformOperationEncrypt) || (encCtx->operation == xmlSecTransformOperationDecrypt), -1);
       
   720     xmlSecAssert2(node != NULL, -1);
       
   721 
       
   722     switch(encCtx->mode) {
       
   723 	case xmlEncCtxModeEncryptedData:
       
   724 	    if(!xmlSecCheckNodeName(node, xmlSecNodeEncryptedData, xmlSecEncNs)) {
       
   725     		xmlSecError(XMLSEC_ERRORS_HERE,
       
   726 			    NULL,
       
   727 			    xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
       
   728 			    XMLSEC_ERRORS_R_INVALID_NODE,
       
   729 			    "expected=%s",
       
   730 			    xmlSecErrorsSafeString(xmlSecNodeEncryptedData));
       
   731 		return(-1);	    
       
   732 	    }
       
   733 	    break;
       
   734 	case xmlEncCtxModeEncryptedKey:
       
   735 	    if(!xmlSecCheckNodeName(node, xmlSecNodeEncryptedKey, xmlSecEncNs)) {
       
   736     		xmlSecError(XMLSEC_ERRORS_HERE,
       
   737 			    NULL,
       
   738 			    xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
       
   739 			    XMLSEC_ERRORS_R_INVALID_NODE,
       
   740 			    "expected=%s",
       
   741 			    xmlSecErrorsSafeString(xmlSecNodeEncryptedKey));
       
   742 		return(-1);	    
       
   743 	    }
       
   744 	    break;
       
   745     }
       
   746     
       
   747     /* first read node data */
       
   748     xmlSecAssert2(encCtx->id == NULL, -1);
       
   749     xmlSecAssert2(encCtx->type == NULL, -1);
       
   750     xmlSecAssert2(encCtx->mimeType == NULL, -1);
       
   751     xmlSecAssert2(encCtx->encoding == NULL, -1);
       
   752     xmlSecAssert2(encCtx->recipient == NULL, -1);
       
   753     xmlSecAssert2(encCtx->carriedKeyName == NULL, -1);
       
   754     
       
   755     encCtx->id = xmlGetProp(node, xmlSecAttrId);
       
   756     encCtx->type = xmlGetProp(node, xmlSecAttrType);
       
   757     encCtx->mimeType = xmlGetProp(node, xmlSecAttrMimeType);
       
   758     encCtx->encoding = xmlGetProp(node, xmlSecAttrEncoding);    
       
   759     if(encCtx->mode == xmlEncCtxModeEncryptedKey) {
       
   760 	encCtx->recipient = xmlGetProp(node, xmlSecAttrRecipient);    
       
   761     }
       
   762     cur = xmlSecGetNextElementNode(node->children);
       
   763     
       
   764     /* first node is optional EncryptionMethod, we'll read it later */
       
   765     xmlSecAssert2(encCtx->encMethodNode == NULL, -1);
       
   766     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeEncryptionMethod, xmlSecEncNs))) {
       
   767 	encCtx->encMethodNode = cur;
       
   768         cur = xmlSecGetNextElementNode(cur->next);
       
   769     }
       
   770 
       
   771     /* next node is optional KeyInfo, we'll process it later */
       
   772     xmlSecAssert2(encCtx->keyInfoNode == NULL, -1);
       
   773     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs))) {
       
   774 	encCtx->keyInfoNode = cur;
       
   775 	cur = xmlSecGetNextElementNode(cur->next);
       
   776     }    
       
   777 
       
   778     /* next is required CipherData node */
       
   779     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeCipherData, xmlSecEncNs))) {
       
   780 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   781 		    NULL,
       
   782 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
   783 		    XMLSEC_ERRORS_R_INVALID_NODE,
       
   784 		    "node=%s",
       
   785 		    xmlSecErrorsSafeString(xmlSecNodeCipherData));
       
   786 	return(-1);
       
   787     }
       
   788     
       
   789     ret = xmlSecEncCtxCipherDataNodeRead(encCtx, cur);
       
   790     if(ret < 0) {
       
   791         xmlSecError(XMLSEC_ERRORS_HERE,
       
   792 		    NULL,
       
   793 		    "xmlSecEncCtxCipherDataNodeRead",
       
   794 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   795 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   796 	return(-1);
       
   797     }
       
   798     cur = xmlSecGetNextElementNode(cur->next);
       
   799 
       
   800     /* next is optional EncryptionProperties node (we simply ignore it) */
       
   801     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeEncryptionProperties, xmlSecEncNs))) {
       
   802 	cur = xmlSecGetNextElementNode(cur->next);
       
   803     }
       
   804 
       
   805     /* there are more possible nodes for the <EncryptedKey> node */
       
   806     if(encCtx->mode == xmlEncCtxModeEncryptedKey) {
       
   807 	/* next is optional ReferenceList node (we simply ignore it) */
       
   808         if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeReferenceList, xmlSecEncNs))) {
       
   809 	    cur = xmlSecGetNextElementNode(cur->next);
       
   810 	}
       
   811 
       
   812         /* next is optional CarriedKeyName node (we simply ignore it) */
       
   813 	if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCarriedKeyName, xmlSecEncNs))) {
       
   814 	    encCtx->carriedKeyName = xmlNodeGetContent(cur);
       
   815 	    if(encCtx->carriedKeyName == NULL) {
       
   816 		xmlSecError(XMLSEC_ERRORS_HERE,
       
   817 			    NULL,
       
   818 			    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
   819 			    XMLSEC_ERRORS_R_INVALID_NODE_CONTENT,
       
   820 			    "node=%s",
       
   821 			    xmlSecErrorsSafeString(xmlSecNodeCipherData));
       
   822 		return(-1);
       
   823 	    }
       
   824 	    cur = xmlSecGetNextElementNode(cur->next);
       
   825 	}
       
   826     }
       
   827 
       
   828     /* if there is something left than it's an error */
       
   829     if(cur != NULL) {
       
   830 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   831 		    NULL,
       
   832 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
   833 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
   834 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   835 	return(-1);
       
   836     }
       
   837 
       
   838     /* now read the encryption method node */
       
   839     xmlSecAssert2(encCtx->encMethod == NULL, -1);
       
   840     if(encCtx->encMethodNode != NULL) {
       
   841 	encCtx->encMethod = xmlSecTransformCtxNodeRead(&(encCtx->transformCtx), encCtx->encMethodNode,
       
   842 						xmlSecTransformUsageEncryptionMethod);
       
   843 	if(encCtx->encMethod == NULL) {
       
   844 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   845 		    	NULL,
       
   846 			"xmlSecTransformCtxNodeRead",
       
   847 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   848 			"node=%s",
       
   849 			xmlSecErrorsSafeString(xmlSecNodeGetName(encCtx->encMethodNode)));
       
   850 	    return(-1);	    
       
   851 	}	
       
   852     } else if(encCtx->defEncMethodId != xmlSecTransformIdUnknown) {
       
   853 	encCtx->encMethod = xmlSecTransformCtxCreateAndAppend(&(encCtx->transformCtx), 
       
   854 							      encCtx->defEncMethodId);
       
   855 	if(encCtx->encMethod == NULL) {
       
   856     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   857 			NULL,
       
   858 			"xmlSecTransformCtxAppend",
       
   859 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   860 			XMLSEC_ERRORS_NO_MESSAGE);
       
   861 	    return(-1);
       
   862 	}
       
   863     } else {
       
   864 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   865 		    NULL,
       
   866 		    NULL,
       
   867 		    XMLSEC_ERRORS_R_INVALID_DATA,
       
   868 		    "encryption method not specified");
       
   869 	return(-1);
       
   870     }
       
   871     encCtx->encMethod->operation = encCtx->operation;
       
   872     
       
   873     /* we have encryption method, find key */
       
   874     ret = xmlSecTransformSetKeyReq(encCtx->encMethod, &(encCtx->keyInfoReadCtx.keyReq));
       
   875     if(ret < 0) {
       
   876     	xmlSecError(XMLSEC_ERRORS_HERE,
       
   877 		    NULL,
       
   878 		    "xmlSecTransformSetKeyReq",
       
   879 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   880 		    "transform=%s",
       
   881 		    xmlSecErrorsSafeString(xmlSecTransformGetName(encCtx->encMethod)));
       
   882 	return(-1);
       
   883     }	
       
   884 
       
   885     if((encCtx->encKey == NULL) && (encCtx->keyInfoReadCtx.keysMngr != NULL) 
       
   886 			&& (encCtx->keyInfoReadCtx.keysMngr->getKey != NULL)) {
       
   887 	encCtx->encKey = (encCtx->keyInfoReadCtx.keysMngr->getKey)(encCtx->keyInfoNode, 
       
   888 							     &(encCtx->keyInfoReadCtx));
       
   889     }
       
   890     
       
   891     /* check that we have exactly what we want */
       
   892     if((encCtx->encKey == NULL) || 
       
   893        (!xmlSecKeyMatch(encCtx->encKey, NULL, &(encCtx->keyInfoReadCtx.keyReq)))) {
       
   894 
       
   895 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   896 		    NULL,
       
   897 		    NULL,
       
   898 		    XMLSEC_ERRORS_R_KEY_NOT_FOUND,
       
   899 		    XMLSEC_ERRORS_NO_MESSAGE);
       
   900 	return(-1);
       
   901     }
       
   902     
       
   903     /* set the key to the transform */
       
   904     ret = xmlSecTransformSetKey(encCtx->encMethod, encCtx->encKey);
       
   905     if(ret < 0) {
       
   906 	xmlSecError(XMLSEC_ERRORS_HERE,
       
   907 		    NULL,
       
   908 		    "xmlSecTransformSetKey",
       
   909 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   910 		    "transform=%s",
       
   911 		    xmlSecErrorsSafeString(xmlSecTransformGetName(encCtx->encMethod)));
       
   912 	return(-1);
       
   913     }
       
   914 
       
   915     /* if we need to write result to xml node then we need base64 encode it */
       
   916     if((encCtx->operation == xmlSecTransformOperationEncrypt) && (encCtx->cipherValueNode != NULL)) {	
       
   917 	xmlSecTransformPtr base64Encode;
       
   918 	
       
   919 	/* we need to add base64 encode transform */
       
   920 	base64Encode = xmlSecTransformCtxCreateAndAppend(&(encCtx->transformCtx), xmlSecTransformBase64Id);
       
   921     	if(base64Encode == NULL) {
       
   922     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   923 			NULL,
       
   924 			"xmlSecTransformCtxCreateAndAppend",
       
   925 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   926 			XMLSEC_ERRORS_NO_MESSAGE);
       
   927 	    return(-1);
       
   928 	}
       
   929 	base64Encode->operation 	= xmlSecTransformOperationEncode;
       
   930 	encCtx->resultBase64Encoded 	= 1;
       
   931     }
       
   932     
       
   933     return(0);
       
   934 }
       
   935 
       
   936 static int 
       
   937 xmlSecEncCtxEncDataNodeWrite(xmlSecEncCtxPtr encCtx) {
       
   938     int ret;
       
   939     
       
   940     xmlSecAssert2(encCtx != NULL, -1);
       
   941     xmlSecAssert2(encCtx->result != NULL, -1);
       
   942     xmlSecAssert2(encCtx->encKey != NULL, -1);
       
   943     
       
   944     /* write encrypted data to xml (if requested) */
       
   945     if(encCtx->cipherValueNode != NULL) {	
       
   946 	xmlSecAssert2(xmlSecBufferGetData(encCtx->result) != NULL, -1);
       
   947 
       
   948 	xmlNodeSetContentLen(encCtx->cipherValueNode,
       
   949 			    xmlSecBufferGetData(encCtx->result),
       
   950 			    xmlSecBufferGetSize(encCtx->result));
       
   951 	if (OOM_FLAG)
       
   952 	    {
       
   953 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   954 			NULL,
       
   955 			"xmlNodeSetContentLen",
       
   956 			XMLSEC_ERRORS_R_MALLOC_FAILED,
       
   957 			XMLSEC_ERRORS_NO_MESSAGE);
       
   958 	    return(-1);
       
   959 	    }			    
       
   960 	encCtx->resultReplaced = 1;
       
   961     }
       
   962 
       
   963     /* update <enc:KeyInfo/> node */
       
   964     if(encCtx->keyInfoNode != NULL) {
       
   965 	ret = xmlSecKeyInfoNodeWrite(encCtx->keyInfoNode, encCtx->encKey, &(encCtx->keyInfoWriteCtx));
       
   966 	if(ret < 0) {
       
   967     	    xmlSecError(XMLSEC_ERRORS_HERE,
       
   968 			NULL,
       
   969 			"xmlSecKeyInfoNodeWrite",
       
   970 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
   971 			XMLSEC_ERRORS_NO_MESSAGE);
       
   972 	    return(-1);
       
   973 	}	
       
   974     }
       
   975     
       
   976     return(0);
       
   977 }
       
   978 
       
   979 static int 
       
   980 xmlSecEncCtxCipherDataNodeRead(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
       
   981     xmlNodePtr cur;
       
   982     int ret;
       
   983     
       
   984     xmlSecAssert2(encCtx != NULL, -1);
       
   985     xmlSecAssert2(node != NULL, -1);
       
   986     
       
   987     cur = xmlSecGetNextElementNode(node->children);
       
   988     
       
   989     /* we either have CipherValue or CipherReference node  */
       
   990     xmlSecAssert2(encCtx->cipherValueNode == NULL, -1);
       
   991     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCipherValue, xmlSecEncNs))) {
       
   992         /* don't need data from CipherData node when we are encrypting */
       
   993 	if(encCtx->operation == xmlSecTransformOperationDecrypt) {
       
   994 	    xmlSecTransformPtr base64Decode;
       
   995 	
       
   996 	    /* we need to add base64 decode transform */
       
   997 	    base64Decode = xmlSecTransformCtxCreateAndPrepend(&(encCtx->transformCtx), xmlSecTransformBase64Id);
       
   998     	    if(base64Decode == NULL) {
       
   999     		xmlSecError(XMLSEC_ERRORS_HERE,
       
  1000 			    NULL,
       
  1001 			    "xmlSecTransformCtxCreateAndPrepend",
       
  1002 			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1003 			    XMLSEC_ERRORS_NO_MESSAGE);
       
  1004 	        return(-1);
       
  1005 	    }
       
  1006 	}
       
  1007 	encCtx->cipherValueNode = cur;
       
  1008         cur = xmlSecGetNextElementNode(cur->next);
       
  1009     } else if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCipherReference, xmlSecEncNs))) {
       
  1010         /* don't need data from CipherReference node when we are encrypting */
       
  1011 	if(encCtx->operation == xmlSecTransformOperationDecrypt) {
       
  1012     	    ret = xmlSecEncCtxCipherReferenceNodeRead(encCtx, cur);
       
  1013 	    if(ret < 0) {
       
  1014 		xmlSecError(XMLSEC_ERRORS_HERE,
       
  1015 		    	    NULL,
       
  1016 			    "xmlSecEncCtxCipherReferenceNodeRead",
       
  1017 			    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1018 			    "node=%s",
       
  1019 			    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
       
  1020 		return(-1);	    
       
  1021 	    }
       
  1022 	}	
       
  1023         cur = xmlSecGetNextElementNode(cur->next);
       
  1024     }
       
  1025     
       
  1026     if(cur != NULL) {
       
  1027 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1028 		    NULL,
       
  1029 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  1030 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  1031 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1032 	return(-1);
       
  1033     }
       
  1034     return(0);
       
  1035 }
       
  1036 
       
  1037 static int 
       
  1038 xmlSecEncCtxCipherReferenceNodeRead(xmlSecEncCtxPtr encCtx, xmlNodePtr node) {
       
  1039     xmlNodePtr cur;
       
  1040     xmlChar* uri;
       
  1041     int ret;
       
  1042     
       
  1043     xmlSecAssert2(encCtx != NULL, -1);
       
  1044     xmlSecAssert2(node != NULL, -1);
       
  1045     
       
  1046     /* first read the optional uri attr and check that we can process it */
       
  1047     uri = xmlGetProp(node, xmlSecAttrURI);
       
  1048     ret = xmlSecTransformCtxSetUri(&(encCtx->transformCtx), uri, node);
       
  1049     if(ret < 0) {
       
  1050 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1051 		    NULL,
       
  1052 		    "xmlSecTransformCtxSetUri",
       
  1053 		    XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1054 		    "uri=%s",
       
  1055 		    xmlSecErrorsSafeString(uri));
       
  1056 	xmlFree(uri);
       
  1057 	return(-1);	    
       
  1058     }		
       
  1059     xmlFree(uri);
       
  1060 
       
  1061     cur = xmlSecGetNextElementNode(node->children);
       
  1062     
       
  1063     /* the only one node is optional Transforms node */
       
  1064     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeTransforms, xmlSecEncNs))) {
       
  1065 	ret = xmlSecTransformCtxNodesListRead(&(encCtx->transformCtx), cur,
       
  1066 				    xmlSecTransformUsageDSigTransform);
       
  1067 	if(ret < 0) {
       
  1068 	    xmlSecError(XMLSEC_ERRORS_HERE,
       
  1069 		    	NULL,
       
  1070 			"xmlSecTransformCtxNodesListRead",
       
  1071 			XMLSEC_ERRORS_R_XMLSEC_FAILED,
       
  1072 			"node=%s",
       
  1073 			xmlSecErrorsSafeString(xmlSecNodeGetName(encCtx->encMethodNode)));
       
  1074 	    return(-1);	    
       
  1075 	}	
       
  1076         cur = xmlSecGetNextElementNode(cur->next);
       
  1077     }
       
  1078     
       
  1079     /* if there is something left than it's an error */
       
  1080     if(cur != NULL) {
       
  1081 	xmlSecError(XMLSEC_ERRORS_HERE,
       
  1082 		    NULL,
       
  1083 		    xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
       
  1084 		    XMLSEC_ERRORS_R_UNEXPECTED_NODE,
       
  1085 		    XMLSEC_ERRORS_NO_MESSAGE);
       
  1086 	return(-1);
       
  1087     }
       
  1088     return(0);
       
  1089 }
       
  1090 
       
  1091 /**
       
  1092  * xmlSecEncCtxDebugDump:
       
  1093  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
  1094  * @output:		the pointer to output FILE.
       
  1095  *
       
  1096  * Prints the debug information about @encCtx to @output.
       
  1097  */
       
  1098 EXPORT_C
       
  1099 void 
       
  1100 xmlSecEncCtxDebugDump(xmlSecEncCtxPtr encCtx, FILE* output) {
       
  1101     xmlSecAssert(encCtx != NULL);
       
  1102     xmlSecAssert(output != NULL);
       
  1103 
       
  1104     switch(encCtx->mode) {
       
  1105 	case xmlEncCtxModeEncryptedData:
       
  1106 	    if(encCtx->operation == xmlSecTransformOperationEncrypt) {    
       
  1107 		fprintf(output, "= DATA ENCRYPTION CONTEXT\n");
       
  1108 	    } else {
       
  1109 		fprintf(output, "= DATA DECRYPTION CONTEXT\n");
       
  1110 	    }
       
  1111 	    break;
       
  1112 	case xmlEncCtxModeEncryptedKey:
       
  1113 	    if(encCtx->operation == xmlSecTransformOperationEncrypt) {    
       
  1114 		fprintf(output, "= KEY ENCRYPTION CONTEXT\n");
       
  1115 	    } else {
       
  1116 		fprintf(output, "= KEY DECRYPTION CONTEXT\n");
       
  1117 	    }
       
  1118 	    break;
       
  1119     }
       
  1120     fprintf(output, "== Status: %s\n",
       
  1121 	    (encCtx->resultReplaced) ? "replaced" : "not-replaced" );
       
  1122 
       
  1123     fprintf(output, "== flags: 0x%08x\n", encCtx->flags);
       
  1124     fprintf(output, "== flags2: 0x%08x\n", encCtx->flags2);
       
  1125 
       
  1126     if(encCtx->id != NULL) {
       
  1127 	fprintf(output, "== Id: \"%s\"\n", encCtx->id);
       
  1128     }
       
  1129     if(encCtx->type != NULL) {
       
  1130 	fprintf(output, "== Type: \"%s\"\n", encCtx->type);
       
  1131     }
       
  1132     if(encCtx->mimeType != NULL) {
       
  1133 	fprintf(output, "== MimeType: \"%s\"\n", encCtx->mimeType);
       
  1134     }
       
  1135     if(encCtx->encoding != NULL) {
       
  1136 	fprintf(output, "== Encoding: \"%s\"\n", encCtx->encoding);
       
  1137     }
       
  1138     if(encCtx->recipient != NULL) {
       
  1139 	fprintf(output, "== Recipient: \"%s\"\n", encCtx->recipient);
       
  1140     }
       
  1141     if(encCtx->carriedKeyName != NULL) {
       
  1142 	fprintf(output, "== CarriedKeyName: \"%s\"\n", encCtx->carriedKeyName);
       
  1143     }
       
  1144     
       
  1145     fprintf(output, "== Key Info Read Ctx:\n");
       
  1146     xmlSecKeyInfoCtxDebugDump(&(encCtx->keyInfoReadCtx), output);
       
  1147 
       
  1148     fprintf(output, "== Key Info Write Ctx:\n");
       
  1149     xmlSecKeyInfoCtxDebugDump(&(encCtx->keyInfoWriteCtx), output);
       
  1150 
       
  1151     fprintf(output, "== Encryption Transform Ctx:\n");
       
  1152     xmlSecTransformCtxDebugDump(&(encCtx->transformCtx), output);
       
  1153 
       
  1154     if(encCtx->encMethod != NULL) {
       
  1155         fprintf(output, "== Encryption Method:\n");
       
  1156 	xmlSecTransformDebugDump(encCtx->encMethod, output);
       
  1157     }
       
  1158 
       
  1159     if(encCtx->encKey != NULL) {
       
  1160         fprintf(output, "== Encryption Key:\n");
       
  1161 	xmlSecKeyDebugDump(encCtx->encKey, output);
       
  1162     }
       
  1163     
       
  1164     if((encCtx->result != NULL) && 
       
  1165        (xmlSecBufferGetData(encCtx->result) != NULL) && 
       
  1166        (encCtx->resultBase64Encoded != 0)) {
       
  1167 
       
  1168 	fprintf(output, "== Result - start buffer:\n");
       
  1169 	fwrite(xmlSecBufferGetData(encCtx->result), 
       
  1170 	       xmlSecBufferGetSize(encCtx->result), 1,
       
  1171 	       output);
       
  1172 	fprintf(output, "\n== Result - end buffer\n");
       
  1173     }
       
  1174 }
       
  1175 
       
  1176 /**
       
  1177  * xmlSecEncCtxDebugXmlDump:
       
  1178  * @encCtx:		the pointer to <enc:EncryptedData/> processing context.
       
  1179  * @output:		the pointer to output FILE.
       
  1180  *
       
  1181  * Prints the debug information about @encCtx to @output in XML format.
       
  1182  */
       
  1183 EXPORT_C
       
  1184 void 
       
  1185 xmlSecEncCtxDebugXmlDump(xmlSecEncCtxPtr encCtx, FILE* output) {
       
  1186     xmlSecAssert(encCtx != NULL);
       
  1187     xmlSecAssert(output != NULL);
       
  1188 
       
  1189     switch(encCtx->mode) {
       
  1190 	case xmlEncCtxModeEncryptedData:
       
  1191 	    if(encCtx->operation == xmlSecTransformOperationEncrypt) {    
       
  1192 		fprintf(output, "<DataEncryptionContext ");
       
  1193 	    } else {
       
  1194 		fprintf(output, "<DataDecryptionContext ");
       
  1195 	    }
       
  1196 	    break;
       
  1197 	case xmlEncCtxModeEncryptedKey:
       
  1198 	    if(encCtx->operation == xmlSecTransformOperationEncrypt) {    
       
  1199 		fprintf(output, "<KeyEncryptionContext ");
       
  1200 	    } else {
       
  1201 		fprintf(output, "<KeyDecryptionContext ");
       
  1202 	    }
       
  1203 	    break;
       
  1204     }
       
  1205     fprintf(output, "status=\"%s\" >\n", (encCtx->resultReplaced) ? "replaced" : "not-replaced" );
       
  1206 
       
  1207     fprintf(output, "<Flags>%08x</Flags>\n", encCtx->flags);
       
  1208     fprintf(output, "<Flags2>%08x</Flags2>\n", encCtx->flags2);
       
  1209 
       
  1210     if(encCtx->id != NULL) {
       
  1211 	fprintf(output, "<Id>%s</Id>\n", encCtx->id);
       
  1212     }
       
  1213     if(encCtx->type != NULL) {
       
  1214 	fprintf(output, "<Type>%s</Type>\n", encCtx->type);
       
  1215     }
       
  1216     if(encCtx->mimeType != NULL) {
       
  1217 	fprintf(output, "<MimeType>%s</MimeType>\n", encCtx->mimeType);
       
  1218     }
       
  1219     if(encCtx->encoding != NULL) {
       
  1220 	fprintf(output, "<Encoding>%s</Encoding>\n", encCtx->encoding);
       
  1221     }
       
  1222     if(encCtx->recipient != NULL) {
       
  1223 	fprintf(output, "<Recipient>%s</Recipient>\n", encCtx->recipient);
       
  1224     }
       
  1225     if(encCtx->carriedKeyName != NULL) {
       
  1226 	fprintf(output, "<CarriedKeyName>%s</CarriedKeyName>\n", encCtx->carriedKeyName);
       
  1227     }
       
  1228 
       
  1229     fprintf(output, "<KeyInfoReadCtx>\n");
       
  1230     xmlSecKeyInfoCtxDebugXmlDump(&(encCtx->keyInfoReadCtx), output);
       
  1231     fprintf(output, "</KeyInfoReadCtx>\n");
       
  1232 
       
  1233     fprintf(output, "<KeyInfoWriteCtx>\n");
       
  1234     xmlSecKeyInfoCtxDebugXmlDump(&(encCtx->keyInfoWriteCtx), output);
       
  1235     fprintf(output, "</KeyInfoWriteCtx>\n");
       
  1236 
       
  1237     fprintf(output, "<EncryptionTransformCtx>\n");
       
  1238     xmlSecTransformCtxDebugXmlDump(&(encCtx->transformCtx), output);
       
  1239     fprintf(output, "</EncryptionTransformCtx>\n");
       
  1240 
       
  1241     if(encCtx->encMethod != NULL) {
       
  1242         fprintf(output, "<EncryptionMethod>\n");
       
  1243 	xmlSecTransformDebugXmlDump(encCtx->encMethod, output);
       
  1244         fprintf(output, "</EncryptionMethod>\n");
       
  1245     }
       
  1246 
       
  1247     if(encCtx->encKey != NULL) {
       
  1248         fprintf(output, "<EncryptionKey>\n");
       
  1249 	xmlSecKeyDebugXmlDump(encCtx->encKey, output);
       
  1250         fprintf(output, "</EncryptionKey>\n");
       
  1251     }
       
  1252     
       
  1253     if((encCtx->result != NULL) && 
       
  1254        (xmlSecBufferGetData(encCtx->result) != NULL) && 
       
  1255        (encCtx->resultBase64Encoded != 0)) {
       
  1256 
       
  1257 	fprintf(output, "<Result>");
       
  1258 	fwrite(xmlSecBufferGetData(encCtx->result), 
       
  1259 	       xmlSecBufferGetSize(encCtx->result), 1,
       
  1260 	       output);
       
  1261 	fprintf(output, "</Result>\n");
       
  1262     }
       
  1263 
       
  1264     switch(encCtx->mode) {
       
  1265 	case xmlEncCtxModeEncryptedData:
       
  1266 	    if(encCtx->operation == xmlSecTransformOperationEncrypt) {    
       
  1267 		fprintf(output, "</DataEncryptionContext>\n");
       
  1268 	    } else {
       
  1269 		fprintf(output, "</DataDecryptionContext>\n");
       
  1270 	    }
       
  1271 	    break;
       
  1272 	case xmlEncCtxModeEncryptedKey:
       
  1273 	    if(encCtx->operation == xmlSecTransformOperationEncrypt) {    
       
  1274 		fprintf(output, "</KeyEncryptionContext>\n");
       
  1275 	    } else {
       
  1276 		fprintf(output, "</KeyDecryptionContext>\n");
       
  1277 	    }
       
  1278 	    break;
       
  1279     }
       
  1280 }
       
  1281 
       
  1282 #endif /* XMLSEC_NO_XMLENC */
       
  1283