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