refactored credential builder
authorMartin Willi <martin@strongswan.org>
Tue, 2 Sep 2008 11:00:13 +0000 (11:00 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 2 Sep 2008 11:00:13 +0000 (11:00 -0000)
allow enumeration of matching builders
try a second builder if the first one fails
builder clones resources internally on demand
caller frees added resources on failure and success
stricter handling of non-supported build parts

29 files changed:
src/charon/credentials/credential_manager.c
src/charon/credentials/sets/auth_info_wrapper.c
src/charon/encoding/payloads/cert_payload.c
src/charon/plugins/medcli/medcli_creds.c
src/charon/plugins/medsrv/medsrv_creds.c
src/charon/plugins/sql/sql_cred.c
src/charon/plugins/stroke/stroke_cred.c
src/charon/plugins/unit_tester/Makefile.am
src/charon/plugins/unit_tester/tests.h
src/charon/plugins/unit_tester/tests/test_agent.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_auth_info.c
src/charon/plugins/unit_tester/tests/test_rsa_gen.c
src/libstrongswan/credentials/builder.c
src/libstrongswan/credentials/builder.h
src/libstrongswan/credentials/credential_factory.c
src/libstrongswan/credentials/credential_factory.h
src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
src/libstrongswan/plugins/pubkey/pubkey_cert.c
src/libstrongswan/plugins/pubkey/pubkey_public_key.c
src/libstrongswan/plugins/x509/x509_ac.c
src/libstrongswan/plugins/x509/x509_cert.c
src/libstrongswan/plugins/x509/x509_crl.c
src/libstrongswan/plugins/x509/x509_ocsp_request.c
src/libstrongswan/plugins/x509/x509_ocsp_response.c

index 48d066e..74593aa 100644 (file)
@@ -474,8 +474,8 @@ static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
        /* TODO: requestor name, signature */
        request = lib->creds->create(lib->creds,
                                                CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
-                                               BUILD_CA_CERT, issuer->get_ref(issuer),
-                                               BUILD_CERT, subject->get_ref(subject), BUILD_END);
+                                               BUILD_CA_CERT, issuer,
+                                               BUILD_CERT, subject, BUILD_END);
        if (!request)
        {
                DBG1(DBG_CFG, "generating ocsp request failed");
@@ -500,6 +500,7 @@ static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
        response = lib->creds->create(lib->creds,
                                                                  CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
                                                                  BUILD_BLOB_ASN1_DER, receive, BUILD_END);
+       chunk_free(&receive);
        if (!response)
        {
                DBG1(DBG_CFG, "parsing ocsp response failed");
index 9307ff2..7ec75be 100644 (file)
@@ -83,6 +83,7 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
        
        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                                          BUILD_BLOB_ASN1_DER, data, BUILD_END);
+       free(data.ptr);
        
        if (!cert)
        {
index 4534118..ef6e99d 100644 (file)
@@ -229,7 +229,7 @@ static certificate_t *get_cert(private_cert_payload_t *this)
                return NULL;
        }
        return lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-                                                         BUILD_BLOB_ASN1_DER, chunk_clone(this->data),
+                                                         BUILD_BLOB_ASN1_DER, this->data,
                                                          BUILD_END);
 }
 
index 685f342..1e99f69 100644 (file)
@@ -63,7 +63,7 @@ static bool private_enumerator_enumerate(private_enumerator_t *this,
        while (this->inner->enumerate(this->inner, &chunk))
        {
                this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-                                                                                  BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+                                                                                  BUILD_BLOB_ASN1_DER, chunk,
                                                                                   BUILD_END);
                if (this->current)
                {
@@ -143,7 +143,7 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
        while (this->inner->enumerate(this->inner, &chunk))
        {
                public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
-                                                                       BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+                                                                       BUILD_BLOB_ASN1_DER, chunk,
                                                                        BUILD_END);
                if (public)
                {
@@ -152,14 +152,17 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
                                this->current = lib->creds->create(lib->creds,
                                                                                CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
                                                                                BUILD_PUBLIC_KEY, public, BUILD_END);
+                               public->destroy(public);
                                if (this->current)
                                {
                                        *cert = this->current;
                                        return TRUE;
                                }
-                               continue;
                        }
-                       public->destroy(public);
+                       else
+                       {
+                               public->destroy(public);
+                       }
                }
        }
        this->current = NULL;
