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