Index: libabac/abac_verifier.c
===================================================================
--- libabac/abac_verifier.c	(revision ec550f769c681cfa831dc724f82ddacd21fc75cd)
+++ libabac/abac_verifier.c	(revision bec30b5ab9c079bfa792531837b13442d03db10c)
@@ -6,13 +6,10 @@
 #include "abac.h"
 #include "abac_list.h"
-#include "uthash.h"
 #include "abac_util.h"
 
-typedef struct _abac_id_cert_t {
+struct _abac_id_cert_t {
     char *keyid; // using cert's keyid
     abac_id_t *cert;
-
-    UT_hash_handle hh;
-} abac_id_cert_t;
+};
 
 struct _abac_credential_t {
@@ -24,7 +21,4 @@
     int refcount;
 };
-
-/* hash table of all the principal id credentials */
-abac_id_cert_t *id_certs = NULL;
 
 extern int abac_id_pass_privkey_from_id(abac_id_t *to_id, abac_id_t *from_id);
@@ -71,21 +65,24 @@
  */
 void abac_verifier_deinit(void) {
-    abac_id_cert_t *id;
-
-    while ((id = id_certs) != NULL) {
-        HASH_DEL(id_certs, id);
-
-        free(id->keyid);
-        abac_id_free(id->cert);
-        free(id);
-    }
     deinit_xmlsec();
     deinit_openssl();
 }
 
+static abac_id_cert_t *_lookup_cert(abac_list_t *id_certs, char *keyid)
+{
+    abac_id_cert_t *id_cert=NULL;
+    if(id_certs != NULL) {
+        abac_list_foreach(id_certs, id_cert,
+            if(strcmp(keyid,id_cert->keyid)==0)
+               return id_cert;
+        );
+    }
+    return NULL;
+}
+
 /**
  * Load an ID certificate.
  */