index decd381..b88ff22 100644 (file)
@@ -67,7 +67,7 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
        while (this->inner->enumerate(this->inner, &chunk))
        {
                public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
-                                                                       BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+                                                                       BUILD_BLOB_ASN1_DER, chunk,
                                                                        BUILD_END);
                if (public)
                {
@@ -76,14 +76,17 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
                                trusted = lib->creds->create(lib->creds,
                                                                                CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
                                                                                BUILD_PUBLIC_KEY, public, BUILD_END);
+                               public->destroy(public);
                                if (trusted)
                                {
                                        *cert = this->current = trusted;
                                        return TRUE;
                                }
-                               continue;
                        }
-                       public->destroy(public);
+                       else
+                       {
+                               public->destroy(public);
+                       }
                }
        }
        this->current = NULL;
index 9d91973..7313b7e 100644 (file)
@@ -64,7 +64,7 @@ static bool private_enumerator_enumerate(private_enumerator_t *this,
        while (this->inner->enumerate(this->inner, &type, &blob))
        {
                this->current = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
-                                                                                  BUILD_BLOB_ASN1_DER, chunk_clone(blob),
+                                                                                  BUILD_BLOB_ASN1_DER, blob,
                                                                                   BUILD_END);
                if (this->current)
                {
@@ -150,7 +150,7 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
        while (this->inner->enumerate(this->inner, &type, &blob))
        {
                this->current = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
-                                                                                  BUILD_BLOB_ASN1_DER, chunk_clone(blob),
+                                                                                  BUILD_BLOB_ASN1_DER, blob,
                                                                                   BUILD_END);
                if (this->current)
                {
index ad93576..c699a08 100644 (file)
@@ -783,6 +783,7 @@ static void load_secrets(private_stroke_cred_t *this)
                        {
                                key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
                                                                                 BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+                               free(chunk.ptr);
                                if (key)
                                {
                                        DBG1(DBG_CFG, "  loaded private key file '%s'", path);
index ff3d770..238e5a1 100644 (file)
@@ -17,6 +17,8 @@ libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \
   tests/test_med_db.c \
   tests/test_aes.c \
   tests/test_chunk.c \
-  tests/test_pool.c
+  tests/test_pool.c \
+  tests/test_agent.c
+
 libstrongswan_unit_tester_la_LDFLAGS = -module
 
index e36000b..f15d4af 100644 (file)
@@ -37,4 +37,5 @@ DEFINE_TEST("Mediation database key fetch", test_med_db, FALSE)
 DEFINE_TEST("AES-128 encryption", test_aes128, FALSE)
 DEFINE_TEST("AES-XCBC", test_aes_xcbc, FALSE)
 DEFINE_TEST("Base64 converter", test_chunk_base64, FALSE)
-DEFINE_TEST("IP pool", test_pool, TRUE)
+DEFINE_TEST("IP pool", test_pool, FALSE)
+DEFINE_TEST("SSH agent", test_agent, TRUE)
diff --git a/src/charon/plugins/unit_tester/tests/test_agent.c b/src/charon/plugins/unit_tester/tests/test_agent.c
new file mode 100644 (file)
index 0000000..fd76b9c
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * 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 <library.h>
+#include <daemon.h>
+
+/*******************************************************************************
+ * SSH agent signature creation and verification
+ ******************************************************************************/
+bool test_agent()
+{
+       char *path, buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+       chunk_t sig, data = chunk_from_buf(buf);
+       private_key_t *private;
+       public_key_t *public;
+       
+       path = getenv("SSH_AUTH_SOCK");
+       if (!path)
+       {
+               DBG1(DBG_CFG, "ssh-agent not found.");
+               return FALSE;
+       }
+       
+       private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                                                BUILD_AGENT_SOCKET, path, BUILD_END);
+       if (!private)
+       {
+               return FALSE;
+       }
+       if (!private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, data, &sig))
+       {
+               return FALSE;
+       }
+       public = private->get_public_key(private);
+       if (!public)
+       {
+               return FALSE;;
+       }
+       if (!public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
+       {
+               return FALSE;
+       }
+       free(sig.ptr);
+       buf[1] = 0x01; /* fake it */
+       if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
+       {
+               return FALSE;
+       }
+       
+       private->destroy(private);
+       public->destroy(public);
+       
+       return TRUE;
+}
+
index 2640c95..1719190 100644 (file)
@@ -85,7 +85,7 @@ bool test_auth_info()
        auth_item_t type;
        
        c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-                                                       BUILD_BLOB_ASN1_DER, chunk_clone(certchunk),
+                                                       BUILD_BLOB_ASN1_DER, certchunk,
                                                        BUILD_END);
        if (!c1)
        {
index 783a4c9..f13bb5b 100644 (file)
@@ -97,7 +97,7 @@ bool test_rsa_load_any()
        public_key_t *public;
        
        public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
-                                                               BUILD_BLOB_ASN1_DER, chunk_clone(chunk),
+                                                               BUILD_BLOB_ASN1_DER, chunk,
                                                                BUILD_END);
        if (!public || public->get_keysize(public) != 256)
        {
index c13a8a8..c4f3d4f 100644 (file)
@@ -15,8 +15,9 @@
 
 #include "builder.h"
 
-ENUM(builder_part_names, BUILD_BLOB_ASN1_DER, BUILD_END,
+ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
        "BUILD_FROM_FILE",
+       "BUILD_AGENT_SOCKET",
        "BUILD_BLOB_ASN1_DER",
        "BUILD_BLOB_ASN1_PEM",
        "BUILD_KEY_SIZE",
index 22c106b..8e0c513 100644 (file)
@@ -40,6 +40,8 @@ typedef builder_t* (*builder_constructor_t)(int subtype);
 enum builder_part_t {
        /** path to a file containing an ASN1 blob, char* */
        BUILD_FROM_FILE,
+       /** unix socket of a ssh/pgp agent, char* */
+       BUILD_AGENT_SOCKET,
        /** DER encoded ASN1 blob, chunk_t */
        BUILD_BLOB_ASN1_DER,
        /** PEM encoded ASN1 blob, null terminated char* */
@@ -94,8 +96,8 @@ struct builder_t {
        /**
         * Add a part to the construct.
         *
-        * Any added parts get owned by the builder/construct, so clone/refcount
-        * them if needed.
+        * Any added parts are cloned/refcounted by the builder implementation, a 
+        * caller may need to free the passed ressources themself.
         *
         * @param part          kind of part
         * @param ...           part specific variable argument
@@ -112,4 +114,10 @@ struct builder_t {
        void* (*build)(builder_t *this);
 };
 
+/**
+ * Helper macro to cancel a build in a builder
+ */
+#define builder_cancel(builder) { (builder)->add = (void*)nop; \
+                                                                 (builder)->build = (void*)free; }
+
 #endif /* BUILDER_H_ @}*/
index 951ddb5..8527599 100644 (file)
@@ -62,31 +62,36 @@ struct entry_t {
 };
 
 /**
- * Implementation of credential_factory_t.create_builder.
+ * type/subtype filter function for builder_enumerator
  */
-static builder_t* create_builder(private_credential_factory_t *this,
-                                                                credential_type_t type, int subtype)
+static bool builder_filter(entry_t *data, entry_t **in, builder_t **out)
 {
-       enumerator_t *enumerator;
-       entry_t *entry;
-       builder_t *builder = NULL;
-       
-       this->mutex->lock(this->mutex);
-       enumerator = this->constructors->create_enumerator(this->constructors);
-       while (enumerator->enumerate(enumerator, &entry))
+       if (data->type == (*in)->type &&
+               data->subtype == (*in)->subtype)
        {
-               if (entry->type == type && entry->subtype == subtype)
-               {
-                       builder = entry->constructor(subtype);
-                       if (builder)
-                       {
-                               break;
-                       }
-               }
+               *out = (*in)->constructor(data->subtype);
+               return TRUE;
        }
-       enumerator->destroy(enumerator);
-       this->mutex->unlock(this->mutex);
-       return builder;
+       return FALSE;
+}
+
+/**
+ * Implementation of credential_factory_t.create_builder_enumerator.
+ */
+static enumerator_t* create_builder_enumerator(
+               private_credential_factory_t *this,     credential_type_t type, int subtype)
+{
+       entry_t *data = malloc_thing(entry_t);
+       
+       data->type = type;
+       data->subtype = subtype;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_cleaner(
+                               enumerator_create_filter(
+                                       this->constructors->create_enumerator(this->constructors),
+                                       (void*)builder_filter, data, free), 
+                               (void*)this->mutex->unlock, this->mutex);
 }
 
 /**
@@ -135,18 +140,19 @@ static void remove_builder(private_credential_factory_t *this,
 static void* create(private_credential_factory_t *this, credential_type_t type,
                                        int subtype, ...)
 {
+       enumerator_t *enumerator;
        builder_t *builder;
        builder_part_t part;
        va_list args;
+       void* construct = NULL;
        
-       builder = create_builder(this, type, subtype);
-       if (builder)
+       enumerator = create_builder_enumerator(this, type, subtype);
+       while (enumerator->enumerate(enumerator, &builder))
        {
                va_start(args, subtype);
                while (TRUE)
                {
                        part = va_arg(args, builder_part_t);
-               
                        switch (part)
                        {
                                case BUILD_END:
@@ -167,6 +173,7 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
                                        continue;
                                case BUILD_BLOB_ASN1_PEM:
                                case BUILD_FROM_FILE:
+                               case BUILD_AGENT_SOCKET:
                                case BUILD_SIGNING_KEY:
                                case BUILD_PUBLIC_KEY:
                                case BUILD_SUBJECT:
@@ -179,105 +186,25 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
                                case BUILD_IETF_GROUP_ATTR:
                                        builder->add(builder, part, va_arg(args, void*));
                                        continue;
-                               default:
-                                       DBG1("builder part %N not supported by factory",
-                                                builder_part_names, part);
-                                       break;
+                               /* no default to get a compiler warning */
                        }
                        break;
                }
                va_end(args);
-       
-               return builder->build(builder);
-       }
-       else
-       {
-               DBG1("failed to create a builder for credential type %N,"
-                               " subtype (%d)", credential_type_names, type, subtype);
-       }
-       
-       /** shredder all data on failure */
-       va_start(args, subtype);
-       while (TRUE)
-       {
-               part = va_arg(args, builder_part_t);
                
-               switch (part)
+               construct = builder->build(builder);
+               if (construct)
                {
-                       case BUILD_END:
-                               break;
-                       case BUILD_BLOB_ASN1_DER:
-                       {
-                               chunk_t chunk = va_arg(args, chunk_t);
-                               free(chunk.ptr);
-                               continue;
-                       }
-                       case BUILD_SERIAL:
-                       {
-                               va_arg(args, chunk_t);
-                               continue;
-                       }
-                       case BUILD_X509_FLAG:
-                       {
-                               va_arg(args, x509_flag_t);
-                               continue;
-                       }
-                       case BUILD_KEY_SIZE:
-                       {
-                               va_arg(args, u_int);
-                               continue;
-                       }
-                       case BUILD_NOT_BEFORE_TIME:
-                       case BUILD_NOT_AFTER_TIME:
-                       {
-                               va_arg(args, time_t);
-                               continue;
-                       }
-                       case BUILD_SIGNING_KEY:
-                       {
-                               private_key_t *private = va_arg(args, private_key_t*);
-                               private->destroy(private);
-                               continue;
-                       }
-                       case BUILD_PUBLIC_KEY:
-                       {
-                               public_key_t *public = va_arg(args, public_key_t*);
-                               public->destroy(public);
-                               continue;
-                       }
-                       case BUILD_SUBJECT:
-                       case BUILD_SUBJECT_ALTNAME:
-                       case BUILD_ISSUER:
-                       case BUILD_ISSUER_ALTNAME:
-                       {
-                               identification_t *id = va_arg(args, identification_t*);
-                               id->destroy(id);
-                               continue;
-                       }
-                       case BUILD_SIGNING_CERT:
-                       case BUILD_CA_CERT:
-                       case BUILD_CERT:
-                       {
-                               certificate_t *cert = va_arg(args, certificate_t*);
-                               cert->destroy(cert);
-                               continue;
-                       }
-                       case BUILD_BLOB_ASN1_PEM:
-                       case BUILD_FROM_FILE:
-                       case BUILD_IETF_GROUP_ATTR:
-                       {
-                               va_arg(args, void*);
-                               continue;
-                       }
-                       default:
-                               DBG1("builder part %N not supported by factory",
-                                        builder_part_names, part);
-                               continue;
+                       break;
                }
-               break;
        }
-       va_end(args);
-       return NULL;
+       enumerator->destroy(enumerator);
+       if (!construct)
+       {
+               DBG1("failed to create a builder for credential type %N,"
+                        " subtype (%d)", credential_type_names, type, subtype);
+       }
+       return construct;
 }
 
 /**
@@ -298,7 +225,7 @@ credential_factory_t *credential_factory_create()
        private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
 
        this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
-       this->public.create_builder = (builder_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder;
+       this->public.create_builder_enumerator = (enumerator_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder_enumerator;
        this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
        this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
        this->public.destroy = (void(*)(credential_factory_t*))destroy;
index 873cf8a..dc4d626 100644 (file)
@@ -56,6 +56,9 @@ struct credential_factory_t {
         *
         * The variable argument list takes builder_part_t types followed
         * by the type specific value. The list must be terminated using BUILD_END.
+        * All passed parts get cloned/refcounted by the builder implementations,
+        * so free up allocated ressources after successful and unsuccessful
+        * invocations.
         *
         * @param type                  credential type to build
         * @param subtype               subtype specific for type of the credential
@@ -66,14 +69,18 @@ struct credential_factory_t {
                                        int subtype, ...);
        
        /**
-        * Create a builder instance to build credentials.
+        * Create an enumerator for a builder type.
+        *
+        * The build() method has to be called on each enumerated builder to 
+        * cleanup associated ressources. 
         *
         * @param type                  type of credentials the builder creates
         * @param subtype               type specific subtype, such as certificate_type_t
-        * @return                              builder instance
+        * @return                              enumerator over builder_t
         */
-       builder_t* (*create_builder)(credential_factory_t *this,
-                                                                credential_type_t type, int subtype);
+       enumerator_t* (*create_builder_enumerator)(credential_factory_t *this,
+                                                                               credential_type_t type, int subtype);
+       
        /**
         * Register a builder_t constructor function.
         *
index 7d9cd10..c3fc464 100644 (file)
@@ -789,34 +789,37 @@ static gmp_rsa_private_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
+       if (!this->key)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
+               chunk_t chunk;
        
-       switch (part)
-       {
-               case BUILD_BLOB_ASN1_DER:
-               {
-                       va_start(args, part);
-                       this->key = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
-               }               
-               case BUILD_KEY_SIZE:
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = generate(va_arg(args, u_int));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->key = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }               
+                       case BUILD_KEY_SIZE:
+                       {
+                               va_start(args, part);
+                               this->key = generate(va_arg(args, u_int));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_gmp_rsa_private_key_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index 761a676..f58e28f 100644 (file)
@@ -541,27 +541,30 @@ static gmp_rsa_public_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
+       if (!this->key)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
+               chunk_t chunk;
        
-       switch (part)
-       {
-               case BUILD_BLOB_ASN1_DER:
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->key = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_gmp_rsa_public_key_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index b29440a..fa16fe2 100644 (file)
@@ -399,27 +399,30 @@ static openssl_ec_private_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
-       {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
-       
-       switch (part)
+       if (!this->key)
        {
-               case BUILD_BLOB_ASN1_DER:
+               va_list args;
+               chunk_t chunk;
+               
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->key = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_openssl_ec_private_key_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index 0377023..ae5ede2 100644 (file)
@@ -401,27 +401,30 @@ static openssl_ec_public_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
+       if (!this->key)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
+               chunk_t chunk;
        
-       switch (part)
-       {
-               case BUILD_BLOB_ASN1_DER:
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->key = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_openssl_ec_public_key_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index efc3ba6..fd10ab9 100644 (file)
@@ -369,34 +369,37 @@ static openssl_rsa_private_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
+       if (!this->key)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
+               chunk_t chunk;
        
-       switch (part)
-       {
-               case BUILD_BLOB_ASN1_DER:
-               {
-                       va_start(args, part);
-                       this->key = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
-               }               
-               case BUILD_KEY_SIZE:
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = generate(va_arg(args, u_int));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->key = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }               
+                       case BUILD_KEY_SIZE:
+                       {
+                               va_start(args, part);
+                               this->key = generate(va_arg(args, u_int));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_openssl_rsa_private_key_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index b1c2a03..756a033 100644 (file)
@@ -387,27 +387,30 @@ static openssl_rsa_public_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
+       if (!this->key)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
+               chunk_t chunk;
        
-       switch (part)
-       {
-               case BUILD_BLOB_ASN1_DER:
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->key = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_openssl_rsa_public_key_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index 63dffb4..6305f46 100644 (file)
@@ -238,27 +238,28 @@ static pubkey_cert_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
+       if (!this->key)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
        
-       switch (part)
-       {
-               case BUILD_PUBLIC_KEY:
+               switch (part)
                {
-                       va_start(args, part);
-                       this->key = pubkey_cert_create(va_arg(args, public_key_t*));
-                       va_end(args);
-                       break;
+                       case BUILD_PUBLIC_KEY:
+                       {
+                               va_start(args, part);
+                               this->key = pubkey_cert_create(va_arg(args, public_key_t*));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->key)
+       {
+               destroy((private_pubkey_cert_t*)this->key);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index 5a072c4..0bb3d71 100644 (file)
@@ -67,9 +67,8 @@ static public_key_t *load(chunk_t blob)
                                else if (oid == OID_EC_PUBLICKEY)
                                {
                                        /* we need the whole subjectPublicKeyInfo for EC public keys */
-                                       key = lib->creds->create(lib->creds,
-                                                               CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
-                                                               chunk_clone(blob), BUILD_END);
+                                       key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, 
+                                                               KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                                        goto end;
                                }
                                else
@@ -86,8 +85,7 @@ static public_key_t *load(chunk_t blob)
                                        object = chunk_skip(object, 1);
                                }
                                key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
