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