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