-                                                                                BUILD_BLOB_ASN1_DER, chunk_clone(object),
-                                                                                BUILD_END);
+                                                                                BUILD_BLOB_ASN1_DER, object, BUILD_END);
                                break;
                }
        } 
@@ -125,41 +123,43 @@ static public_key_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->key)
-       {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
-       va_start(args, part);
-       switch (part)
+       if (!this->key)
        {
-               case BUILD_BLOB_ASN1_DER:
+               va_list args;
+               chunk_t blob;
+               
+               switch (part)
                {
-                       this->key = load(va_arg(args, chunk_t));
-                       break;
-               }
-               case BUILD_BLOB_ASN1_PEM:
-               {
-                       bool pgp;
-                       char *pem;
-                       chunk_t blob;
-                       
-                       pem = va_arg(args, char *);
-                       blob = chunk_clone(chunk_create(pem, strlen(pem)));
-                       if (pem_to_bin(&blob, &chunk_empty, &pgp))
+                       case BUILD_BLOB_ASN1_DER:
                        {
+                               va_start(args, part);
+                               blob = va_arg(args, chunk_t);
                                this->key = load(chunk_clone(blob));
+                               va_end(args);
+                               return;
                        }
-                       free(blob.ptr);
-                       break;
+                       case BUILD_BLOB_ASN1_PEM:
+                       {
+                               bool pgp;
+                               char *pem;
+                       
+                               va_start(args, part);
+                               pem = va_arg(args, char *);
+                               blob = chunk_clone(chunk_create(pem, strlen(pem)));
+                               if (pem_to_bin(&blob, &chunk_empty, &pgp))
+                               {
+                                       this->key = load(chunk_clone(blob));
+                               }
+                               free(blob.ptr);
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
-       va_end(args);
+       DESTROY_IF(this->key);
+       builder_cancel(&this->public);
 }
 
 /**
index cfa38c6..caae5e0 100644 (file)
@@ -1054,6 +1054,7 @@ static void add(private_builder_t *this, builder_part_t part, ...)
 {
        va_list args;
        certificate_t *cert;
+       chunk_t chunk;
 
        va_start(args, part);
        switch (part)
@@ -1070,7 +1071,8 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        {
                                destroy(this->ac);
                        }
-                       this->ac = create_from_chunk(va_arg(args, chunk_t));
+                       chunk = va_arg(args, chunk_t);
+                       this->ac = create_from_chunk(chunk_clone(chunk));
                        break;
                case BUILD_NOT_BEFORE_TIME:
                        this->ac->notBefore = va_arg(args, time_t);
@@ -1079,7 +1081,8 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        this->ac->notAfter = va_arg(args, time_t);
                        break;
                case BUILD_SERIAL:
-                       this->ac->serialNumber = va_arg(args, chunk_t);
+                       chunk = va_arg(args, chunk_t);
+                       this->ac->serialNumber = chunk_clone(chunk);
                        break;
                case BUILD_IETF_GROUP_ATTR:
                        ietfAttr_list_create_from_string(va_arg(args, char*),
@@ -1089,29 +1092,27 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        cert = va_arg(args, certificate_t*);
                        if (cert->get_type(cert) == CERT_X509)
                        {
-                               this->ac->holderCert = cert;
-                       }
-                       else
-                       {
-                               cert->destroy(cert);
+                               this->ac->holderCert = cert->get_ref(cert);
                        }
                        break;
                case BUILD_SIGNING_CERT:
                        cert = va_arg(args, certificate_t*);
                        if (cert->get_type(cert) == CERT_X509)
                        {
-                               this->ac->signerCert = cert;
-                       }
-                       else
-                       {
-                               cert->destroy(cert);
+                               this->ac->signerCert = cert->get_ref(cert);
                        }
                        break;
                case BUILD_SIGNING_KEY:
                        this->ac->signerKey = va_arg(args, private_key_t*);
+                       this->ac->signerKey->get_ref(this->ac->signerKey);
                        break;
                default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       /* abort if unsupported option */
+                       if (this->ac)
+                       {
+                               destroy(this->ac);
+                       }
+                       builder_cancel(&this->public);
                        break;
        }
        va_end(args);
index d604b5e..d403386 100644 (file)
@@ -722,7 +722,7 @@ static bool parse_certificate(private_x509_cert_t *this)
                                break;
                        case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
                                this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
-                                               KEY_ANY, BUILD_BLOB_ASN1_DER, chunk_clone(object), BUILD_END);
+                                               KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
                                if (this->public_key == NULL)
                                {
                                        DBG1("could not create public key");
@@ -1251,6 +1251,7 @@ static private_x509_cert_t *build(private_builder_t *this)
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
        va_list args;
+       chunk_t chunk;
        
        va_start(args, part);
        switch (part)
@@ -1259,13 +1260,19 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        this->cert = create_from_file(va_arg(args, char*));
                        break;
                case BUILD_BLOB_ASN1_DER:
-                       this->cert = create_from_chunk(va_arg(args, chunk_t));
+                       chunk = va_arg(args, chunk_t);
+                       this->cert = create_from_chunk(chunk_clone(chunk));
                        break;
                case BUILD_X509_FLAG:
                        this->flags = va_arg(args, x509_flag_t);
                        break;
                default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       /* abort if unsupported option */
+                       if (this->cert)
+                       {
+                               destroy(this->cert);
+                       }
+                       builder_cancel(&this->public);
                        break;
        }
        va_end(args);
index 83496cb..4977934 100644 (file)
@@ -693,30 +693,37 @@ static private_x509_crl_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->crl)
+       if (!this->crl)
        {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
+               va_list args;
+               chunk_t chunk;
        
-       va_start(args, part);
-       switch (part)
-       {
-               case BUILD_FROM_FILE:
-                       this->crl = create_from_file(va_arg(args, char*));
-                       break;
-               case BUILD_BLOB_ASN1_DER:
+               switch (part)
                {
-                       this->crl = create_from_chunk(va_arg(args, chunk_t));
-                       break;
+                       case BUILD_FROM_FILE:
+                       {
+                               va_start(args, part);
+                               this->crl = create_from_file(va_arg(args, char*));
+                               va_end(args);
+                               return;
+                       }
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->crl = create_from_chunk(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
-       va_end(args);
+       if (this->crl)
+       {
+               destroy(this->crl);
+       }
+       builder_cancel(&this->public);
 }
 
 /**
index 0fc5b9d..c97c306 100644 (file)
@@ -547,6 +547,8 @@ static void add(private_builder_t *this, builder_part_t part, ...)
 {
        va_list args;
        certificate_t *cert;
+       identification_t *subject;
+       private_key_t *private;
        
        va_start(args, part);
        switch (part)
@@ -555,35 +557,36 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        cert = va_arg(args, certificate_t*);
                        if (cert->get_type(cert) == CERT_X509)
                        {
-                               this->req->ca = (x509_t*)cert;
-                       }
-                       else
-                       {
-                               cert->destroy(cert);
+                               this->req->ca = (x509_t*)cert->get_ref(cert);
                        }
                        break;
                case BUILD_CERT:
                        cert = va_arg(args, certificate_t*);
                        if (cert->get_type(cert) == CERT_X509)
                        {
-                               this->req->candidates->insert_last(this->req->candidates, cert);
-                       }
-                       else
-                       {
-                               cert->destroy(cert);
+                               this->req->candidates->insert_last(this->req->candidates,
+                                                                                                  cert->get_ref(cert));
                        }
                        break;
                case BUILD_SIGNING_CERT:
-                       this->req->cert = va_arg(args, certificate_t*);
+                       cert = va_arg(args, certificate_t*);
+                       this->req->cert = cert->get_ref(cert);
                        break;
                case BUILD_SIGNING_KEY:
-                       this->req->key = va_arg(args, private_key_t*);
+                       private = va_arg(args, private_key_t*);
+                       this->req->key = private->get_ref(private);
                        break;
                case BUILD_SUBJECT:
-                       this->req->requestor = va_arg(args, identification_t*);
+                       subject = va_arg(args, identification_t*);
+                       this->req->requestor = subject->clone(subject);
                        break;
                default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       /* cancel if option not supported */
+                       if (this->req)
+                       {
+                               destroy(this->req);
+                       }
+                       builder_cancel(&this->public);
                        break;
        }
        va_end(args);
index 3fd293d..8214d91 100644 (file)
@@ -560,8 +560,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
                        case BASIC_RESPONSE_CERTIFICATE:
                        {
                                cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
-                                                                                 BUILD_BLOB_ASN1_DER,
-                                                                                 chunk_clone(object),
+                                                                                 BUILD_BLOB_ASN1_DER, object,
                                                                                  BUILD_END);
                                if (cert)
                                {
@@ -944,27 +943,30 @@ static x509_ocsp_response_t *build(private_builder_t *this)
  */
 static void add(private_builder_t *this, builder_part_t part, ...)
 {
-       va_list args;
-       
-       if (this->res)
-       {
-               DBG1("ignoring surplus build part %N", builder_part_names, part);
-               return;
-       }
-       
-       switch (part)
+       if (!this->res)
        {
-               case BUILD_BLOB_ASN1_DER:
+               va_list args;
+               chunk_t chunk;
+               
+               switch (part)
                {
-                       va_start(args, part);
-                       this->res = load(va_arg(args, chunk_t));
-                       va_end(args);
-                       break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               va_start(args, part);
+                               chunk = va_arg(args, chunk_t);
+                               this->res = load(chunk_clone(chunk));
+                               va_end(args);
+                               return;
+                       }
+                       default:
+                               break;
                }
-               default:
-                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
-                       break;
        }
+       if (this->res)
+       {
+               destroy((private_x509_ocsp_response_t*)this->res);
+       }
+       builder_cancel(&this->public);
 }
 
 /**