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