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