2 * XML Security Library (http://www.aleksey.com/xmlsec).
6 * This is free software; see Copyright file in the source
7 * distribution for preciese wording.
9 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
18 #include <libxml/tree.h>
19 #include <libxml/parser.h>
21 #include <xmlsec/xmlsec.h>
22 #include <xmlsec/xmltree.h>
23 #include <xmlsec/list.h>
24 #include <xmlsec/keys.h>
25 #include <xmlsec/transforms.h>
26 #include <xmlsec/keysmngr.h>
27 #include <xmlsec/errors.h>
29 /****************************************************************************
33 ***************************************************************************/
35 * xmlSecKeysMngrCreate:
37 * Creates new keys manager. Caller is responsible for freeing it with
38 * #xmlSecKeysMngrDestroy function.
40 * Returns: the pointer to newly allocated keys manager or NULL if
44 xmlSecKeysMngrCreate(void) {
45 xmlSecKeysMngrPtr mngr;
48 /* Allocate a new xmlSecKeysMngr and fill the fields. */
49 mngr = (xmlSecKeysMngrPtr)xmlMalloc(sizeof(xmlSecKeysMngr));
51 xmlSecError(XMLSEC_ERRORS_HERE,
54 XMLSEC_ERRORS_R_MALLOC_FAILED,
55 "sizeof(xmlSecKeysMngr)=%d",
56 sizeof(xmlSecKeysMngr));
59 memset(mngr, 0, sizeof(xmlSecKeysMngr));
61 ret = xmlSecPtrListInitialize(&(mngr->storesList), xmlSecKeyDataStorePtrListId);
63 xmlSecError(XMLSEC_ERRORS_HERE,
65 "xmlSecPtrListInitialize",
66 XMLSEC_ERRORS_R_XMLSEC_FAILED,
67 "xmlSecKeyDataStorePtrListId");
75 * xmlSecKeysMngrDestroy:
76 * @mngr: the pointer to keys manager.
78 * Destroys keys manager created with #xmlSecKeysMngrCreate function.
81 xmlSecKeysMngrDestroy(xmlSecKeysMngrPtr mngr) {
82 xmlSecAssert(mngr != NULL);
84 /* destroy keys store */
85 if(mngr->keysStore != NULL) {
86 xmlSecKeyStoreDestroy(mngr->keysStore);
89 /* destroy other data stores */
90 xmlSecPtrListFinalize(&(mngr->storesList));
92 memset(mngr, 0, sizeof(xmlSecKeysMngr));
97 * xmlSecKeysMngrFindKey:
98 * @mngr: the pointer to keys manager.
99 * @name: the desired key name.
100 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> node processing context.
102 * Lookups key in the keys manager keys store. The caller is responsible
103 * for destroying the returned key using #xmlSecKeyDestroy method.
105 * Returns: the pointer to a key or NULL if key is not found or an error occurs.
108 xmlSecKeysMngrFindKey(xmlSecKeysMngrPtr mngr, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) {
109 xmlSecKeyStorePtr store;
111 xmlSecAssert2(mngr != NULL, NULL);
112 xmlSecAssert2(keyInfoCtx != NULL, NULL);
114 store = xmlSecKeysMngrGetKeysStore(mngr);
116 /* no store. is it an error? */
120 return(xmlSecKeyStoreFindKey(store, name, keyInfoCtx));
124 * xmlSecKeysMngrAdoptKeysStore:
125 * @mngr: the pointer to keys manager.
126 * @store: the pointer to keys store.
128 * Adopts keys store in the keys manager @mngr.
130 * Returns: 0 on success or a negative value if an error occurs.
133 xmlSecKeysMngrAdoptKeysStore(xmlSecKeysMngrPtr mngr, xmlSecKeyStorePtr store) {
134 xmlSecAssert2(mngr != NULL, -1);
135 xmlSecAssert2(xmlSecKeyStoreIsValid(store), -1);
137 if(mngr->keysStore != NULL) {
138 xmlSecKeyStoreDestroy(mngr->keysStore);
140 mngr->keysStore = store;
146 * xmlSecKeysMngrGetKeysStore:
147 * @mngr: the pointer to keys manager.
149 * Gets the keys store.
151 * Returns: the keys store in the keys manager @mngr or NULL if
152 * there is no store or an error occurs.
155 xmlSecKeysMngrGetKeysStore(xmlSecKeysMngrPtr mngr) {
156 xmlSecAssert2(mngr != NULL, NULL);
158 return(mngr->keysStore);
162 * xmlSecKeysMngrAdoptDataStore:
163 * @mngr: the pointer to keys manager.
164 * @store: the pointer to data store.
166 * Adopts data store in the keys manager.
168 * Returns: 0 on success or a negative value if an error occurs.
171 xmlSecKeysMngrAdoptDataStore(xmlSecKeysMngrPtr mngr, xmlSecKeyDataStorePtr store) {
172 xmlSecKeyDataStorePtr tmp;
173 xmlSecSize pos, size;
175 xmlSecAssert2(mngr != NULL, -1);
176 xmlSecAssert2(xmlSecKeyDataStoreIsValid(store), -1);
178 size = xmlSecPtrListGetSize(&(mngr->storesList));
179 for(pos = 0; pos < size; ++pos) {
180 tmp = (xmlSecKeyDataStorePtr)xmlSecPtrListGetItem(&(mngr->storesList), pos);
181 if((tmp != NULL) && (tmp->id == store->id)) {
182 return(xmlSecPtrListSet(&(mngr->storesList), store, pos));
186 return(xmlSecPtrListAdd(&(mngr->storesList), store));
191 * xmlSecKeysMngrGetDataStore:
192 * @mngr: the pointer to keys manager.
193 * @id: the desired data store klass.
195 * Lookups the data store of given klass @id in the keys manager.
197 * Returns: pointer to data store or NULL if it is not found or an error
200 xmlSecKeyDataStorePtr
201 xmlSecKeysMngrGetDataStore(xmlSecKeysMngrPtr mngr, xmlSecKeyDataStoreId id) {
202 xmlSecKeyDataStorePtr tmp;
203 xmlSecSize pos, size;
205 xmlSecAssert2(mngr != NULL, NULL);
206 xmlSecAssert2(id != xmlSecKeyDataStoreIdUnknown, NULL);
208 size = xmlSecPtrListGetSize(&(mngr->storesList));
209 for(pos = 0; pos < size; ++pos) {
210 tmp = (xmlSecKeyDataStorePtr)xmlSecPtrListGetItem(&(mngr->storesList), pos);
211 if((tmp != NULL) && (tmp->id == id)) {
219 /**************************************************************************
221 * xmlSecKeyStore functions
223 *************************************************************************/
225 * xmlSecKeyStoreCreate:
226 * @id: the key store klass.
228 * Creates new store of the specified klass @klass. Caller is responsible
229 * for freeing the returned store by calling #xmlSecKeyStoreDestroy function.
231 * Returns: the pointer to newly allocated keys store or NULL if an error occurs.
234 xmlSecKeyStoreCreate(xmlSecKeyStoreId id) {
235 xmlSecKeyStorePtr store;
238 xmlSecAssert2(id != NULL, NULL);
239 xmlSecAssert2(id->objSize > 0, NULL);
241 /* Allocate a new xmlSecKeyStore and fill the fields. */
242 store = (xmlSecKeyStorePtr)xmlMalloc(id->objSize);
244 xmlSecError(XMLSEC_ERRORS_HERE,
245 xmlSecErrorsSafeString(xmlSecKeyStoreKlassGetName(id)),
247 XMLSEC_ERRORS_R_MALLOC_FAILED,
248 "size=%d", id->objSize);
251 memset(store, 0, id->objSize);
254 if(id->initialize != NULL) {
255 ret = (id->initialize)(store);
257 xmlSecError(XMLSEC_ERRORS_HERE,
258 xmlSecErrorsSafeString(xmlSecKeyStoreKlassGetName(id)),
260 XMLSEC_ERRORS_R_XMLSEC_FAILED,
261 XMLSEC_ERRORS_NO_MESSAGE);
262 xmlSecKeyStoreDestroy(store);
271 * xmlSecKeyStoreDestroy:
272 * @store: the pointer to keys store.
274 * Destroys the store created with #xmlSecKeyStoreCreate function.
277 xmlSecKeyStoreDestroy(xmlSecKeyStorePtr store) {
278 xmlSecAssert(xmlSecKeyStoreIsValid(store));
279 xmlSecAssert(store->id->objSize > 0);
281 if(store->id->finalize != NULL) {
282 (store->id->finalize)(store);
284 memset(store, 0, store->id->objSize);
289 * xmlSecKeyStoreFindKey:
290 * @store: the pointer to keys store.
291 * @name: the desired key name.
292 * @keyInfoCtx: the pointer to <dsig:KeyInfo/> node processing context.
294 * Lookups key in the store. The caller is responsible for destroying
295 * the returned key using #xmlSecKeyDestroy method.
297 * Returns: the pointer to a key or NULL if key is not found or an error occurs.
300 xmlSecKeyStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) {
301 xmlSecAssert2(xmlSecKeyStoreIsValid(store), NULL);
302 xmlSecAssert2(store->id->findKey != NULL, NULL);
303 xmlSecAssert2(keyInfoCtx != NULL, NULL);
305 return(store->id->findKey(store, name, keyInfoCtx));
308 /****************************************************************************
312 * keys list (xmlSecPtrList) is located after xmlSecKeyStore
314 ***************************************************************************/
315 #define xmlSecSimpleKeysStoreSize \
316 (sizeof(xmlSecKeyStore) + sizeof(xmlSecPtrList))
317 #define xmlSecSimpleKeysStoreGetList(store) \
318 ((xmlSecKeyStoreCheckSize((store), xmlSecSimpleKeysStoreSize)) ? \
319 (xmlSecPtrListPtr)(((xmlSecByte*)(store)) + sizeof(xmlSecKeyStore)) : \
320 (xmlSecPtrListPtr)NULL)
322 static int xmlSecSimpleKeysStoreInitialize (xmlSecKeyStorePtr store);
323 static void xmlSecSimpleKeysStoreFinalize (xmlSecKeyStorePtr store);
324 static xmlSecKeyPtr xmlSecSimpleKeysStoreFindKey (xmlSecKeyStorePtr store,
326 xmlSecKeyInfoCtxPtr keyInfoCtx);
328 static xmlSecKeyStoreKlass xmlSecSimpleKeysStoreKlass = {
329 sizeof(xmlSecKeyStoreKlass),
330 xmlSecSimpleKeysStoreSize,
333 BAD_CAST "simple-keys-store", /* const xmlChar* name; */
335 /* constructors/destructor */
336 xmlSecSimpleKeysStoreInitialize, /* xmlSecKeyStoreInitializeMethod initialize; */
337 xmlSecSimpleKeysStoreFinalize, /* xmlSecKeyStoreFinalizeMethod finalize; */
338 xmlSecSimpleKeysStoreFindKey, /* xmlSecKeyStoreFindKeyMethod findKey; */
340 /* reserved for the future */
341 NULL, /* void* reserved0; */
342 NULL, /* void* reserved1; */
346 * xmlSecSimpleKeysStoreGetKlass:
348 * The simple list based keys store klass.
350 * Returns: simple list based keys store klass.
353 xmlSecSimpleKeysStoreGetKlass(void) {
354 return(&xmlSecSimpleKeysStoreKlass);
358 * xmlSecSimpleKeysStoreAdoptKey:
359 * @store: the pointer to simple keys store.
360 * @key: the pointer to key.
362 * Adds @key to the @store.
364 * Returns: 0 on success or a negative value if an error occurs.
367 xmlSecSimpleKeysStoreAdoptKey(xmlSecKeyStorePtr store, xmlSecKeyPtr key) {
368 xmlSecPtrListPtr list;
371 xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
372 xmlSecAssert2(key != NULL, -1);
374 list = xmlSecSimpleKeysStoreGetList(store);
375 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), -1);
377 ret = xmlSecPtrListAdd(list, key);
379 xmlSecError(XMLSEC_ERRORS_HERE,
380 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
382 XMLSEC_ERRORS_R_XMLSEC_FAILED,
383 XMLSEC_ERRORS_NO_MESSAGE);
391 * xmlSecSimpleKeysStoreLoad:
392 * @store: the pointer to simple keys store.
393 * @uri: the filename.
394 * @keysMngr: the pointer to associated keys manager.
396 * Reads keys from an XML file.
398 * Returns: 0 on success or a negative value if an error occurs.
401 xmlSecSimpleKeysStoreLoad(xmlSecKeyStorePtr store, const char *uri,
402 xmlSecKeysMngrPtr keysMngr) {
407 xmlSecKeyInfoCtx keyInfoCtx;
410 xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
411 xmlSecAssert2(uri != NULL, -1);
413 doc = xmlParseFile(uri);
415 xmlSecError(XMLSEC_ERRORS_HERE,
416 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
418 XMLSEC_ERRORS_R_XML_FAILED,
420 xmlSecErrorsSafeString(uri));
424 root = xmlDocGetRootElement(doc);
425 if(!xmlSecCheckNodeName(root, BAD_CAST "Keys", xmlSecNs)) {
426 xmlSecError(XMLSEC_ERRORS_HERE,
427 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
428 xmlSecErrorsSafeString(xmlSecNodeGetName(root)),
429 XMLSEC_ERRORS_R_INVALID_NODE,
430 "expected-node=<xmlsec:Keys>");
435 cur = xmlSecGetNextElementNode(root->children);
436 while((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs)) {
437 key = xmlSecKeyCreate();
439 xmlSecError(XMLSEC_ERRORS_HERE,
440 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
441 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
442 XMLSEC_ERRORS_R_INVALID_NODE,
444 xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
449 ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
451 xmlSecError(XMLSEC_ERRORS_HERE,
452 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
453 "xmlSecKeyInfoCtxInitialize",
454 XMLSEC_ERRORS_R_XMLSEC_FAILED,
455 XMLSEC_ERRORS_NO_MESSAGE);
456 xmlSecKeyDestroy(key);
461 keyInfoCtx.mode = xmlSecKeyInfoModeRead;
462 keyInfoCtx.keysMngr = keysMngr;
463 keyInfoCtx.flags = XMLSEC_KEYINFO_FLAGS_DONT_STOP_ON_KEY_FOUND |
464 XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS;
465 keyInfoCtx.keyReq.keyId = xmlSecKeyDataIdUnknown;
466 keyInfoCtx.keyReq.keyType = xmlSecKeyDataTypeAny;
467 keyInfoCtx.keyReq.keyUsage= xmlSecKeyDataUsageAny;
469 ret = xmlSecKeyInfoNodeRead(cur, key, &keyInfoCtx);
471 xmlSecError(XMLSEC_ERRORS_HERE,
472 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
473 "xmlSecKeyInfoNodeRead",
474 XMLSEC_ERRORS_R_XMLSEC_FAILED,
475 XMLSEC_ERRORS_NO_MESSAGE);
476 xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
477 xmlSecKeyDestroy(key);
481 xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
483 if(xmlSecKeyIsValid(key)) {
484 ret = xmlSecSimpleKeysStoreAdoptKey(store, key);
486 xmlSecError(XMLSEC_ERRORS_HERE,
487 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
488 "xmlSecSimpleKeysStoreAdoptKey",
489 XMLSEC_ERRORS_R_XMLSEC_FAILED,
490 XMLSEC_ERRORS_NO_MESSAGE);
491 xmlSecKeyDestroy(key);
496 /* we have an unknown key in our file, just ignore it */
497 xmlSecKeyDestroy(key);
499 cur = xmlSecGetNextElementNode(cur->next);
503 xmlSecError(XMLSEC_ERRORS_HERE,
504 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
505 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
506 XMLSEC_ERRORS_R_UNEXPECTED_NODE,
507 XMLSEC_ERRORS_NO_MESSAGE);
518 * xmlSecSimpleKeysStoreSave:
519 * @store: the pointer to simple keys store.
520 * @filename: the filename.
521 * @type: the saved keys type (public, private, ...).
523 * Writes keys from @store to an XML file.
525 * Returns: 0 on success or a negative value if an error occurs.
528 xmlSecSimpleKeysStoreSave(xmlSecKeyStorePtr store, const char *filename, xmlSecKeyDataType type) {
529 xmlSecKeyInfoCtx keyInfoCtx;
530 xmlSecPtrListPtr list;
532 xmlSecSize i, keysSize;
535 xmlSecKeyDataPtr data;
536 xmlSecPtrListPtr idsList;
537 xmlSecKeyDataId dataId;
538 xmlSecSize idsSize, j;
541 xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
542 xmlSecAssert2(filename != NULL, -1);
544 list = xmlSecSimpleKeysStoreGetList(store);
545 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), -1);
548 doc = xmlSecCreateTree(BAD_CAST "Keys", xmlSecNs);
550 xmlSecError(XMLSEC_ERRORS_HERE,
551 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
553 XMLSEC_ERRORS_R_XMLSEC_FAILED,
554 XMLSEC_ERRORS_NO_MESSAGE);
558 idsList = xmlSecKeyDataIdsGet();
559 xmlSecAssert2(idsList != NULL, -1);
561 keysSize = xmlSecPtrListGetSize(list);
562 idsSize = xmlSecPtrListGetSize(idsList);
563 for(i = 0; i < keysSize; ++i) {
564 key = (xmlSecKeyPtr)xmlSecPtrListGetItem(list, i);
565 xmlSecAssert2(key != NULL, -1);
567 cur = xmlSecAddChild(xmlDocGetRootElement(doc), xmlSecNodeKeyInfo, xmlSecDSigNs);
569 xmlSecError(XMLSEC_ERRORS_HERE,
570 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
572 XMLSEC_ERRORS_R_XMLSEC_FAILED,
574 xmlSecErrorsSafeString(xmlSecNodeKeyInfo));
579 /* special data key name */
580 if(xmlSecKeyGetName(key) != NULL) {
581 if(xmlSecAddChild(cur, xmlSecNodeKeyName, xmlSecDSigNs) == NULL) {
582 xmlSecError(XMLSEC_ERRORS_HERE,
583 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
585 XMLSEC_ERRORS_R_XMLSEC_FAILED,
587 xmlSecErrorsSafeString(xmlSecNodeKeyName));
593 /* create nodes for other keys data */
594 for(j = 0; j < idsSize; ++j) {
595 dataId = (xmlSecKeyDataId)xmlSecPtrListGetItem(idsList, j);
596 xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, -1);
598 if(dataId->dataNodeName == NULL) {
602 data = xmlSecKeyGetData(key, dataId);
607 if(xmlSecAddChild(cur, dataId->dataNodeName, dataId->dataNodeNs) == NULL) {
608 xmlSecError(XMLSEC_ERRORS_HERE,
609 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
611 XMLSEC_ERRORS_R_XMLSEC_FAILED,
613 xmlSecErrorsSafeString(dataId->dataNodeName));
619 ret = xmlSecKeyInfoCtxInitialize(&keyInfoCtx, NULL);
621 xmlSecError(XMLSEC_ERRORS_HERE,
622 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
623 "xmlSecKeyInfoCtxInitialize",
624 XMLSEC_ERRORS_R_XMLSEC_FAILED,
625 XMLSEC_ERRORS_NO_MESSAGE);
630 keyInfoCtx.mode = xmlSecKeyInfoModeWrite;
631 keyInfoCtx.keyReq.keyId = xmlSecKeyDataIdUnknown;
632 keyInfoCtx.keyReq.keyType = type;
633 keyInfoCtx.keyReq.keyUsage = xmlSecKeyDataUsageAny;
635 /* finally write key in the node */
636 ret = xmlSecKeyInfoNodeWrite(cur, key, &keyInfoCtx);
638 xmlSecError(XMLSEC_ERRORS_HERE,
639 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
640 "xmlSecKeyInfoNodeWrite",
641 XMLSEC_ERRORS_R_XMLSEC_FAILED,
642 XMLSEC_ERRORS_NO_MESSAGE);
643 xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
647 xmlSecKeyInfoCtxFinalize(&keyInfoCtx);
650 /* now write result */
651 ret = xmlSaveFormatFile(filename, doc, 1);
653 xmlSecError(XMLSEC_ERRORS_HERE,
654 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
656 XMLSEC_ERRORS_R_XML_FAILED,
658 xmlSecErrorsSafeString(filename));
668 * xmlSecSimpleKeysStoreGetKeys:
669 * @store: the pointer to simple keys store.
671 * Gets list of keys from simple keys store.
673 * Returns: pointer to the list of keys stored in the keys store or NULL
674 * if an error occurs.
677 xmlSecSimpleKeysStoreGetKeys(xmlSecKeyStorePtr store) {
678 xmlSecPtrListPtr list;
680 xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), NULL);
682 list = xmlSecSimpleKeysStoreGetList(store);
683 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), NULL);
689 xmlSecSimpleKeysStoreInitialize(xmlSecKeyStorePtr store) {
690 xmlSecPtrListPtr list;
693 xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), -1);
695 list = xmlSecSimpleKeysStoreGetList(store);
696 xmlSecAssert2(list != NULL, -1);
698 ret = xmlSecPtrListInitialize(list, xmlSecKeyPtrListId);
700 xmlSecError(XMLSEC_ERRORS_HERE,
701 xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
702 "xmlSecPtrListInitialize",
703 XMLSEC_ERRORS_R_XMLSEC_FAILED,
704 "xmlSecKeyPtrListId");
712 xmlSecSimpleKeysStoreFinalize(xmlSecKeyStorePtr store) {
713 xmlSecPtrListPtr list;
715 xmlSecAssert(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId));
717 list = xmlSecSimpleKeysStoreGetList(store);
718 xmlSecAssert(list != NULL);
720 xmlSecPtrListFinalize(list);
724 xmlSecSimpleKeysStoreFindKey(xmlSecKeyStorePtr store, const xmlChar* name,
725 xmlSecKeyInfoCtxPtr keyInfoCtx) {
726 xmlSecPtrListPtr list;
728 xmlSecSize pos, size;
730 xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecSimpleKeysStoreId), NULL);
731 xmlSecAssert2(keyInfoCtx != NULL, NULL);
733 list = xmlSecSimpleKeysStoreGetList(store);
734 xmlSecAssert2(xmlSecPtrListCheckId(list, xmlSecKeyPtrListId), NULL);
736 size = xmlSecPtrListGetSize(list);
737 for(pos = 0; pos < size; ++pos) {
738 key = (xmlSecKeyPtr)xmlSecPtrListGetItem(list, pos);
739 if((key != NULL) && (xmlSecKeyMatch(key, name, &(keyInfoCtx->keyReq)) == 1)) {
740 return(xmlSecKeyDuplicate(key));