Implement TKM-specific credential set
authorReto Buerki <reet@codelabs.ch>
Tue, 18 Dec 2012 14:35:40 +0000 (15:35 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:50 +0000 (15:23 +0100)
The TKM credential set extends the in-memory credential set. It
provides a private key enumerator which is used to instantiate private
key proxy objects on-demand. This allows the usage of private keys with
arbitrary identifiers.

src/charon-tkm/src/charon-tkm.c
src/charon-tkm/src/tkm/tkm_cred.c [new file with mode: 0644]
src/charon-tkm/src/tkm/tkm_cred.h [new file with mode: 0644]
src/charon-tkm/src/tkm/tkm_private_key.c
src/charon-tkm/src/tkm/tkm_private_key.h

index eac9a27..7afde6e 100644 (file)
@@ -32,7 +32,7 @@
 #include <utils/backtrace.h>
 #include <threading/thread.h>
 #include <sa/keymat.h>
-#include <credentials/sets/mem_cred.h>
+#include <credentials/credential_manager.h>
 
 #include "tkm.h"
 #include "tkm_nonceg.h"
@@ -41,7 +41,7 @@
 #include "tkm_listener.h"
 #include "tkm_kernel_ipsec.h"
 #include "tkm_public_key.h"
-#include "tkm_private_key.h"
+#include "tkm_cred.h"
 
 /**
  * TKM bus listener for IKE authorize events.
@@ -240,9 +240,8 @@ int main(int argc, char *argv[])
                dmn_name = "charon-tkm";
        }
 
-       /* credential set and TKM private key */
-       mem_cred_t *creds;
-       tkm_private_key_t *key;
+       /* TKM credential set */
+       tkm_cred_t *creds;
 
        struct sigaction action;
        int status = SS_RC_INITIALIZATION_FAILED;
@@ -347,10 +346,8 @@ int main(int argc, char *argv[])
        listener = tkm_listener_create();
        charon->bus->add_listener(charon->bus, &listener->listener);
 
-       /* register TKM private key */
-       creds = mem_cred_create();
-       key = tkm_private_key_init();
-       creds->add_key(creds, (private_key_t *)key);
+       /* register TKM credential set */
+       creds = tkm_cred_create();
        lib->credmgr->add_set(lib->credmgr, (credential_set_t*)creds);
 
        /* add handler for SEGV and ILL,
diff --git a/src/charon-tkm/src/tkm/tkm_cred.c b/src/charon-tkm/src/tkm/tkm_cred.c
new file mode 100644 (file)
index 0000000..cf591d4
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <credentials/sets/mem_cred.h>
+#include <collections/hashtable.h>
+#include <threading/rwlock.h>
+#include <utils/debug.h>
+
+#include "tkm_private_key.h"
+#include "tkm_cred.h"
+
+typedef struct private_tkm_cred_t private_tkm_cred_t;
+
+/**
+ * Private data of a tkm_cred_t object.
+ */
+struct private_tkm_cred_t {
+
+       /**
+        * Public tkm_cred_t interface.
+        */
+       tkm_cred_t public;
+
+       /**
+        * In-memory credential set.
+        */
+       mem_cred_t *creds;
+
+       /**
+        * Key-id hashtable.
+        */
+       hashtable_t *known_keys;
+
+       /**
+        * rwlock for hashtable.
+        */
+       rwlock_t *lock;
+
+};
+
+METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
+       private_tkm_cred_t *this, key_type_t type, identification_t *id)
+{
+       if (!id)
+       {
+               return this->known_keys->create_enumerator(this->known_keys);
+       }
+
+       identification_t *entry;
+       this->lock->write_lock(this->lock);
+       entry = this->known_keys->get(this->known_keys, id);
+
+       if (!entry)
+       {
+               identification_t *clone = id->clone(id);
+               DBG1(DBG_CFG, "adding private key proxy for id '%Y'", clone);
+               tkm_private_key_t *key = tkm_private_key_init(id);
+               if (!key)
+               {
+                       DBG1(DBG_CFG, "unable to create private key for id '%Y'", clone);
+                       this->lock->unlock(this->lock);
+                       return NULL;
+               }
+               this->creds->add_key(this->creds, (private_key_t *)key);
+               entry = this->known_keys->put(this->known_keys, clone, clone);
+       }
+       this->lock->unlock(this->lock);
+
+       return this->creds->set.create_private_enumerator(&this->creds->set,
+                                                                                                         type, id);
+}
+
+METHOD(tkm_cred_t, destroy, void,
+       private_tkm_cred_t *this)
+{
+       enumerator_t *enumerator;
+       identification_t *entry;
+
+       enumerator = this->known_keys->create_enumerator(this->known_keys);
+       while (enumerator->enumerate(enumerator, NULL, &entry))
+       {
+               entry->destroy(entry);
+       }
+       enumerator->destroy(enumerator);
+       this->known_keys->destroy(this->known_keys);
+
+       this->creds->destroy(this->creds);
+       this->lock->destroy(this->lock);
+       free(this);
+}
+
+/**
+ * Hashtable hash function.
+ */
+static u_int hash(identification_t *id)
+{
+       return chunk_hash(id->get_encoding(id));
+}
+
+/**
+ * Hashtable equals function.
+ */
+static bool equals(identification_t *a, identification_t *b)
+{
+       return a->equals(a, b);
+}
+
+/**
+ * See header
+ */
+tkm_cred_t *tkm_cred_create()
+{
+       private_tkm_cred_t *this;
+
+       INIT(this,
+               .public = {
+                       .set = {
+                               .create_shared_enumerator = (void*)return_null,
+                               .create_private_enumerator = _create_private_enumerator,
+                               .create_cert_enumerator = (void*)return_null,
+                               .create_cdp_enumerator = (void*)return_null,
+                               .cache_cert = (void*)nop,
+                       },
+                       .destroy = _destroy,
+               },
+               .creds = mem_cred_create(),
+               .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+               .known_keys = hashtable_create((hashtable_hash_t)hash,
+                                                                          (hashtable_equals_t)equals, 4),
+       );
+
+       return &this->public;
+}
diff --git a/src/charon-tkm/src/tkm/tkm_cred.h b/src/charon-tkm/src/tkm/tkm_cred.h
new file mode 100644 (file)
index 0000000..362e228
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef TKM_CRED_H_
+#define TKM_CRED_H_
+
+typedef struct tkm_cred_t tkm_cred_t;
+
+#include <credentials/credential_set.h>
+
+/**
+ * TKM in-memory credential set.
+ */
+struct tkm_cred_t {
+
+       /**
+        * Implements credential_set_t.
+        */
+       credential_set_t set;
+
+       /**
+        * Destroy a tkm_cred_t.
+        */
+       void (*destroy)(tkm_cred_t *this);
+
+};
+
+/**
+ * Create a tkm_cred instance.
+ */
+tkm_cred_t *tkm_cred_create();
+
+#endif /** TKM_CRED_H_ */
index d728f8d..6169414 100644 (file)
@@ -35,9 +35,9 @@ struct private_tkm_private_key_t {
        tkm_private_key_t public;
 
        /**
-        * Key fingerprint.
+        * Key ID.
         */
-       chunk_t fingerprint;
+       identification_t *id;
 
        /**
         * Reference count.
@@ -109,7 +109,7 @@ METHOD(private_key_t, get_encoding, bool,
 METHOD(private_key_t, get_fingerprint, bool,
        private_tkm_private_key_t *this, cred_encoding_type_t type, chunk_t *fp)
 {
-       *fp = this->fingerprint;
+       *fp = this->id->get_encoding(this->id);
        return TRUE;
 }
 
@@ -125,7 +125,7 @@ METHOD(private_key_t, destroy, void,
 {
        if (ref_put(&this->ref))
        {
-               chunk_free(&this->fingerprint);
+               this->id->destroy(this->id);
                free(this);
        }
 }
@@ -133,7 +133,7 @@ METHOD(private_key_t, destroy, void,
 /**
  * See header.
  */
-tkm_private_key_t *tkm_private_key_init(void)
+tkm_private_key_t *tkm_private_key_init(identification_t * const id)
 {
        private_tkm_private_key_t *this;
 
@@ -155,12 +155,8 @@ tkm_private_key_t *tkm_private_key_init(void)
                        },
                },
                .ref = 1,
+               .id = id->clone(id),
        );
 
-       /* fingerprint of alice@strongswan.org keypair */
-       const char fake_fp[] = "05da04208c02f428470acf6c772d066613da863c";
-       this->fingerprint = chunk_create((u_char *)fake_fp, strlen(fake_fp));
-       this->fingerprint = chunk_from_hex(this->fingerprint, NULL);
-
        return &this->public;
 }
index aa472a1..343752f 100644 (file)
@@ -33,8 +33,8 @@ struct tkm_private_key_t {
 };
 
 /**
- * Initialize TKM private key.
+ * Initialize TKM private key with given key ID.
  */
-tkm_private_key_t *tkm_private_key_init(void);
+tkm_private_key_t *tkm_private_key_init(identification_t * const id);
 
 #endif /** TKM_PRIVATE_KEY_H_ */