-static int _load_id(abac_id_t *cert) {
+static int _load_id(abac_list_t *id_certs, abac_id_t *cert) {
     abac_id_cert_t *id_cert = NULL;
     char *keyid = NULL;
@@ -98,5 +95,6 @@
 
     // if we already have this cert 'error' with success
-    HASH_FIND_STR(id_certs, keyid, id_cert);
+    id_cert=_lookup_cert(id_certs, keyid);
+
     if (id_cert != NULL) {
         /* special case, if
@@ -122,5 +120,5 @@
     id_cert->keyid = abac_xstrdup(keyid);
     id_cert->cert = cert;
-    HASH_ADD_KEYPTR(hh, id_certs, id_cert->keyid, strlen(id_cert->keyid), id_cert);
+    abac_list_add(id_certs, id_cert); 
 
     return ABAC_CERT_SUCCESS;
@@ -131,8 +129,7 @@
 }
 
-abac_id_t *abac_verifier_lookup_id(char *keyid)
+abac_id_t *abac_verifier_lookup_id(abac_list_t *id_certs, char *keyid)
 {
-    abac_id_cert_t *id_cert;
-    HASH_FIND_STR(id_certs, keyid, id_cert);
+    abac_id_cert_t *id_cert=_lookup_cert(id_certs,keyid);
     if(id_cert == NULL) return NULL;
     return id_cert->cert;
@@ -142,5 +139,5 @@
  * Load an ID cert from a file.
  */
-int abac_verifier_load_id_file(char *filename) {
+int abac_verifier_load_id_file(abac_list_t *id_certs,char *filename) {
     // load the cert
     abac_id_t *cert = abac_id_from_file(filename);
@@ -149,5 +146,5 @@
         return ABAC_CERT_INVALID;
 
-    return _load_id(cert);
+    return _load_id(id_certs,cert);
 }
 
@@ -155,5 +152,5 @@
  * Load an ID cert from a chunk.
  */
-int abac_verifier_load_id_chunk(abac_chunk_t chunk) {
+int abac_verifier_load_id_chunk(abac_list_t *id_certs,abac_chunk_t chunk) {
 
     // load the cert
@@ -162,5 +159,5 @@
     if (cert == NULL)
         return ABAC_CERT_INVALID;
-    return _load_id(cert);
+    return _load_id(id_certs,cert);
 }
 
@@ -169,5 +166,7 @@
  * this is called from parse_privilege(..)
  */
-int abac_verifier_load_id_chars(char *naked_pem) {
+int abac_verifier_load_id_chars(void *id_certs,char *naked_pem) {
+    /* if id_certs is NULL, don't even try to load it */
+    if(id_certs == NULL) return ABAC_CERT_SUCCESS;
     /* make a well formed pem from this */
     char *new_naked_pem=abac_xstrdup(naked_pem);
@@ -176,5 +175,5 @@
     abac_chunk_t chunk = { pem, len }; 
     free(new_naked_pem);
-    return abac_verifier_load_id_chunk(chunk);
+    return abac_verifier_load_id_chunk((abac_list_t *)id_certs,chunk);
 }
 /**
@@ -183,5 +182,5 @@
  * authority.
  */
-static int _load_attribute_cert(abac_attribute_t *cert, abac_credential_t **cred_ret) {
+static int _load_attribute_cert(abac_list_t *id_certs,abac_attribute_t *cert, abac_credential_t **cred_ret) {
     abac_role_t *head_role = NULL;
     abac_role_t *tail_role = NULL;
@@ -220,5 +219,5 @@
 
     char *principal = abac_role_principal(head_role);
-    HASH_FIND_STR(id_certs, principal, issuer);
+    issuer=_lookup_cert(id_certs,principal);
     if (issuer == NULL) {
         ret = ABAC_CERT_MISSING_ISSUER;
@@ -257,5 +256,5 @@
 }
 
-static int _load_attribute_certs(abac_list_t *attr_list, abac_list_t *cred_list) {
+static int _load_attribute_certs(abac_list_t *id_certs,abac_list_t *attr_list, abac_list_t *cred_list) {
 
     int sz=abac_list_size(attr_list);
@@ -264,5 +263,5 @@
     if(sz) { 
         abac_list_foreach(attr_list, attr,
-            int ret=_load_attribute_cert(attr, &cred_ret);
+            int ret=_load_attribute_cert(id_certs, attr, &cred_ret);
             if(ret==ABAC_CERT_SUCCESS) {
                 abac_list_add(cred_list, cred_ret);
@@ -276,13 +275,13 @@
  * Load an attribute cert from a file.
  */
-int abac_verifier_load_attribute_cert_file(char *filename, abac_list_t *cred_list) {
+int abac_verifier_load_attribute_cert_file(abac_list_t *id_certs,char *filename, abac_list_t *cred_list) {
 
     // load the cert
-    abac_list_t *attr_list = abac_attribute_certs_from_file(filename);
+    abac_list_t *attr_list = abac_attribute_certs_from_file(id_certs,filename);
 
     if (abac_list_size(attr_list) == 0)
         return ABAC_CERT_INVALID;
 
-    int ret=_load_attribute_certs(attr_list, cred_list);
+    int ret=_load_attribute_certs(id_certs,attr_list, cred_list);
 
     if(ret) return ABAC_CERT_SUCCESS;
@@ -293,13 +292,13 @@
  * Load an attribute cert from a chunk.
  */
-int abac_verifier_load_attribute_cert_chunk(abac_chunk_t chunk, abac_list_t *cred_list) {
+int abac_verifier_load_attribute_cert_chunk(abac_list_t *id_certs,abac_chunk_t chunk, abac_list_t *cred_list) {
 
     // load the cert
-    abac_list_t *attr_list = abac_attribute_certs_from_chunk(chunk);
+    abac_list_t *attr_list = abac_attribute_certs_from_chunk(id_certs,chunk);
 
     if (abac_list_size(attr_list) == 0)
         return ABAC_CERT_INVALID;
 
-    int ret=_load_attribute_certs(attr_list,cred_list);
+    int ret=_load_attribute_certs(id_certs,attr_list,cred_list);
 
     if(ret) return ABAC_CERT_SUCCESS;
@@ -348,4 +347,15 @@
 }
 
+abac_id_cert_t *abac_id_cert_dup(abac_id_cert_t *id_cert) {
+    assert(id_cert != NULL && id_cert->keyid!=NULL);
+
+    abac_id_cert_t *new_cert = abac_xmalloc(sizeof(abac_id_cert_t));
+    new_cert->keyid=abac_xstrdup(id_cert->keyid);
+    new_cert->cert=abac_id_dup(id_cert->cert);
+ 
+    return new_cert;
+}
+
+
 /**
  * Decrease the reference count of a credential, freeing it when it reaches 0.
@@ -366,2 +376,24 @@
     free(cred);
 }
+
+/**
+ * remove an id cert, (not reference counted, so abac_id_certs are 
+ * deep-copied)
+ */
+void abac_id_cert_free(abac_id_cert_t *id_cert) {
+    if (id_cert==NULL)
+        return;
+
+    abac_id_free(id_cert->cert);
+    if(id_cert->keyid) free(id_cert->keyid);
+    free(id_cert);
+}
+
+char *abac_id_cert_keyid(abac_id_cert_t *id_cert)
+{
+    assert(id_cert);
+    return id_cert->keyid;
+}
+
+
+
