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