1 /*
2  * XML Security Library (http://www.aleksey.com/xmlsec).
3  *
4  *
5  * This is free software; see Copyright file in the source
6  * distribution for preciese wording.
7  *
8  * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
9  */
10 /**
11  * SECTION:keysmngr
12  * @Short_description: Keys manager object functions.
13  * @Stability: Stable
14  *
15  */
16 #include "globals.h"
17 
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 
23 #include <libxml/tree.h>
24 #include <libxml/parser.h>
25 
26 #include <xmlsec/xmlsec.h>
27 #include <xmlsec/xmltree.h>
28 #include <xmlsec/list.h>
29 #include <xmlsec/keys.h>
30 #include <xmlsec/transforms.h>
31 #include <xmlsec/keysmngr.h>
32 #include <xmlsec/errors.h>
33 #include <xmlsec/private.h>
34 
35 
36 /****************************************************************************
37  *
38  * Keys Manager
39  *
40  ***************************************************************************/
41 /**
42  * xmlSecKeysMngrCreate:
43  *
44  * Creates new keys manager. Caller is responsible for freeing it with
45  * #xmlSecKeysMngrDestroy function.
46  *
47  * Returns: the pointer to newly allocated keys manager or NULL if
48  * an error occurs.
49  */
50 xmlSecKeysMngrPtr
xmlSecKeysMngrCreate(void)51 xmlSecKeysMngrCreate(void) {
52     xmlSecKeysMngrPtr mngr;
53     int ret;
54 
55     /* Allocate a new xmlSecKeysMngr and fill the fields. */
56     mngr = (xmlSecKeysMngrPtr)xmlMalloc(sizeof(xmlSecKeysMngr));
57     if(mngr == NULL) {
58         xmlSecMallocError(sizeof(xmlSecKeysMngr), NULL);
59         return(NULL);
60     }
61     memset(mngr, 0, sizeof(xmlSecKeysMngr));
62 
63     ret = xmlSecPtrListInitialize(&(mngr->storesList), xmlSecKeyDataStorePtrListId);
64     if(ret < 0) {
65         xmlSecInternalError("xmlSecPtrListInitialize(xmlSecKeyDataStorePtrListId)", NULL);
66         return(NULL);
67     }
68 
69     return(mngr);
70 }
71 
72 /**
73  * xmlSecKeysMngrDestroy:
74  * @mngr:               the pointer to keys manager.
75  *
76  * Destroys keys manager created with #xmlSecKeysMngrCreate function.
77  */
78 void
xmlSecKeysMngrDestroy(xmlSecKeysMngrPtr mngr)79 xmlSecKeysMngrDestroy(xmlSecKeysMngrPtr mngr) {
80     xmlSecAssert(mngr != NULL);
81 
82     /* destroy keys store */
83     if(mngr->keysStore != NULL) {
84         xmlSecKeyStoreDestroy(mngr->keysStore);
85     }
86 
87     /* destroy other data stores */
88     xmlSecPtrListFinalize(&(mngr->storesList));
89 
90     memset(mngr, 0, sizeof(xmlSecKeysMngr));
91     xmlFree(mngr);
92 }
93 
94 /**
95  * xmlSecKeysMngrFindKey:
96  * @mngr:               the pointer to keys manager.
97  * @name:               the desired key name.
98  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> node processing context.
99  *
100  * Lookups key in the keys manager keys store. The caller is responsible
101  * for destroying the returned key using #xmlSecKeyDestroy method.
102  *
103  * Returns: the pointer to a key or NULL if key is not found or an error occurs.
104  */
105 xmlSecKeyPtr
xmlSecKeysMngrFindKey(xmlSecKeysMngrPtr mngr,const xmlChar * name,xmlSecKeyInfoCtxPtr keyInfoCtx)106 xmlSecKeysMngrFindKey(xmlSecKeysMngrPtr mngr, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) {
107     xmlSecKeyStorePtr store;
108 
109     xmlSecAssert2(mngr != NULL, NULL);
110     xmlSecAssert2(keyInfoCtx != NULL, NULL);
111 
112     store = xmlSecKeysMngrGetKeysStore(mngr);
113     if(store == NULL) {
114         /* no store. is it an error? */
115         return(NULL);
116     }
117 
118     return(xmlSecKeyStoreFindKey(store, name, keyInfoCtx));
119 }
120 
121 /**
122  * xmlSecKeysMngrAdoptKeysStore:
123  * @mngr:               the pointer to keys manager.
124  * @store:              the pointer to keys store.
125  *
126  * Adopts keys store in the keys manager @mngr.
127  *
128  * Returns: 0 on success or a negative value if an error occurs.
129  */
130 int
xmlSecKeysMngrAdoptKeysStore(xmlSecKeysMngrPtr mngr,xmlSecKeyStorePtr store)131 xmlSecKeysMngrAdoptKeysStore(xmlSecKeysMngrPtr mngr, xmlSecKeyStorePtr store) {
132     xmlSecAssert2(mngr != NULL, -1);
133     xmlSecAssert2(xmlSecKeyStoreIsValid(store), -1);
134 
135     if(mngr->keysStore != NULL) {
136         xmlSecKeyStoreDestroy(mngr->keysStore);
137     }
138     mngr->keysStore = store;
139 
140     return(0);
141 }
142 
143 /**
144  * xmlSecKeysMngrGetKeysStore:
145  * @mngr:               the pointer to keys manager.
146  *
147  * Gets the keys store.
148  *
149  * Returns: the keys store in the keys manager @mngr or NULL if
150  * there is no store or an error occurs.
151  */
152 xmlSecKeyStorePtr
xmlSecKeysMngrGetKeysStore(xmlSecKeysMngrPtr mngr)153 xmlSecKeysMngrGetKeysStore(xmlSecKeysMngrPtr mngr) {
154     xmlSecAssert2(mngr != NULL, NULL);
155 
156     return(mngr->keysStore);
157 }
158 
159 /**
160  * xmlSecKeysMngrAdoptDataStore:
161  * @mngr:               the pointer to keys manager.
162  * @store:              the pointer to data store.
163  *
164  * Adopts data store in the keys manager.
165  *
166  * Returns: 0 on success or a negative value if an error occurs.
167  */
168 int
xmlSecKeysMngrAdoptDataStore(xmlSecKeysMngrPtr mngr,xmlSecKeyDataStorePtr store)169 xmlSecKeysMngrAdoptDataStore(xmlSecKeysMngrPtr mngr, xmlSecKeyDataStorePtr store) {
170     xmlSecKeyDataStorePtr tmp;
171     xmlSecSize pos, size;
172 
173     xmlSecAssert2(mngr != NULL, -1);
174     xmlSecAssert2(xmlSecKeyDataStoreIsValid(store), -1);
175 
176     size = xmlSecPtrListGetSize(&(mngr->storesList));
177     for(pos = 0; pos < size; ++pos) {
178         tmp = (xmlSecKeyDataStorePtr)xmlSecPtrListGetItem(&(mngr->storesList), pos);
179         if((tmp != NULL) && (tmp->id == store->id)) {
180             return(xmlSecPtrListSet(&(mngr->storesList), store, pos));
181         }
182     }
183 
184     return(xmlSecPtrListAdd(&(mngr->storesList), store));
185 }
186 
187 
188 /**
189  * xmlSecKeysMngrGetDataStore:
190  * @mngr:               the pointer to keys manager.
191  * @id:                 the desired data store klass.
192  *
193  * Lookups the data store of given klass @id in the keys manager.
194  *
195  * Returns: pointer to data store or NULL if it is not found or an error
196  * occurs.
197  */
198 xmlSecKeyDataStorePtr
xmlSecKeysMngrGetDataStore(xmlSecKeysMngrPtr mngr,xmlSecKeyDataStoreId id)199 xmlSecKeysMngrGetDataStore(xmlSecKeysMngrPtr mngr, xmlSecKeyDataStoreId id) {
200     xmlSecKeyDataStorePtr tmp;
201     xmlSecSize pos, size;
202 
203     xmlSecAssert2(mngr != NULL, NULL);
204     xmlSecAssert2(id != xmlSecKeyDataStoreIdUnknown, NULL);
205 
206     size = xmlSecPtrListGetSize(&(mngr->storesList));
207     for(pos = 0; pos < size; ++pos) {
208         tmp = (xmlSecKeyDataStorePtr)xmlSecPtrListGetItem(&(mngr->storesList), pos);
209         if((tmp != NULL) && (tmp->id == id)) {
210             return(tmp);
211         }
212     }
213 
214     return(NULL);
215 }
216 
217 /**************************************************************************
218  *
219  * xmlSecKeyStore functions
220  *
221  *************************************************************************/
222 /**
223  * xmlSecKeyStoreCreate:
224  * @id:                 the key store klass.
225  *
226  * Creates new store of the specified klass @klass. Caller is responsible
227  * for freeing the returned store by calling #xmlSecKeyStoreDestroy function.
228  *
229  * Returns: the pointer to newly allocated keys store or NULL if an error occurs.
230  */
231 xmlSecKeyStorePtr
xmlSecKeyStoreCreate(xmlSecKeyStoreId id)232 xmlSecKeyStoreCreate(xmlSecKeyStoreId id)  {
233     xmlSecKeyStorePtr store;
234     int ret;
235 
236     xmlSecAssert2(id != NULL, NULL);
237     xmlSecAssert2(id->objSize > 0, NULL);
238 
239     /* Allocate a new xmlSecKeyStore and fill the fields. */
240     store = (xmlSecKeyStorePtr)xmlMalloc(id->objSize);
241     if(store == NULL) {
242         xmlSecMallocError(id->objSize,
243                           xmlSecKeyStoreKlassGetName(id));
244         return(NULL);
245     }
246     memset(store, 0, id->objSize);
247     store->id = id;
248 
249     if(id->initialize != NULL) {
250         ret = (id->initialize)(store);
251         if(ret < 0) {
252             xmlSecInternalError("id->initialize",
253                                 xmlSecKeyStoreKlassGetName(id));
254             xmlSecKeyStoreDestroy(store);
255             return(NULL);
256         }
257     }
258 
259     return(store);
260 }
261 
262 /**
263  * xmlSecKeyStoreDestroy:
264  * @store:              the pointer to keys store.
265  *
266  * Destroys the store created with #xmlSecKeyStoreCreate function.
267  */
268 void
xmlSecKeyStoreDestroy(xmlSecKeyStorePtr store)269 xmlSecKeyStoreDestroy(xmlSecKeyStorePtr store) {
270     xmlSecAssert(xmlSecKeyStoreIsValid(store));
271     xmlSecAssert(store->id->objSize > 0);
272 
273     if(store->id->finalize != NULL) {
274         (store->id->finalize)(store);
275     }
276     memset(store, 0, store->id->objSize);
277     xmlFree(store);
278 }
279 
280 /**
281  * xmlSecKeyStoreFindKey:
282  * @store:              the pointer to keys store.
283  * @name:               the desired key name.
284  * @keyInfoCtx:         the pointer to <dsig:KeyInfo/> node processing context.
285  *
286  * Lookups key in the store. The caller is responsible for destroying
287  * the returned key using #xmlSecKeyDestroy method.
288  *
289  * Returns: the pointer to a key or NULL if key is not found or an error occurs.
290  */
291 xmlSecKeyPtr
xmlSecKeyStoreFindKey(xmlSecKeyStorePtr store,const xmlChar * name,xmlSecKeyInfoCtxPtr keyInfoCtx)292 xmlSecKeyStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) {
293     xmlSecAssert2(xmlSecKeyStoreIsValid(store), NULL);
294     xmlSecAssert2(store->id->findKey != NULL, NULL);
295     xmlSecAssert2(keyInfoCtx != NULL, NULL);
296 
297     return(store->id->findKey(store, name, keyInfoCtx));
298 }
299 
300 /****************************************************************************
301  *
302  * Simple Keys Store
303  *
304  * keys list (xmlSecPtrList) is located after xmlSecKeyStore
305  *
306  ***************************************************************************/
307 #define xmlSecSimpleKeysStoreSize \
308         (sizeof(xmlSecKeyStore) + sizeof(xmlSecPtrList))
309 #define xmlSecSimpleKeysStoreGetList(store) \
310     ((xmlSecKeyStoreCheckSize((store), xmlSecSimpleKeysStoreSize)) ? \
311         (xmlSecPtrListPtr)(((xmlSecByte*)(store)) + sizeof(xmlSecKeyStore)) : \
312         (xmlSecPtrListPtr)NULL)
313 
314 static int                      xmlSecSimpleKeysStoreInitialize (xmlSecKeyStorePtr store);
315 static void                     xmlSecSimpleKeysStoreFinalize   (xmlSecKeyStorePtr store);
316 static xmlSecKeyPtr             xmlSecSimpleKeysStoreFindKey    (xmlSecKeyStorePtr store,
317                                                                  const xmlChar* name,
318                                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
319 
320 static xmlSecKeyStoreKlass xmlSecSimpleKeysStoreKlass = {
321     sizeof(xmlSecKeyStoreKlass),
322     xmlSecSimpleKeysStoreSize,
323 
324     /* data */
325     BAD_CAST "simple-keys-store",               /* const xmlChar* name; */
326 
327     /* constructors/destructor */
328     xmlSecSimpleKeysStoreInitialize,            /* xmlSecKeyStoreInitializeMethod initialize; */
329     xmlSecSimpleKeysStoreFinalize,              /* xmlSecKeyStoreFinalizeMethod finalize; */
330     xmlSecSimpleKeysStoreFindKey,               /* xmlSecKeyStoreFindKeyMethod findKey; */
331 
332     /* reserved for the future */
333     NULL,                                       /* void* reserved0; */
334     NULL,                                       /* void* reserved1; */
335 };
336 
337 /**
338  * xmlSecSimpleKeysStoreGetKlass:
339  *
340  * The simple list based keys store klass.
341  *
342  * Returns: simple list based keys store klass.
343  */
344 xmlSecKeyStoreId
xmlSecSimpleKeysStoreGetKlass(void)345 xmlSecSimpleKeysStoreGetKlass(void) {
346     return(&xmlSecSimpleKeysStoreKlass);
347 }
348 
349 /**
350  * xmlSecSimpleKeysStoreAdoptKey:
351  * @store:              the pointer to simple keys store.
352  * @key:                the pointer to key.
353  *
354  * Adds @key to the @store.
355  *
356  * Returns: 0 on success or a negative value if an error occurs.
357  */
358 int
xmlSecSimpleKeysStoreAdoptKey(xmlSecKeyStorePtr store,xmlSecKeyPtr key)359 xmlSecSimpleKeysStoreAdoptKey(xmlSecKeyStorePtr store, xmlSecKeyPtr key) {
360     xmlSecPtrListPtr list;
361     int ret;
362 
363     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
364     xmlSecAssert2(key != NULL, -1);
365 
366     list = xmlSecSimpleKeysStoreGetList(store);
367     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), -1);
368 
369     ret = xmlSecPtrListAdd(list, key);
370     if(ret < 0) {
371         xmlSecInternalError("xmlSecPtrListAdd",
372                             xmlSecKeyStoreGetName(store));
373         return(-1);
374     }
375 
376     return(0);
377 }
378 
379 /**
380  * xmlSecSimpleKeysStoreLoad:
381  * @store:              the pointer to simple keys store.
382  * @uri:                the filename.
383  * @keysMngr:           the pointer to associated keys manager.
384  *
385  * Reads keys from an XML file.
386  *
387  * Returns: 0 on success or a negative value if an error occurs.
388  */
389 int
xmlSecSimpleKeysStoreLoad(xmlSecKeyStorePtr store,const char * uri,xmlSecKeysMngrPtr keysMngr ATTRIBUTE_UNUSED)390 xmlSecSimpleKeysStoreLoad(xmlSecKeyStorePtr store, const char *uri,
391                             xmlSecKeysMngrPtr keysMngr ATTRIBUTE_UNUSED) {
392     xmlDocPtr doc;
393     xmlNodePtr root;
394     xmlNodePtr cur;
395     xmlSecKeyPtr key;
396     xmlSecKeyInfoCtx keyInfoCtx;
397     int ret;
398 
399     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
400     xmlSecAssert2(uri != NULL, -1);
401     UNREFERENCED_PARAMETER(keysMngr);
402 
403     doc = xmlParseFile(uri);
404     if(doc == NULL) {
405         xmlSecXmlError2("xmlParseFile", xmlSecKeyStoreGetName(store),
406                         "uri=%s", xmlSecErrorsSafeString(uri));
407         return(-1);
408     }
409 
410     root = xmlDocGetRootElement(doc);
411     if(!xmlSecCheckNodeName(root, BAD_CAST "Keys", xmlSecNs)) {
412         xmlSecInvalidNodeError(root, BAD_CAST "Keys",
413                                xmlSecKeyStoreGetName(store));
414         xmlFreeDoc(doc);
415         return(-1);
416     }
417 
418     cur = xmlSecGetNextElementNode(root->children);
419     while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs)) {
420         key = xmlSecKeyCreate();
421         if(key == NULL) {
422             xmlSecInternalError("xmlSecKeyCreate",
423                                 xmlSecKeyStoreGetName(store));
424             xmlFreeDoc(doc);
425             return(-1);
426         }
427 
428         ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
429         if(ret < 0) {
430             xmlSecInternalError("xmlSecKeyInfoCtxInitialize",
431                                 xmlSecKeyStoreGetName(store));
432             xmlSecKeyDestroy(key);
433             xmlFreeDoc(doc);
434             return(-1);
435         }
436 
437         keyInfoCtx.mode           = xmlSecKeyInfoModeRead;
438         keyInfoCtx.keysMngr       = NULL;
439         keyInfoCtx.flags          = XMLSEC_KEYINFO_FLAGS_DONT_STOP_ON_KEY_FOUND |
440                                     XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS;
441         keyInfoCtx.keyReq.keyId   = xmlSecKeyDataIdUnknown;
442         keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
443         keyInfoCtx.keyReq.keyUsage= xmlSecKeyDataUsageAny;
444 
445         ret = xmlSecKeyInfoNodeRead(cur, key, &keyInfoCtx);
446         if(ret < 0) {
447             xmlSecInternalError("xmlSecKeyInfoNodeRead",
448                                 xmlSecKeyStoreGetName(store));
449             xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
450             xmlSecKeyDestroy(key);
451             xmlFreeDoc(doc);
452             return(-1);
453         }
454         xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
455 
456         if(xmlSecKeyIsValid(key)) {
457             ret = xmlSecSimpleKeysStoreAdoptKey(store, key);
458             if(ret < 0) {
459                 xmlSecInternalError("xmlSecSimpleKeysStoreAdoptKey",
460                                     xmlSecKeyStoreGetName(store));
461                 xmlSecKeyDestroy(key);
462                 xmlFreeDoc(doc);
463                 return(-1);
464             }
465         } else {
466             /* we have an unknown key in our file, just ignore it */
467             xmlSecKeyDestroy(key);
468         }
469         cur = xmlSecGetNextElementNode(cur->next);
470     }
471 
472     if(cur != NULL) {
473         xmlSecUnexpectedNodeError(cur, xmlSecKeyStoreGetName(store));
474         xmlFreeDoc(doc);
475         return(-1);
476     }
477 
478     xmlFreeDoc(doc);
479     return(0);
480 
481 }
482 
483 /**
484  * xmlSecSimpleKeysStoreSave:
485  * @store:              the pointer to simple keys store.
486  * @filename:           the filename.
487  * @type:               the saved keys type (public, private, ...).
488  *
489  * Writes keys from @store to an XML file.
490  *
491  * Returns: 0 on success or a negative value if an error occurs.
492  */
493 int
xmlSecSimpleKeysStoreSave(xmlSecKeyStorePtr store,const char * filename,xmlSecKeyDataType type)494 xmlSecSimpleKeysStoreSave(xmlSecKeyStorePtr store, const char *filename, xmlSecKeyDataType type) {
495     xmlSecKeyInfoCtx keyInfoCtx;
496     xmlSecPtrListPtr list;
497     xmlSecKeyPtr key;
498     xmlSecSize i, keysSize;
499     xmlDocPtr doc;
500     xmlNodePtr cur;
501     xmlSecKeyDataPtr data;
502     xmlSecPtrListPtr idsList;
503     xmlSecKeyDataId dataId;
504     xmlSecSize idsSize, j;
505     int ret;
506 
507     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
508     xmlSecAssert2(filename != NULL, -1);
509 
510     list = xmlSecSimpleKeysStoreGetList(store);
511     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), -1);
512 
513     /* create doc */
514     doc = xmlSecCreateTree(BAD_CAST "Keys", xmlSecNs);
515     if(doc == NULL) {
516         xmlSecInternalError("xmlSecCreateTree",
517                             xmlSecKeyStoreGetName(store));
518         return(-1);
519     }
520 
521     idsList = xmlSecKeyDataIdsGet();
522     xmlSecAssert2(idsList != NULL, -1);
523 
524     keysSize = xmlSecPtrListGetSize(list);
525     idsSize = xmlSecPtrListGetSize(idsList);
526     for(i = 0; i < keysSize; ++i) {
527         key = (xmlSecKeyPtr)xmlSecPtrListGetItem(list, i);
528         xmlSecAssert2(key != NULL, -1);
529 
530         cur = xmlSecAddChild(xmlDocGetRootElement(doc), xmlSecNodeKeyInfo, xmlSecDSigNs);
531         if(cur == NULL) {
532             xmlSecInternalError2("xmlSecAddChild",
533                                  xmlSecKeyStoreGetName(store),
534                                  "node=%s",
535                                  xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
536             xmlFreeDoc(doc);
537             return(-1);
538         }
539 
540         /* special data key name */
541         if(xmlSecKeyGetName(key) != NULL) {
542             if(xmlSecAddChild(cur, xmlSecNodeKeyName, xmlSecDSigNs) == NULL) {
543                 xmlSecInternalError2("xmlSecAddChild",
544                                      xmlSecKeyStoreGetName(store),
545                                      "node=%s",
546                                      xmlSecErrorsSafeString(xmlSecNodeKeyName));
547                 xmlFreeDoc(doc);
548                 return(-1);
549             }
550         }
551 
552         /* create nodes for other keys data */
553         for(j = 0; j < idsSize; ++j) {
554             dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(idsList, j);
555             xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, -1);
556 
557             if(dataId->dataNodeName == NULL) {
558                 continue;
559             }
560 
561             data = xmlSecKeyGetData(key, dataId);
562             if(data == NULL) {
563                 continue;
564             }
565 
566             if(xmlSecAddChild(cur, dataId->dataNodeName, dataId->dataNodeNs) == NULL) {
567                 xmlSecInternalError2("xmlSecAddChild",
568                                      xmlSecKeyStoreGetName(store),
569                                     "node=%s", xmlSecErrorsSafeString(dataId->dataNodeName));
570                 xmlFreeDoc(doc);
571                 return(-1);
572             }
573         }
574 
575         ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
576         if(ret < 0) {
577             xmlSecInternalError("xmlSecKeyInfoCtxInitialize",
578                                 xmlSecKeyStoreGetName(store));
579             xmlFreeDoc(doc);
580             return(-1);
581         }
582 
583         keyInfoCtx.mode                 = xmlSecKeyInfoModeWrite;
584         keyInfoCtx.keyReq.keyId         = xmlSecKeyDataIdUnknown;
585         keyInfoCtx.keyReq.keyType       = type;
586         keyInfoCtx.keyReq.keyUsage      = xmlSecKeyDataUsageAny;
587 
588         /* finally write key in the node */
589         ret = xmlSecKeyInfoNodeWrite(cur, key, &keyInfoCtx);
590         if(ret < 0) {
591             xmlSecInternalError("xmlSecKeyInfoNodeWrite",
592                                 xmlSecKeyStoreGetName(store));
593             xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
594             xmlFreeDoc(doc);
595             return(-1);
596         }
597         xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
598     }
599 
600     /* now write result */
601     ret = xmlSaveFormatFile(filename, doc, 1);
602     if(ret < 0) {
603         xmlSecXmlError2("xmlSaveFormatFile", xmlSecKeyStoreGetName(store),
604                         "filename=%s", xmlSecErrorsSafeString(filename));
605         xmlFreeDoc(doc);
606         return(-1);
607     }
608 
609     xmlFreeDoc(doc);
610     return(0);
611 }
612 
613 /**
614  * xmlSecSimpleKeysStoreGetKeys:
615  * @store:              the pointer to simple keys store.
616  *
617  * Gets list of keys from simple keys store.
618  *
619  * Returns: pointer to the list of keys stored in the keys store or NULL
620  * if an error occurs.
621  */
622 xmlSecPtrListPtr
xmlSecSimpleKeysStoreGetKeys(xmlSecKeyStorePtr store)623 xmlSecSimpleKeysStoreGetKeys(xmlSecKeyStorePtr store) {
624     xmlSecPtrListPtr list;
625 
626     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), NULL);
627 
628     list = xmlSecSimpleKeysStoreGetList(store);
629     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), NULL);
630 
631     return list;
632 }
633 
634 static int
xmlSecSimpleKeysStoreInitialize(xmlSecKeyStorePtr store)635 xmlSecSimpleKeysStoreInitialize(xmlSecKeyStorePtr store) {
636     xmlSecPtrListPtr list;
637     int ret;
638 
639     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
640 
641     list = xmlSecSimpleKeysStoreGetList(store);
642     xmlSecAssert2(list != NULL, -1);
643 
644     ret = xmlSecPtrListInitialize(list, xmlSecKeyPtrListId);
645     if(ret < 0) {
646         xmlSecInternalError("xmlSecPtrListInitialize(xmlSecKeyPtrListId)",
647                             xmlSecKeyStoreGetName(store));
648         return(-1);
649     }
650 
651     return(0);
652 }
653 
654 static void
xmlSecSimpleKeysStoreFinalize(xmlSecKeyStorePtr store)655 xmlSecSimpleKeysStoreFinalize(xmlSecKeyStorePtr store) {
656     xmlSecPtrListPtr list;
657 
658     xmlSecAssert(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId));
659 
660     list = xmlSecSimpleKeysStoreGetList(store);
661     xmlSecAssert(list != NULL);
662 
663     xmlSecPtrListFinalize(list);
664 }
665 
666 static xmlSecKeyPtr
xmlSecSimpleKeysStoreFindKey(xmlSecKeyStorePtr store,const xmlChar * name,xmlSecKeyInfoCtxPtr keyInfoCtx)667 xmlSecSimpleKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name,
668                             xmlSecKeyInfoCtxPtr keyInfoCtx) {
669     xmlSecPtrListPtr list;
670     xmlSecKeyPtr key;
671     xmlSecSize pos, size;
672 
673     xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), NULL);
674     xmlSecAssert2(keyInfoCtx != NULL, NULL);
675 
676     list = xmlSecSimpleKeysStoreGetList(store);
677     xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), NULL);
678 
679     size = xmlSecPtrListGetSize(list);
680     for(pos = 0; pos < size; ++pos) {
681         key = (xmlSecKeyPtr)xmlSecPtrListGetItem(list, pos);
682         if((key != NULL) && (xmlSecKeyMatch(key, name, &(keyInfoCtx->keyReq)) == 1)) {
683             return(xmlSecKeyDuplicate(key));
684         }
685     }
686     return(NULL);
687 }
688 
689