1 /*
2  * XML Security Library (http://www.aleksey.com/xmlsec).
3  *
4  *
5  * This is free software; see Copyright file in the source
6  * distribution for preciese wording.
7  *
8  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
9  */
10 /**
11  * SECTION:keys
12  * @Short_description: Crypto key object functions.
13  * @Stability: Stable
14  *
15  */
16 
17 #include "globals.h"
18 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <libxml/tree.h>
23 
24 #include <xmlsec/xmlsec.h>
25 #include <xmlsec/xmltree.h>
26 #include <xmlsec/list.h>
27 #include <xmlsec/keys.h>
28 #include <xmlsec/keysmngr.h>
29 #include <xmlsec/transforms.h>
30 #include <xmlsec/keyinfo.h>
31 #include <xmlsec/errors.h>
32 
33 
34 /**************************************************************************
35  *
36  * xmlSecKeyUseWith
37  *
38  *************************************************************************/
39 /**
40  * xmlSecKeyUseWithInitialize:
41  * @keyUseWith:         the pointer to information about key application/user.
42  *
43  * Initializes @keyUseWith object.
44  *
45  * Returns: 0 on success or a negative value if an error occurs.
46  */
47 int
xmlSecKeyUseWithInitialize(xmlSecKeyUseWithPtr keyUseWith)48 xmlSecKeyUseWithInitialize(xmlSecKeyUseWithPtr keyUseWith) {
49     xmlSecAssert2(keyUseWith != NULL, -1);
50 
51     memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
52     return(0);
53 }
54 
55 /**
56  * xmlSecKeyUseWithFinalize:
57  * @keyUseWith:         the pointer to information about key application/user.
58  *
59  * Finalizes @keyUseWith object.
60  */
61 void
xmlSecKeyUseWithFinalize(xmlSecKeyUseWithPtr keyUseWith)62 xmlSecKeyUseWithFinalize(xmlSecKeyUseWithPtr keyUseWith) {
63     xmlSecAssert(keyUseWith != NULL);
64 
65     xmlSecKeyUseWithReset(keyUseWith);
66     memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
67 }
68 
69 /**
70  * xmlSecKeyUseWithReset:
71  * @keyUseWith:         the pointer to information about key application/user.
72  *
73  * Resets the @keyUseWith to its state after initialization.
74  */
75 void
xmlSecKeyUseWithReset(xmlSecKeyUseWithPtr keyUseWith)76 xmlSecKeyUseWithReset(xmlSecKeyUseWithPtr keyUseWith) {
77     xmlSecAssert(keyUseWith != NULL);
78 
79     xmlSecKeyUseWithSet(keyUseWith, NULL, NULL);
80 }
81 
82 /**
83  * xmlSecKeyUseWithCopy:
84  * @dst:         the pointer to destination object.
85  * @src:         the pointer to source object.
86  *
87  * Copies information from @dst to @src.
88  *
89  * Returns: 0 on success or a negative value if an error occurs.
90  */
91 int
xmlSecKeyUseWithCopy(xmlSecKeyUseWithPtr dst,xmlSecKeyUseWithPtr src)92 xmlSecKeyUseWithCopy(xmlSecKeyUseWithPtr dst, xmlSecKeyUseWithPtr src) {
93     xmlSecAssert2(dst != NULL, -1);
94     xmlSecAssert2(src != NULL, -1);
95 
96     return(xmlSecKeyUseWithSet(dst, src->application, src->identifier));
97 }
98 
99 /**
100  * xmlSecKeyUseWithCreate:
101  * @application:        the application value.
102  * @identifier:         the identifier value.
103  *
104  * Creates new xmlSecKeyUseWith object. The caller is responsible for destroying
105  * returned object with @xmlSecKeyUseWithDestroy function.
106  *
107  * Returns: pointer to newly created object or NULL if an error occurs.
108  */
109 xmlSecKeyUseWithPtr
xmlSecKeyUseWithCreate(const xmlChar * application,const xmlChar * identifier)110 xmlSecKeyUseWithCreate(const xmlChar* application, const xmlChar* identifier) {
111     xmlSecKeyUseWithPtr keyUseWith;
112     int ret;
113 
114     /* Allocate a new xmlSecKeyUseWith and fill the fields. */
115     keyUseWith = (xmlSecKeyUseWithPtr)xmlMalloc(sizeof(xmlSecKeyUseWith));
116     if(keyUseWith == NULL) {
117         xmlSecMallocError(sizeof(xmlSecKeyUseWith), NULL);
118         return(NULL);
119     }
120     memset(keyUseWith, 0, sizeof(xmlSecKeyUseWith));
121 
122     ret = xmlSecKeyUseWithInitialize(keyUseWith);
123     if(ret < 0) {
124         xmlSecInternalError("xmlSecKeyUseWithInitialize", NULL);
125         xmlSecKeyUseWithDestroy(keyUseWith);
126         return(NULL);
127     }
128 
129     ret = xmlSecKeyUseWithSet(keyUseWith, application, identifier);
130     if(ret < 0) {
131         xmlSecInternalError("xmlSecKeyUseWithSet", NULL);
132         xmlSecKeyUseWithDestroy(keyUseWith);
133         return(NULL);
134     }
135 
136     return(keyUseWith);
137 }
138 
139 /**
140  * xmlSecKeyUseWithDuplicate:
141  * @keyUseWith:         the pointer to information about key application/user.
142  *
143  * Duplicates @keyUseWith object. The caller is responsible for destroying
144  * returned object with @xmlSecKeyUseWithDestroy function.
145  *
146  * Returns: pointer to newly created object or NULL if an error occurs.
147  */
148 xmlSecKeyUseWithPtr
xmlSecKeyUseWithDuplicate(xmlSecKeyUseWithPtr keyUseWith)149 xmlSecKeyUseWithDuplicate(xmlSecKeyUseWithPtr keyUseWith) {
150     int ret;
151 
152     xmlSecKeyUseWithPtr newKeyUseWith;
153 
154     xmlSecAssert2(keyUseWith != NULL, NULL);
155 
156     newKeyUseWith = xmlSecKeyUseWithCreate(NULL, NULL);
157     if(newKeyUseWith == NULL) {
158         xmlSecInternalError("xmlSecKeyUseWithCreate", NULL);
159         return(NULL);
160     }
161 
162     ret = xmlSecKeyUseWithCopy(newKeyUseWith, keyUseWith);
163     if(ret < 0) {
164         xmlSecInternalError("xmlSecKeyUseWithCopy", NULL);
165         xmlSecKeyUseWithDestroy(keyUseWith);
166         return(NULL);
167     }
168 
169     return(newKeyUseWith);
170 }
171 
172 /**
173  * xmlSecKeyUseWithDestroy:
174  * @keyUseWith:         the pointer to information about key application/user.
175  *
176  * Destroys @keyUseWith created with @xmlSecKeyUseWithCreate or @xmlSecKeyUseWithDuplicate
177  * functions.
178  */
179 void
xmlSecKeyUseWithDestroy(xmlSecKeyUseWithPtr keyUseWith)180 xmlSecKeyUseWithDestroy(xmlSecKeyUseWithPtr keyUseWith) {
181     xmlSecAssert(keyUseWith != NULL);
182 
183     xmlSecKeyUseWithFinalize(keyUseWith);
184     xmlFree(keyUseWith);
185 }
186 
187 /**
188  * xmlSecKeyUseWithSet:
189  * @keyUseWith:         the pointer to information about key application/user.
190  * @application:        the new application value.
191  * @identifier:         the new identifier value.
192  *
193  * Sets @application and @identifier in the @keyUseWith.
194  *
195  * Returns: 0 on success or a negative value if an error occurs.
196  */
197 int
xmlSecKeyUseWithSet(xmlSecKeyUseWithPtr keyUseWith,const xmlChar * application,const xmlChar * identifier)198 xmlSecKeyUseWithSet(xmlSecKeyUseWithPtr keyUseWith, const xmlChar* application, const xmlChar* identifier) {
199     xmlSecAssert2(keyUseWith != NULL, -1);
200 
201     if(keyUseWith->application != NULL) {
202         xmlFree(keyUseWith->application);
203         keyUseWith->application = NULL;
204     }
205     if(keyUseWith->identifier != NULL) {
206         xmlFree(keyUseWith->identifier);
207         keyUseWith->identifier = NULL;
208     }
209 
210     if(application != NULL) {
211         keyUseWith->application = xmlStrdup(application);
212         if(keyUseWith->application == NULL) {
213             xmlSecStrdupError(application, NULL);
214             return(-1);
215         }
216     }
217     if(identifier != NULL) {
218         keyUseWith->identifier = xmlStrdup(identifier);
219         if(keyUseWith->identifier == NULL) {
220             xmlSecStrdupError(identifier, NULL);
221             return(-1);
222         }
223     }
224 
225     return(0);
226 }
227 
228 /**
229  * xmlSecKeyUseWithDebugDump:
230  * @keyUseWith:         the pointer to information about key application/user.
231  * @output:             the pointer to output FILE.
232  *
233  * Prints xmlSecKeyUseWith debug information to a file @output.
234  */
235 void
xmlSecKeyUseWithDebugDump(xmlSecKeyUseWithPtr keyUseWith,FILE * output)236 xmlSecKeyUseWithDebugDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
237     xmlSecAssert(keyUseWith != NULL);
238     xmlSecAssert(output != NULL);
239 
240     fprintf(output, "=== KeyUseWith: application=\"%s\",identifier=\"%s\"\n",
241                 (keyUseWith->application) ? keyUseWith->application : BAD_CAST "",
242                 (keyUseWith->identifier) ? keyUseWith->identifier : BAD_CAST "");
243 }
244 
245 /**
246  * xmlSecKeyUseWithDebugXmlDump:
247  * @keyUseWith:         the pointer to information about key application/user.
248  * @output:             the pointer to output FILE.
249  *
250  * Prints xmlSecKeyUseWith debug information to a file @output in XML format.
251  */
252 void
xmlSecKeyUseWithDebugXmlDump(xmlSecKeyUseWithPtr keyUseWith,FILE * output)253 xmlSecKeyUseWithDebugXmlDump(xmlSecKeyUseWithPtr keyUseWith, FILE* output) {
254     xmlSecAssert(keyUseWith != NULL);
255     xmlSecAssert(output != NULL);
256 
257     fprintf(output, "<KeyUseWith>\n");
258 
259     fprintf(output, "<Application>");
260     xmlSecPrintXmlString(output, keyUseWith->application);
261     fprintf(output, "</Application>");
262 
263     fprintf(output, "<Identifier>");
264     xmlSecPrintXmlString(output, keyUseWith->identifier);
265     fprintf(output, "</Identifier>");
266 
267     fprintf(output, "</KeyUseWith>\n");
268 }
269 
270 /***********************************************************************
271  *
272  * KeyUseWith list
273  *
274  **********************************************************************/
275 static xmlSecPtrListKlass xmlSecKeyUseWithPtrListKlass = {
276     BAD_CAST "key-use-with-list",
277     (xmlSecPtrDuplicateItemMethod)xmlSecKeyUseWithDuplicate,    /* xmlSecPtrDuplicateItemMethod duplicateItem; */
278     (xmlSecPtrDestroyItemMethod)xmlSecKeyUseWithDestroy,        /* xmlSecPtrDestroyItemMethod destroyItem; */
279     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugDump,    /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
280     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyUseWithDebugXmlDump, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
281 };
282 
283 /**
284  * xmlSecKeyUseWithPtrListGetKlass:
285  *
286  * The key data list klass.
287  *
288  * Returns: pointer to the key data list klass.
289  */
290 xmlSecPtrListId
xmlSecKeyUseWithPtrListGetKlass(void)291 xmlSecKeyUseWithPtrListGetKlass(void) {
292     return(&xmlSecKeyUseWithPtrListKlass);
293 }
294 
295 /**************************************************************************
296  *
297  * xmlSecKeyReq - what key are we looking for?
298  *
299  *************************************************************************/
300 /**
301  * xmlSecKeyReqInitialize:
302  * @keyReq:             the pointer to key requirements object.
303  *
304  * Initialize key requirements object. Caller is responsible for
305  * cleaning it with #xmlSecKeyReqFinalize function.
306  *
307  * Returns: 0 on success or a negative value if an error occurs.
308  */
309 int
xmlSecKeyReqInitialize(xmlSecKeyReqPtr keyReq)310 xmlSecKeyReqInitialize(xmlSecKeyReqPtr keyReq) {
311     int ret;
312 
313     xmlSecAssert2(keyReq != NULL, -1);
314 
315     memset(keyReq, 0, sizeof(xmlSecKeyReq));
316 
317     keyReq->keyUsage    = xmlSecKeyUsageAny;    /* by default you can do whatever you want with the key */
318     ret = xmlSecPtrListInitialize(&keyReq->keyUseWithList, xmlSecKeyUseWithPtrListId);
319     if(ret < 0) {
320         xmlSecInternalError("xmlSecPtrListInitialize", NULL);
321         return(-1);
322     }
323 
324 
325     return(0);
326 }
327 
328 /**
329  * xmlSecKeyReqFinalize:
330  * @keyReq:             the pointer to key requirements object.
331  *
332  * Cleans the key requirements object initialized with #xmlSecKeyReqInitialize
333  * function.
334  */
335 void
xmlSecKeyReqFinalize(xmlSecKeyReqPtr keyReq)336 xmlSecKeyReqFinalize(xmlSecKeyReqPtr keyReq) {
337     xmlSecAssert(keyReq != NULL);
338 
339     xmlSecPtrListFinalize(&keyReq->keyUseWithList);
340     memset(keyReq, 0, sizeof(xmlSecKeyReq));
341 }
342 
343 /**
344  * xmlSecKeyReqReset:
345  * @keyReq:             the pointer to key requirements object.
346  *
347  * Resets key requirements object for new key search.
348  */
349 void
xmlSecKeyReqReset(xmlSecKeyReqPtr keyReq)350 xmlSecKeyReqReset(xmlSecKeyReqPtr keyReq) {
351     xmlSecAssert(keyReq != NULL);
352 
353     xmlSecPtrListEmpty(&keyReq->keyUseWithList);
354     keyReq->keyId       = NULL;
355     keyReq->keyType     = 0;
356     keyReq->keyUsage    = xmlSecKeyUsageAny;
357     keyReq->keyBitsSize = 0;
358 }
359 
360 /**
361  * xmlSecKeyReqCopy:
362  * @dst:                the pointer to destination object.
363  * @src:                the pointer to source object.
364  *
365  * Copies key requirements from @src object to @dst object.
366  *
367  * Returns: 0 on success and a negative value if an error occurs.
368  */
369 int
xmlSecKeyReqCopy(xmlSecKeyReqPtr dst,xmlSecKeyReqPtr src)370 xmlSecKeyReqCopy(xmlSecKeyReqPtr dst, xmlSecKeyReqPtr src) {
371     int ret;
372 
373     xmlSecAssert2(dst != NULL, -1);
374     xmlSecAssert2(src != NULL, -1);
375 
376     dst->keyId          = src->keyId;
377     dst->keyType        = src->keyType;
378     dst->keyUsage       = src->keyUsage;
379     dst->keyBitsSize    = src->keyBitsSize;
380 
381     ret = xmlSecPtrListCopy(&dst->keyUseWithList, &src->keyUseWithList);
382     if(ret < 0) {
383         xmlSecInternalError("xmlSecPtrListCopy", NULL);
384         return(-1);
385     }
386 
387     return(0);
388 }
389 
390 /**
391  * xmlSecKeyReqMatchKey:
392  * @keyReq:             the pointer to key requirements object.
393  * @key:                the pointer to key.
394  *
395  * Checks whether @key matches key requirements @keyReq.
396  *
397  * Returns: 1 if key matches requirements, 0 if not and a negative value
398  * if an error occurs.
399  */
400 int
xmlSecKeyReqMatchKey(xmlSecKeyReqPtr keyReq,xmlSecKeyPtr key)401 xmlSecKeyReqMatchKey(xmlSecKeyReqPtr keyReq, xmlSecKeyPtr key) {
402     xmlSecAssert2(keyReq != NULL, -1);
403     xmlSecAssert2(xmlSecKeyIsValid(key), -1);
404 
405     if((keyReq->keyType != xmlSecKeyDataTypeUnknown) && ((xmlSecKeyGetType(key) & keyReq->keyType) == 0)) {
406          return(0);
407     }
408     if((keyReq->keyUsage != xmlSecKeyDataUsageUnknown) && ((keyReq->keyUsage & key->usage) == 0)) {
409         return(0);
410     }
411 
412     return(xmlSecKeyReqMatchKeyValue(keyReq, xmlSecKeyGetValue(key)));
413 }
414 
415 /**
416  * xmlSecKeyReqMatchKeyValue:
417  * @keyReq:             the pointer to key requirements.
418  * @value:              the pointer to key value.
419  *
420  * Checks whether @keyValue matches key requirements @keyReq.
421  *
422  * Returns: 1 if key value matches requirements, 0 if not and a negative value
423  * if an error occurs.
424  */
425 int
xmlSecKeyReqMatchKeyValue(xmlSecKeyReqPtr keyReq,xmlSecKeyDataPtr value)426 xmlSecKeyReqMatchKeyValue(xmlSecKeyReqPtr keyReq, xmlSecKeyDataPtr value) {
427     xmlSecAssert2(keyReq != NULL, -1);
428     xmlSecAssert2(value != NULL, -1);
429 
430     if((keyReq->keyId != xmlSecKeyDataIdUnknown) &&
431        (!xmlSecKeyDataCheckId(value, keyReq->keyId))) {
432 
433         return(0);
434     }
435     if((keyReq->keyBitsSize > 0) &&
436        (xmlSecKeyDataGetSize(value) > 0) &&
437        (xmlSecKeyDataGetSize(value) < keyReq->keyBitsSize)) {
438 
439         return(0);
440     }
441     return(1);
442 }
443 
444 /**
445  * xmlSecKeyReqDebugDump:
446  * @keyReq:             the pointer to key requirements object.
447  * @output:             the pointer to output FILE.
448  *
449  * Prints debug information about @keyReq into @output.
450  */
451 void
xmlSecKeyReqDebugDump(xmlSecKeyReqPtr keyReq,FILE * output)452 xmlSecKeyReqDebugDump(xmlSecKeyReqPtr keyReq, FILE* output) {
453     xmlSecAssert(keyReq != NULL);
454     xmlSecAssert(output != NULL);
455 
456     fprintf(output, "=== KeyReq:\n");
457     fprintf(output, "==== keyId: %s\n",
458             (xmlSecKeyDataKlassGetName(keyReq->keyId)) ?
459                 xmlSecKeyDataKlassGetName(keyReq->keyId) :
460                 BAD_CAST "NULL");
461     fprintf(output, "==== keyType: 0x%08x\n", keyReq->keyType);
462     fprintf(output, "==== keyUsage: 0x%08x\n", keyReq->keyUsage);
463     fprintf(output, "==== keyBitsSize: %d\n", keyReq->keyBitsSize);
464     xmlSecPtrListDebugDump(&(keyReq->keyUseWithList), output);
465 }
466 
467 /**
468  * xmlSecKeyReqDebugXmlDump:
469  * @keyReq:             the pointer to key requirements object.
470  * @output:             the pointer to output FILE.
471  *
472  * Prints debug information about @keyReq into @output in XML format.
473  */
474 void
xmlSecKeyReqDebugXmlDump(xmlSecKeyReqPtr keyReq,FILE * output)475 xmlSecKeyReqDebugXmlDump(xmlSecKeyReqPtr keyReq, FILE* output) {
476     xmlSecAssert(keyReq != NULL);
477     xmlSecAssert(output != NULL);
478 
479     fprintf(output, "<KeyReq>\n");
480 
481     fprintf(output, "<KeyId>");
482     xmlSecPrintXmlString(output, xmlSecKeyDataKlassGetName(keyReq->keyId));
483     fprintf(output, "</KeyId>\n");
484 
485     fprintf(output, "<KeyType>0x%08x</KeyType>\n", keyReq->keyType);
486     fprintf(output, "<KeyUsage>0x%08x</KeyUsage>\n", keyReq->keyUsage);
487     fprintf(output, "<KeyBitsSize>%d</KeyBitsSize>\n", keyReq->keyBitsSize);
488     xmlSecPtrListDebugXmlDump(&(keyReq->keyUseWithList), output);
489     fprintf(output, "</KeyReq>\n");
490 }
491 
492 
493 /**************************************************************************
494  *
495  * xmlSecKey
496  *
497  *************************************************************************/
498 /**
499  * xmlSecKeyCreate:
500  *
501  * Allocates and initializes new key. Caller is responsible for
502  * freeing returned object with #xmlSecKeyDestroy function.
503  *
504  * Returns: the pointer to newly allocated @xmlSecKey structure
505  * or NULL if an error occurs.
506  */
507 xmlSecKeyPtr
xmlSecKeyCreate(void)508 xmlSecKeyCreate(void)  {
509     xmlSecKeyPtr key;
510 
511     /* Allocate a new xmlSecKey and fill the fields. */
512     key = (xmlSecKeyPtr)xmlMalloc(sizeof(xmlSecKey));
513     if(key == NULL) {
514         xmlSecMallocError(sizeof(xmlSecKey), NULL);
515         return(NULL);
516     }
517     memset(key, 0, sizeof(xmlSecKey));
518     key->usage = xmlSecKeyUsageAny;
519     return(key);
520 }
521 
522 /**
523  * xmlSecKeyEmpty:
524  * @key:                the pointer to key.
525  *
526  * Clears the @key data.
527  */
528 void
xmlSecKeyEmpty(xmlSecKeyPtr key)529 xmlSecKeyEmpty(xmlSecKeyPtr key) {
530     xmlSecAssert(key != NULL);
531 
532     if(key->value != NULL) {
533         xmlSecKeyDataDestroy(key->value);
534     }
535     if(key->name != NULL) {
536         xmlFree(key->name);
537     }
538     if(key->dataList != NULL) {
539         xmlSecPtrListDestroy(key->dataList);
540     }
541 
542     memset(key, 0, sizeof(xmlSecKey));
543 }
544 
545 /**
546  * xmlSecKeyDestroy:
547  * @key:                the pointer to key.
548  *
549  * Destroys the key created using #xmlSecKeyCreate function.
550  */
551 void
xmlSecKeyDestroy(xmlSecKeyPtr key)552 xmlSecKeyDestroy(xmlSecKeyPtr key) {
553     xmlSecAssert(key != NULL);
554 
555     xmlSecKeyEmpty(key);
556     xmlFree(key);
557 }
558 
559 /**
560  * xmlSecKeyCopy:
561  * @keyDst:             the destination key.
562  * @keySrc:             the source key.
563  *
564  * Copies key data from @keySrc to @keyDst.
565  *
566  * Returns: 0 on success or a negative value if an error occurs.
567  */
568 int
xmlSecKeyCopy(xmlSecKeyPtr keyDst,xmlSecKeyPtr keySrc)569 xmlSecKeyCopy(xmlSecKeyPtr keyDst, xmlSecKeyPtr keySrc) {
570     xmlSecAssert2(keyDst != NULL, -1);
571     xmlSecAssert2(keySrc != NULL, -1);
572 
573     /* empty destination */
574     xmlSecKeyEmpty(keyDst);
575 
576     /* copy everything */
577     if(keySrc->name != NULL) {
578         keyDst->name = xmlStrdup(keySrc->name);
579         if(keyDst->name == NULL) {
580             xmlSecStrdupError(keySrc->name, NULL);
581             return(-1);
582         }
583     }
584 
585     if(keySrc->value != NULL) {
586         keyDst->value = xmlSecKeyDataDuplicate(keySrc->value);
587         if(keyDst->value == NULL) {
588             xmlSecInternalError("xmlSecKeyDataDuplicate", NULL);
589             return(-1);
590         }
591     }
592 
593     if(keySrc->dataList != NULL) {
594         keyDst->dataList = xmlSecPtrListDuplicate(keySrc->dataList);
595         if(keyDst->dataList == NULL) {
596             xmlSecInternalError("xmlSecPtrListDuplicate", NULL);
597             return(-1);
598         }
599     }
600 
601     keyDst->usage          = keySrc->usage;
602     keyDst->notValidBefore = keySrc->notValidBefore;
603     keyDst->notValidAfter  = keySrc->notValidAfter;
604     return(0);
605 }
606 
607 /**
608  * xmlSecKeyDuplicate:
609  * @key:                the pointer to the #xmlSecKey structure.
610  *
611  * Creates a duplicate of the given @key.
612  *
613  * Returns: the pointer to newly allocated #xmlSecKey structure
614  * or NULL if an error occurs.
615  */
616 xmlSecKeyPtr
xmlSecKeyDuplicate(xmlSecKeyPtr key)617 xmlSecKeyDuplicate(xmlSecKeyPtr key) {
618     xmlSecKeyPtr newKey;
619     int ret;
620 
621     xmlSecAssert2(key != NULL, NULL);
622 
623     newKey = xmlSecKeyCreate();
624     if(newKey == NULL) {
625         xmlSecInternalError("xmlSecKeyCreate", NULL);
626         return(NULL);
627     }
628 
629     ret = xmlSecKeyCopy(newKey, key);
630     if(ret < 0) {
631         xmlSecInternalError("xmlSecKeyCopy", NULL);
632         xmlSecKeyDestroy(newKey);
633         return(NULL);
634     }
635 
636     return(newKey);
637 }
638 
639 /**
640  * xmlSecKeyMatch:
641  * @key:                the pointer to key.
642  * @name:               the pointer to key name (may be NULL).
643  * @keyReq:             the pointer to key requirements.
644  *
645  * Checks whether the @key matches the given criteria.
646  *
647  * Returns: 1 if the key satisfies the given criteria or 0 otherwise.
648  */
649 int
xmlSecKeyMatch(xmlSecKeyPtr key,const xmlChar * name,xmlSecKeyReqPtr keyReq)650 xmlSecKeyMatch(xmlSecKeyPtr key, const xmlChar *name, xmlSecKeyReqPtr keyReq) {
651     xmlSecAssert2(xmlSecKeyIsValid(key), -1);
652     xmlSecAssert2(keyReq != NULL, -1);
653 
654     if((name != NULL) && (!xmlStrEqual(xmlSecKeyGetName(key), name))) {
655         return(0);
656     }
657     return(xmlSecKeyReqMatchKey(keyReq, key));
658 }
659 
660 /**
661  * xmlSecKeyGetType:
662  * @key:                the pointer to key.
663  *
664  * Gets @key type.
665  *
666  * Returns: key type.
667  */
668 xmlSecKeyDataType
xmlSecKeyGetType(xmlSecKeyPtr key)669 xmlSecKeyGetType(xmlSecKeyPtr key) {
670     xmlSecKeyDataPtr data;
671 
672     xmlSecAssert2(key != NULL, xmlSecKeyDataTypeUnknown);
673 
674     data = xmlSecKeyGetValue(key);
675     if(data == NULL) {
676         return(xmlSecKeyDataTypeUnknown);
677     }
678     return(xmlSecKeyDataGetType(data));
679 }
680 
681 /**
682  * xmlSecKeyGetName:
683  * @key:                the pointer to key.
684  *
685  * Gets key name (see also #xmlSecKeySetName function).
686  *
687  * Returns: key name.
688  */
689 const xmlChar*
xmlSecKeyGetName(xmlSecKeyPtr key)690 xmlSecKeyGetName(xmlSecKeyPtr key) {
691     xmlSecAssert2(key != NULL, NULL);
692 
693     return(key->name);
694 }
695 
696 /**
697  * xmlSecKeySetName:
698  * @key:                the pointer to key.
699  * @name:               the new key name.
700  *
701  * Sets key name (see also #xmlSecKeyGetName function).
702  *
703  * Returns: 0 on success or a negative value if an error occurs.
704  */
705 int
xmlSecKeySetName(xmlSecKeyPtr key,const xmlChar * name)706 xmlSecKeySetName(xmlSecKeyPtr key, const xmlChar* name) {
707     xmlSecAssert2(key != NULL, -1);
708 
709     if(key->name != NULL) {
710         xmlFree(key->name);
711         key->name = NULL;
712     }
713 
714     if(name != NULL) {
715         key->name = xmlStrdup(name);
716         if(key->name == NULL) {
717             xmlSecStrdupError(name, NULL);
718             return(-1);
719         }
720     }
721 
722     return(0);
723 }
724 
725 /**
726  * xmlSecKeyGetValue:
727  * @key:                the pointer to key.
728  *
729  * Gets key value (see also #xmlSecKeySetValue function).
730  *
731  * Returns: key value (crypto material).
732  */
733 xmlSecKeyDataPtr
xmlSecKeyGetValue(xmlSecKeyPtr key)734 xmlSecKeyGetValue(xmlSecKeyPtr key) {
735     xmlSecAssert2(key != NULL, NULL);
736 
737     return(key->value);
738 }
739 
740 /**
741  * xmlSecKeySetValue:
742  * @key:                the pointer to key.
743  * @value:              the new value.
744  *
745  * Sets key value (see also #xmlSecKeyGetValue function).
746  *
747  * Returns: 0 on success or a negative value if an error occurs.
748  */
749 int
xmlSecKeySetValue(xmlSecKeyPtr key,xmlSecKeyDataPtr value)750 xmlSecKeySetValue(xmlSecKeyPtr key, xmlSecKeyDataPtr value) {
751     xmlSecAssert2(key != NULL, -1);
752 
753     if(key->value != NULL) {
754         xmlSecKeyDataDestroy(key->value);
755         key->value = NULL;
756     }
757     key->value = value;
758 
759     return(0);
760 }
761 
762 /**
763  * xmlSecKeyGetData:
764  * @key:                the pointer to key.
765  * @dataId:             the requested data klass.
766  *
767  * Gets key's data.
768  *
769  * Returns: additional data associated with the @key (see also
770  * #xmlSecKeyAdoptData function).
771  */
772 xmlSecKeyDataPtr
xmlSecKeyGetData(xmlSecKeyPtr key,xmlSecKeyDataId dataId)773 xmlSecKeyGetData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
774 
775     xmlSecAssert2(key != NULL, NULL);
776     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
777 
778     /* special cases */
779     if(dataId == xmlSecKeyDataValueId) {
780         return(key->value);
781     } else if(key->dataList != NULL) {
782         xmlSecKeyDataPtr tmp;
783         xmlSecSize pos, size;
784 
785         size = xmlSecPtrListGetSize(key->dataList);
786         for(pos = 0; pos < size; ++pos) {
787             tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
788             if((tmp != NULL) && (tmp->id == dataId)) {
789                 return(tmp);
790             }
791         }
792     }
793     return(NULL);
794 }
795 
796 /**
797  * xmlSecKeyEnsureData:
798  * @key:                the pointer to key.
799  * @dataId:             the requested data klass.
800  *
801  * If necessary, creates key data of @dataId klass and adds to @key.
802  *
803  * Returns: pointer to key data or NULL if an error occurs.
804  */
805 xmlSecKeyDataPtr
xmlSecKeyEnsureData(xmlSecKeyPtr key,xmlSecKeyDataId dataId)806 xmlSecKeyEnsureData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) {
807     xmlSecKeyDataPtr data;
808     int ret;
809 
810     xmlSecAssert2(key != NULL, NULL);
811     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
812 
813     data = xmlSecKeyGetData(key, dataId);
814     if(data != NULL) {
815         return(data);
816     }
817 
818     data = xmlSecKeyDataCreate(dataId);
819     if(data == NULL) {
820         xmlSecInternalError2("xmlSecKeyDataCreate", NULL,
821                              "dataId=%s",
822                              xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
823         return(NULL);
824     }
825 
826     ret = xmlSecKeyAdoptData(key, data);
827     if(ret < 0) {
828         xmlSecInternalError2("xmlSecKeyAdoptData", NULL,
829                              "dataId=%s",
830                              xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)));
831         xmlSecKeyDataDestroy(data);
832         return(NULL);
833     }
834 
835     return(data);
836 }
837 
838 /**
839  * xmlSecKeyAdoptData:
840  * @key:                the pointer to key.
841  * @data:               the pointer to key data.
842  *
843  * Adds @data to the @key. The @data object will be destroyed
844  * by @key.
845  *
846  * Returns: 0 on success or a negative value otherwise.
847  */
848 int
xmlSecKeyAdoptData(xmlSecKeyPtr key,xmlSecKeyDataPtr data)849 xmlSecKeyAdoptData(xmlSecKeyPtr key, xmlSecKeyDataPtr data) {
850     xmlSecKeyDataPtr tmp;
851     xmlSecSize pos, size;
852 
853     xmlSecAssert2(key != NULL, -1);
854     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
855 
856     /* special cases */
857     if(data->id == xmlSecKeyDataValueId) {
858         if(key->value != NULL) {
859             xmlSecKeyDataDestroy(key->value);
860         }
861         key->value = data;
862         return(0);
863     }
864 
865     if(key->dataList == NULL) {
866         key->dataList = xmlSecPtrListCreate(xmlSecKeyDataListId);
867         if(key->dataList == NULL) {
868             xmlSecInternalError("xmlSecPtrListCreate", NULL);
869             return(-1);
870         }
871     }
872 
873 
874     size = xmlSecPtrListGetSize(key->dataList);
875     for(pos = 0; pos < size; ++pos) {
876         tmp = (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, pos);
877         if((tmp != NULL) && (tmp->id == data->id)) {
878             return(xmlSecPtrListSet(key->dataList, data, pos));
879         }
880     }
881 
882     return(xmlSecPtrListAdd(key->dataList, data));
883 }
884 
885 /**
886  * xmlSecKeyDebugDump:
887  * @key:                the pointer to key.
888  * @output:             the pointer to output FILE.
889  *
890  * Prints the information about the @key to the @output.
891  */
892 void
xmlSecKeyDebugDump(xmlSecKeyPtr key,FILE * output)893 xmlSecKeyDebugDump(xmlSecKeyPtr key, FILE *output) {
894     xmlSecAssert(xmlSecKeyIsValid(key));
895     xmlSecAssert(output != NULL);
896 
897     fprintf(output, "== KEY\n");
898     fprintf(output, "=== method: %s\n",
899             (key->value->id->dataNodeName != NULL) ?
900             (char*)(key->value->id->dataNodeName) : "NULL");
901 
902     fprintf(output, "=== key type: ");
903     if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
904         fprintf(output, "Symmetric\n");
905     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
906         fprintf(output, "Private\n");
907     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
908         fprintf(output, "Public\n");
909     } else {
910         fprintf(output, "Unknown\n");
911     }
912 
913     if(key->name != NULL) {
914         fprintf(output, "=== key name: %s\n", key->name);
915     }
916     fprintf(output, "=== key usage: %d\n", key->usage);
917     if(key->notValidBefore < key->notValidAfter) {
918         fprintf(output, "=== key not valid before: %ld\n", (unsigned long)key->notValidBefore);
919         fprintf(output, "=== key not valid after: %ld\n", (unsigned long)key->notValidAfter);
920     }
921     if(key->value != NULL) {
922         xmlSecKeyDataDebugDump(key->value, output);
923     }
924     if(key->dataList != NULL) {
925         xmlSecPtrListDebugDump(key->dataList, output);
926     }
927 }
928 
929 /**
930  * xmlSecKeyDebugXmlDump:
931  * @key:                the pointer to key.
932  * @output:             the pointer to output FILE.
933  *
934  * Prints the information about the @key to the @output in XML format.
935  */
936 void
xmlSecKeyDebugXmlDump(xmlSecKeyPtr key,FILE * output)937 xmlSecKeyDebugXmlDump(xmlSecKeyPtr key, FILE *output) {
938     xmlSecAssert(xmlSecKeyIsValid(key));
939     xmlSecAssert(output != NULL);
940 
941     fprintf(output, "<KeyInfo>\n");
942 
943     fprintf(output, "<KeyMethod>");
944     xmlSecPrintXmlString(output, key->value->id->dataNodeName);
945     fprintf(output, "</KeyMethod>\n");
946 
947     fprintf(output, "<KeyType>");
948     if((xmlSecKeyGetType(key) & xmlSecKeyDataTypeSymmetric) != 0) {
949         fprintf(output, "Symmetric\n");
950     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePrivate) != 0) {
951         fprintf(output, "Private\n");
952     } else if((xmlSecKeyGetType(key) & xmlSecKeyDataTypePublic) != 0) {
953         fprintf(output, "Public\n");
954     } else {
955         fprintf(output, "Unknown\n");
956     }
957     fprintf(output, "</KeyType>\n");
958 
959     fprintf(output, "<KeyName>");
960     xmlSecPrintXmlString(output, key->name);
961     fprintf(output, "</KeyName>\n");
962 
963     if(key->notValidBefore < key->notValidAfter) {
964         fprintf(output, "<KeyValidity notValidBefore=\"%ld\" notValidAfter=\"%ld\"/>\n",
965                 (unsigned long)key->notValidBefore,
966                 (unsigned long)key->notValidAfter);
967     }
968 
969     if(key->value != NULL) {
970         xmlSecKeyDataDebugXmlDump(key->value, output);
971     }
972     if(key->dataList != NULL) {
973         xmlSecPtrListDebugXmlDump(key->dataList, output);
974     }
975 
976     fprintf(output, "</KeyInfo>\n");
977 }
978 
979 /**
980  * xmlSecKeyGenerate:
981  * @dataId:             the requested key klass (rsa, dsa, aes, ...).
982  * @sizeBits:           the new key size (in bits!).
983  * @type:               the new key type (session, permanent, ...).
984  *
985  * Generates new key of requested klass @dataId and @type.
986  *
987  * Returns: pointer to newly created key or NULL if an error occurs.
988  */
989 xmlSecKeyPtr
xmlSecKeyGenerate(xmlSecKeyDataId dataId,xmlSecSize sizeBits,xmlSecKeyDataType type)990 xmlSecKeyGenerate(xmlSecKeyDataId dataId, xmlSecSize sizeBits, xmlSecKeyDataType type) {
991     xmlSecKeyPtr key;
992     xmlSecKeyDataPtr data;
993     int ret;
994 
995     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
996 
997     data = xmlSecKeyDataCreate(dataId);
998     if(data == NULL) {
999         xmlSecInternalError("xmlSecKeyDataCreate",
1000                             xmlSecKeyDataKlassGetName(dataId));
1001         return(NULL);
1002     }
1003 
1004     ret = xmlSecKeyDataGenerate(data, sizeBits, type);
1005     if(ret < 0) {
1006         xmlSecInternalError3("xmlSecKeyDataGenerate",
1007                              xmlSecKeyDataKlassGetName(dataId),
1008                              "size=%d;type=%d", sizeBits, type);
1009         xmlSecKeyDataDestroy(data);
1010         return(NULL);
1011     }
1012 
1013     key = xmlSecKeyCreate();
1014     if(key == NULL) {
1015         xmlSecInternalError("xmlSecKeyCreate",
1016                             xmlSecKeyDataKlassGetName(dataId));
1017         xmlSecKeyDataDestroy(data);
1018         return(NULL);
1019     }
1020 
1021     ret = xmlSecKeySetValue(key, data);
1022     if(ret < 0) {
1023         xmlSecInternalError("xmlSecKeySetValue",
1024                             xmlSecKeyDataKlassGetName(dataId));
1025         xmlSecKeyDataDestroy(data);
1026         xmlSecKeyDestroy(key);
1027         return(NULL);
1028     }
1029 
1030     return(key);
1031 }
1032 
1033 /**
1034  * xmlSecKeyGenerateByName:
1035  * @name:               the requested key klass name (rsa, dsa, aes, ...).
1036  * @sizeBits:           the new key size (in bits!).
1037  * @type:               the new key type (session, permanent, ...).
1038  *
1039  * Generates new key of requested @klass and @type.
1040  *
1041  * Returns: pointer to newly created key or NULL if an error occurs.
1042  */
1043 xmlSecKeyPtr
xmlSecKeyGenerateByName(const xmlChar * name,xmlSecSize sizeBits,xmlSecKeyDataType type)1044 xmlSecKeyGenerateByName(const xmlChar* name, xmlSecSize sizeBits, xmlSecKeyDataType type) {
1045     xmlSecKeyDataId dataId;
1046 
1047     xmlSecAssert2(name != NULL, NULL);
1048 
1049     dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), name, xmlSecKeyDataUsageAny);
1050     if(dataId == xmlSecKeyDataIdUnknown) {
1051         xmlSecOtherError(XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND, name, NULL);
1052         return(NULL);
1053     }
1054 
1055     return(xmlSecKeyGenerate(dataId, sizeBits, type));
1056 }
1057 
1058 /**
1059  * xmlSecKeyReadBuffer:
1060  * @dataId:             the key value data klass.
1061  * @buffer:             the buffer that contains the binary data.
1062  *
1063  * Reads the key value of klass @dataId from a buffer.
1064  *
1065  * Returns: pointer to newly created key or NULL if an error occurs.
1066  */
1067 xmlSecKeyPtr
xmlSecKeyReadBuffer(xmlSecKeyDataId dataId,xmlSecBuffer * buffer)1068 xmlSecKeyReadBuffer(xmlSecKeyDataId dataId, xmlSecBuffer* buffer) {
1069     xmlSecKeyInfoCtx keyInfoCtx;
1070     xmlSecKeyPtr key;
1071     int ret;
1072 
1073     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1074     xmlSecAssert2(buffer != NULL, NULL);
1075 
1076     /* create key data */
1077     key = xmlSecKeyCreate();
1078     if(key == NULL) {
1079         xmlSecInternalError("xmlSecKeyCreate",
1080                             xmlSecKeyDataKlassGetName(dataId));
1081         return(NULL);
1082     }
1083 
1084     ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
1085     if(ret < 0) {
1086         xmlSecInternalError("xmlSecKeyInfoCtxInitialize",
1087                             xmlSecKeyDataKlassGetName(dataId));
1088         xmlSecKeyDestroy(key);
1089         return(NULL);
1090     }
1091 
1092     keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
1093     ret = xmlSecKeyDataBinRead(dataId, key,
1094                         xmlSecBufferGetData(buffer),
1095                         xmlSecBufferGetSize(buffer),
1096                         &keyInfoCtx);
1097     if(ret < 0) {
1098         xmlSecInternalError("xmlSecKeyDataBinRead",
1099                             xmlSecKeyDataKlassGetName(dataId));
1100         xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
1101         xmlSecKeyDestroy(key);
1102         return(NULL);
1103     }
1104     xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
1105 
1106     return(key);
1107 }
1108 
1109 /**
1110  * xmlSecKeyReadBinaryFile:
1111  * @dataId:             the key value data klass.
1112  * @filename:           the key binary filename.
1113  *
1114  * Reads the key value of klass @dataId from a binary file @filename.
1115  *
1116  * Returns: pointer to newly created key or NULL if an error occurs.
1117  */
1118 xmlSecKeyPtr
xmlSecKeyReadBinaryFile(xmlSecKeyDataId dataId,const char * filename)1119 xmlSecKeyReadBinaryFile(xmlSecKeyDataId dataId, const char* filename) {
1120     xmlSecKeyPtr key;
1121     xmlSecBuffer buffer;
1122     int ret;
1123 
1124     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1125     xmlSecAssert2(filename != NULL, NULL);
1126 
1127     /* read file to buffer */
1128     ret = xmlSecBufferInitialize(&buffer, 0);
1129     if(ret < 0) {
1130         xmlSecInternalError("xmlSecBufferInitialize",
1131                             xmlSecKeyDataKlassGetName(dataId));
1132         return(NULL);
1133     }
1134 
1135     ret = xmlSecBufferReadFile(&buffer, filename);
1136     if(ret < 0) {
1137         xmlSecInternalError2("xmlSecBufferReadFile",
1138                              xmlSecKeyDataKlassGetName(dataId),
1139                              "filename=%s",
1140                              xmlSecErrorsSafeString(filename));
1141         xmlSecBufferFinalize(&buffer);
1142         return(NULL);
1143     }
1144 
1145     key = xmlSecKeyReadBuffer(dataId, &buffer);
1146     if(key == NULL) {
1147         xmlSecInternalError2("xmlSecKeyReadBuffer",
1148                              xmlSecKeyDataKlassGetName(dataId),
1149                              "filename=%s",
1150                              xmlSecErrorsSafeString(filename));
1151         xmlSecBufferFinalize(&buffer);
1152         return(NULL);
1153     }
1154 
1155     xmlSecBufferFinalize(&buffer);
1156     return (key);
1157 }
1158 
1159 /**
1160  * xmlSecKeyReadMemory:
1161  * @dataId:             the key value data klass.
1162  * @data:               the memory containing the key
1163  * @dataSize:           the size of the memory block
1164  *
1165  * Reads the key value of klass @dataId from a memory block @data.
1166  *
1167  * Returns: pointer to newly created key or NULL if an error occurs.
1168  */
1169 xmlSecKeyPtr
xmlSecKeyReadMemory(xmlSecKeyDataId dataId,const xmlSecByte * data,xmlSecSize dataSize)1170 xmlSecKeyReadMemory(xmlSecKeyDataId dataId, const xmlSecByte* data, xmlSecSize dataSize) {
1171     xmlSecBuffer buffer;
1172     xmlSecKeyPtr key;
1173     int ret;
1174 
1175     xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL);
1176     xmlSecAssert2(data != NULL, NULL);
1177     xmlSecAssert2(dataSize > 0, NULL);
1178 
1179     /* read file to buffer */
1180     ret = xmlSecBufferInitialize(&buffer, 0);
1181     if(ret < 0) {
1182         xmlSecInternalError("xmlSecBufferInitialize",
1183                             xmlSecKeyDataKlassGetName(dataId));
1184         return(NULL);
1185     }
1186 
1187     if (xmlSecBufferAppend(&buffer, data, dataSize) < 0) {
1188         xmlSecInternalError("xmlSecBufferAppend",
1189                             xmlSecKeyDataKlassGetName(dataId));
1190         xmlSecBufferFinalize(&buffer);
1191         return(NULL);
1192     }
1193 
1194     key = xmlSecKeyReadBuffer(dataId, &buffer);
1195     if(key == NULL) {
1196         xmlSecInternalError("xmlSecKeyReadBuffer",
1197                             xmlSecKeyDataKlassGetName(dataId));
1198         xmlSecBufferFinalize(&buffer);
1199         return(NULL);
1200     }
1201 
1202     xmlSecBufferFinalize(&buffer);
1203     return (key);
1204 }
1205 
1206 /**
1207  * xmlSecKeysMngrGetKey:
1208  * @keyInfoNode:        the pointer to <dsig:KeyInfo/> node.
1209  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> node processing context.
1210  *
1211  * Reads the <dsig:KeyInfo/> node @keyInfoNode and extracts the key.
1212  *
1213  * Returns: the pointer to key or NULL if the key is not found or
1214  * an error occurs.
1215  */
1216 xmlSecKeyPtr
xmlSecKeysMngrGetKey(xmlNodePtr keyInfoNode,xmlSecKeyInfoCtxPtr keyInfoCtx)1217 xmlSecKeysMngrGetKey(xmlNodePtr keyInfoNode, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1218     xmlSecKeyPtr key;
1219     int ret;
1220 
1221     xmlSecAssert2(keyInfoCtx != NULL, NULL);
1222 
1223 
1224     /* first try to read data from <dsig:KeyInfo/> node */
1225     key = xmlSecKeyCreate();
1226     if(key == NULL) {
1227         xmlSecInternalError("xmlSecKeyCreate", NULL);
1228         return(NULL);
1229     }
1230 
1231     if(keyInfoNode != NULL) {
1232         ret = xmlSecKeyInfoNodeRead(keyInfoNode, key, keyInfoCtx);
1233         if(ret < 0) {
1234             xmlSecInternalError2("xmlSecKeyInfoNodeRead",
1235                                  NULL,
1236                                  "node=%s",
1237                                  xmlSecErrorsSafeString(xmlSecNodeGetName(keyInfoNode)));
1238             xmlSecKeyDestroy(key);
1239             return(NULL);
1240         }
1241 
1242         if((xmlSecKeyGetValue(key) != NULL) &&
1243            (xmlSecKeyMatch(key, NULL, &(keyInfoCtx->keyReq)) != 0)) {
1244             return(key);
1245         }
1246     }
1247     xmlSecKeyDestroy(key);
1248 
1249     /* if we have keys manager, try it */
1250     if(keyInfoCtx->keysMngr != NULL) {
1251         key = xmlSecKeysMngrFindKey(keyInfoCtx->keysMngr, NULL, keyInfoCtx);
1252         if(key == NULL) {
1253             xmlSecInternalError("xmlSecKeysMngrFindKey", NULL);
1254             return(NULL);
1255         }
1256         if(xmlSecKeyGetValue(key) != NULL) {
1257             return(key);
1258         }
1259         xmlSecKeyDestroy(key);
1260     }
1261 
1262     xmlSecOtherError(XMLSEC_ERRORS_R_KEY_NOT_FOUND, NULL, NULL);
1263     return(NULL);
1264 }
1265 
1266 /***********************************************************************
1267  *
1268  * Keys list
1269  *
1270  **********************************************************************/
1271 static xmlSecPtrListKlass xmlSecKeyPtrListKlass = {
1272     BAD_CAST "keys-list",
1273     (xmlSecPtrDuplicateItemMethod)xmlSecKeyDuplicate,   /* xmlSecPtrDuplicateItemMethod duplicateItem; */
1274     (xmlSecPtrDestroyItemMethod)xmlSecKeyDestroy,       /* xmlSecPtrDestroyItemMethod destroyItem; */
1275     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugDump,   /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
1276     (xmlSecPtrDebugDumpItemMethod)xmlSecKeyDebugXmlDump,/* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
1277 };
1278 
1279 /**
1280  * xmlSecKeyPtrListGetKlass:
1281  *
1282  * The keys list klass.
1283  *
1284  * Returns: keys list id.
1285  */
1286 xmlSecPtrListId
xmlSecKeyPtrListGetKlass(void)1287 xmlSecKeyPtrListGetKlass(void) {
1288     return(&xmlSecKeyPtrListKlass);
1289 }
1290 
1291