Updated openssl plugin to the new builder API
authorMartin Willi <martin@strongswan.org>
Wed, 9 Sep 2009 14:21:21 +0000 (16:21 +0200)
committerMartin Willi <martin@strongswan.org>
Thu, 10 Sep 2009 14:20:19 +0000 (16:20 +0200)
src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
src/libstrongswan/plugins/openssl/openssl_plugin.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h

index c6e651e..8533140 100644 (file)
@@ -295,12 +295,33 @@ static private_openssl_ec_private_key_t *create_empty(void)
 }
 
 /**
- * Generate an ECDSA key of specified key size
+ * See header.
  */
-static openssl_ec_private_key_t *generate(size_t key_size)
+openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type,
+                                                                                                        va_list args)
 {
-       private_openssl_ec_private_key_t *this = create_empty();
+       private_openssl_ec_private_key_t *this;
+       u_int key_size = 0;
 
+       while (TRUE)
+       {
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_KEY_SIZE:
+                               key_size = va_arg(args, u_int);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
+       }
+       if (!key_size)
+       {
+               return NULL;
+       }
+       this = create_empty();
        switch (key_size)
        {
                case 256:
@@ -330,104 +351,41 @@ static openssl_ec_private_key_t *generate(size_t key_size)
 }
 
 /**
- * load private key from an ASN1 encoded blob
+ * See header.
  */
-static openssl_ec_private_key_t *load(chunk_t blob)
+openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
+                                                                                                         va_list args)
 {
-       private_openssl_ec_private_key_t *this = create_empty();
-
-       this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
+       private_openssl_ec_private_key_t *this;
+       chunk_t blob = chunk_empty;
 
-       if (!this->ec)
-       {
-               destroy(this);
-               return NULL;
-       }
-       if (!EC_KEY_check_key(this->ec))
+       while (TRUE)
        {
-               destroy(this);
-               return NULL;
-       }
-       return &this->public;
-}
-
-typedef struct private_builder_t private_builder_t;
-
-/**
- * Builder implementation for key loading/generation
- */
-struct private_builder_t {
-       /** implements the builder interface */
-       builder_t public;
-       /** loaded/generated private key */
-       openssl_ec_private_key_t *key;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static openssl_ec_private_key_t *build(private_builder_t *this)
-{
-       openssl_ec_private_key_t *key = this->key;
-
-       free(this);
-       return key;
-}
-
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
-       if (!this->key)
-       {
-               va_list args;
-
-               switch (part)
+               switch (va_arg(args, builder_part_t))
                {
-                       case BUILD_KEY_SIZE:
-                       {
-                               va_start(args, part);
-                               this->key = generate(va_arg(args, u_int));
-                               va_end(args);
-                               return;
-                       }
                        case BUILD_BLOB_ASN1_DER:
-                       {
-                               va_start(args, part);
-                               this->key = load(va_arg(args, chunk_t));
-                               va_end(args);
-                               return;
-                       }
-                       default:
+                               blob = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_END:
                                break;
+                       default:
+                               return NULL;
                }
+               break;
        }
-       if (this->key)
+
+       this = create_empty();
+       this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
+       if (!this->ec)
        {
-               destroy((private_openssl_ec_private_key_t*)this->key);
+               destroy(this);
+               return NULL;
        }
-       builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *openssl_ec_private_key_builder(key_type_t type)
-{
-       private_builder_t *this;
-
-       if (type != KEY_ECDSA)
+       if (!EC_KEY_check_key(this->ec))
        {
+               destroy(this);
                return NULL;
        }
-
-       this = malloc_thing(private_builder_t);
-
-       this->key = NULL;
-       this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
-       this->public.build = (void*(*)(builder_t *this))build;
-
        return &this->public;
 }
 
index 6a6f7c8..720c63f 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef OPENSSL_EC_PRIVATE_KEY_H_
 #define OPENSSL_EC_PRIVATE_KEY_H_
 
+#include <credentials/builder.h>
 #include <credentials/keys/private_key.h>
 
 typedef struct openssl_ec_private_key_t openssl_ec_private_key_t;
@@ -37,11 +38,27 @@ struct openssl_ec_private_key_t {
 };
 
 /**
- * Create the builder for a private key.
+ * Generate a ECDSA private key using OpenSSL.
+ *
+ * Accepts the BUILD_KEY_SIZE argument.
+ *
+ * @param type         type of the key, must be KEY_ECDSA
+ * @param args         builder_part_t argument list
+ * @return                     generated key, NULL on failure
+ */
+openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type,
+                                                                                                        va_list args);
+
+/**
+ * Load a ECDSA private key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
  *
  * @param type         type of the key, must be KEY_ECDSA
- * @return                     builder instance
+ * @param args         builder_part_t argument list
+ * @return                     loaded key, NULL on failure
  */
-builder_t *openssl_ec_private_key_builder(key_type_t type);
+openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
+                                                                                                         va_list args);
 
 #endif /** OPENSSL_EC_PRIVATE_KEY_H_ @}*/
index b0b2c9b..f553c26 100644 (file)
@@ -308,93 +308,40 @@ static private_openssl_ec_public_key_t *create_empty()
 }
 
 /**
- * Load a public key from an ASN1 encoded blob
+ * See header.
  */
-static openssl_ec_public_key_t *load(chunk_t blob)
+openssl_ec_public_key_t *openssl_ec_public_key_load(key_type_t type,
+                                                                                                       va_list args)
 {
-       private_openssl_ec_public_key_t *this = create_empty();
-       u_char *p = blob.ptr;
+       private_openssl_ec_public_key_t *this;
+       chunk_t blob = chunk_empty;
 
-       this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&p, blob.len);
-
-       if (!this->ec)
+       if (type != KEY_ECDSA)
        {
-               destroy(this);
                return NULL;
        }
-       return &this->public;
-}
-
-typedef struct private_builder_t private_builder_t;
 
-/**
- * Builder implementation for key loading
- */
-struct private_builder_t {
-       /** implements the builder interface */
-       builder_t public;
-       /** loaded public key */
-       openssl_ec_public_key_t *key;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static openssl_ec_public_key_t *build(private_builder_t *this)
-{
-       openssl_ec_public_key_t *key = this->key;
-
-       free(this);
-       return key;
-}
-
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
-       if (!this->key)
+       while (TRUE)
        {
-               va_list args;
-
-               switch (part)
+               switch (va_arg(args, builder_part_t))
                {
                        case BUILD_BLOB_ASN1_DER:
-                       {
-                               va_start(args, part);
-                               this->key = load(va_arg(args, chunk_t));
-                               va_end(args);
-                               return;
-                       }
-                       default:
+                               blob = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_END:
                                break;
+                       default:
+                               return NULL;
                }
+               break;
        }
-       if (this->key)
-       {
-               destroy((private_openssl_ec_public_key_t*)this->key);
-       }
-       builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *openssl_ec_public_key_builder(key_type_t type)
-{
-       private_builder_t *this;
-
-       if (type != KEY_ECDSA)
+       this = create_empty();
+       this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&blob.ptr, blob.len);
+       if (!this->ec)
        {
+               destroy(this);
                return NULL;
        }
-
-       this = malloc_thing(private_builder_t);
-
-       this->key = NULL;
-       this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
-       this->public.build = (void*(*)(builder_t *this))build;
-
        return &this->public;
 }
 
index bdbb2fe..29d607d 100644 (file)
@@ -23,6 +23,7 @@
 
 typedef struct openssl_ec_public_key_t openssl_ec_public_key_t;
 
+#include <credentials/builder.h>
 #include <credentials/keys/public_key.h>
 
 /**
@@ -37,11 +38,15 @@ struct openssl_ec_public_key_t {
 };
 
 /**
- * Create the builder for a public key.
+ * Load a ECDSA public key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
  *
  * @param type         type of the key, must be KEY_ECDSA
- * @return                     builder instance
+ * @param args         builder_part_t argument list
+ * @return                     loaded key, NULL on failure
  */
-builder_t *openssl_ec_public_key_builder(key_type_t type);
+openssl_ec_public_key_t *openssl_ec_public_key_load(key_type_t type,
+                                                                                                       va_list args);
 
 #endif /** OPENSSL_EC_PUBLIC_KEY_H_ @}*/
index 1cc6f7c..a6089c8 100644 (file)
@@ -175,13 +175,19 @@ static void destroy(private_openssl_plugin_t *this)
        lib->crypto->remove_dh(lib->crypto,
                                        (dh_constructor_t)openssl_ec_diffie_hellman_create);
        lib->creds->remove_builder(lib->creds,
-                                       (builder_constructor_t)openssl_rsa_private_key_builder);
+                                       (builder_function_t)openssl_rsa_private_key_load);
        lib->creds->remove_builder(lib->creds,
-                                       (builder_constructor_t)openssl_rsa_public_key_builder);
+                                       (builder_function_t)openssl_rsa_private_key_gen);
        lib->creds->remove_builder(lib->creds,
-                                       (builder_constructor_t)openssl_ec_private_key_builder);
+                                       (builder_function_t)openssl_rsa_private_key_connect);
        lib->creds->remove_builder(lib->creds,
-                                       (builder_constructor_t)openssl_ec_public_key_builder);
+                                       (builder_function_t)openssl_rsa_public_key_load);
+       lib->creds->remove_builder(lib->creds,
+                                       (builder_function_t)openssl_ec_private_key_load);
+       lib->creds->remove_builder(lib->creds,
+                                       (builder_function_t)openssl_ec_private_key_gen);
+       lib->creds->remove_builder(lib->creds,
+                                       (builder_function_t)openssl_ec_public_key_load);
 
        ENGINE_cleanup();
        EVP_cleanup();
@@ -282,15 +288,22 @@ plugin_t *plugin_create()
 
        /* rsa */
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-                                               (builder_constructor_t)openssl_rsa_private_key_builder);
+                                       (builder_function_t)openssl_rsa_private_key_load);
+       lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                       (builder_function_t)openssl_rsa_private_key_gen);
+       lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                       (builder_function_t)openssl_rsa_private_key_connect);
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
-                                               (builder_constructor_t)openssl_rsa_public_key_builder);
+                                       (builder_function_t)openssl_rsa_public_key_load);
 
        /* ec */
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
-                                               (builder_constructor_t)openssl_ec_private_key_builder);
+                                       (builder_function_t)openssl_ec_private_key_load);
+       lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+                                       (builder_function_t)openssl_ec_private_key_gen);
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
-                                               (builder_constructor_t)openssl_ec_public_key_builder);
+                                       (builder_function_t)openssl_ec_public_key_load);
 
        return &this->public.plugin;
 }
+
index c689878..ce65cdd 100644 (file)
@@ -288,26 +288,64 @@ static private_openssl_rsa_private_key_t *create_empty(void)
 }
 
 /**
- * Generate an RSA key of specified key size
+ * See header.
  */
-static openssl_rsa_private_key_t *generate(size_t key_size)
+openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type,
+                                                                                                          va_list args)
 {
-       private_openssl_rsa_private_key_t *this = create_empty();
+       private_openssl_rsa_private_key_t *this;
+       u_int key_size = 0;
 
+       while (TRUE)
+       {
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_KEY_SIZE:
+                               key_size = va_arg(args, u_int);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
+       }
+       if (!key_size)
+       {
+               return NULL;
+       }
+       this = create_empty();
        this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL);
 
        return &this->public;
 }
 
 /**
- * load private key from an ASN1 encoded blob
+ * See header
  */
-static openssl_rsa_private_key_t *load(chunk_t blob)
+openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
+                                                                                                               va_list args)
 {
-       u_char *p = blob.ptr;
-       private_openssl_rsa_private_key_t *this = create_empty();
+       private_openssl_rsa_private_key_t *this;
+       chunk_t blob = chunk_empty;
 
-       this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&p, blob.len);
+       while (TRUE)
+       {
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_BLOB_ASN1_DER:
+                               blob = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
+       }
+
+       this = create_empty();
+       this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
        if (!this->rsa)
        {
                destroy(this);
@@ -322,41 +360,67 @@ static openssl_rsa_private_key_t *load(chunk_t blob)
 }
 
 /**
- * load private key from a smart card
+ * See header.
  */
-static openssl_rsa_private_key_t *load_from_smartcard(char *keyid, char *pin)
+openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
+                                                                                                                  va_list args)
 {
-       private_openssl_rsa_private_key_t *this = NULL;
+       private_openssl_rsa_private_key_t *this;
+       char *keyid = NULL, *pin = NULL;
        EVP_PKEY *key;
-       char *engine_id = lib->settings->get_str(lib->settings,
-                                                               "library.plugins.openssl.engine_id", "pkcs11");
+       char *engine_id;
+       ENGINE *engine;
+
+       while (TRUE)
+       {
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_SMARTCARD_KEYID:
+                               keyid = va_arg(args, char*);
+                               continue;
+                       case BUILD_SMARTCARD_PIN:
+                               pin = va_arg(args, char*);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
+       }
+       if (!keyid || !pin)
+       {
+               return NULL;
+       }
 
-       ENGINE *engine = ENGINE_by_id(engine_id);
+       engine_id = lib->settings->get_str(lib->settings,
+                                                               "library.plugins.openssl.engine_id", "pkcs11");
+       engine = ENGINE_by_id(engine_id);
        if (!engine)
        {
                DBG1("engine '%s' is not available", engine_id);
                return NULL;
        }
-
        if (!ENGINE_init(engine))
        {
                DBG1("failed to initialize engine '%s'", engine_id);
-               goto error;
+               ENGINE_free(engine);
+               return NULL;
        }
-
        if (!ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
        {
                DBG1("failed to set PIN on engine '%s'", engine_id);
-               goto error;
+               ENGINE_free(engine);
+               return NULL;
        }
 
        key = ENGINE_load_private_key(engine, keyid, NULL, NULL);
-
        if (!key)
        {
-               DBG1("failed to load private key with ID '%s' from engine '%s'", keyid,
-                               engine_id);
-               goto error;
+               DBG1("failed to load private key with ID '%s' from engine '%s'",
+                        keyid, engine_id);
+               ENGINE_free(engine);
+               return NULL;
        }
        ENGINE_free(engine);
 
@@ -365,113 +429,5 @@ static openssl_rsa_private_key_t *load_from_smartcard(char *keyid, char *pin)
        this->engine = TRUE;
 
        return &this->public;
-
-error:
-       ENGINE_free(engine);
-       return NULL;
-}
-
-typedef struct private_builder_t private_builder_t;
-
-/**
- * Builder implementation for key loading/generation
- */
-struct private_builder_t {
-       /** implements the builder interface */
-       builder_t public;
-       /** loaded/generated private key */
-       openssl_rsa_private_key_t *key;
-       /** temporary stored smartcard key ID */
-       char *keyid;
-       /** temporary stored smartcard pin */
-       char *pin;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static openssl_rsa_private_key_t *build(private_builder_t *this)
-{
-       openssl_rsa_private_key_t *key = this->key;
-
-       if (this->keyid && this->pin)
-       {
-               key = load_from_smartcard(this->keyid, this->pin);
-       }
-       free(this);
-       return key;
-}
-
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
-       if (!this->key)
-       {
-               va_list args;
-
-               switch (part)
-               {
-                       case BUILD_BLOB_ASN1_DER:
-                       {
-                               va_start(args, part);
-                               this->key = load(va_arg(args, chunk_t));
-                               va_end(args);
-                               return;
-                       }
-                       case BUILD_KEY_SIZE:
-                       {
-                               va_start(args, part);
-                               this->key = generate(va_arg(args, u_int));
-                               va_end(args);
-                               return;
-                       }
-                       case BUILD_SMARTCARD_KEYID:
-                       {
-                               va_start(args, part);
-                               this->keyid = va_arg(args, char*);
-                               va_end(args);
-                               return;
-                       }
-                       case BUILD_SMARTCARD_PIN:
-                       {
-                               va_start(args, part);
-                               this->pin = va_arg(args, char*);
-                               va_end(args);
-                               return;
-                       }
-                       default:
-                               break;
-               }
-       }
-       if (this->key)
-       {
-               destroy((private_openssl_rsa_private_key_t*)this->key);
-       }
-       builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *openssl_rsa_private_key_builder(key_type_t type)
-{
-       private_builder_t *this;
-
-       if (type != KEY_RSA)
-       {
-               return NULL;
-       }
-
-       this = malloc_thing(private_builder_t);
-
-       this->key = NULL;
-       this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
-       this->public.build = (void*(*)(builder_t *this))build;
-       this->keyid = NULL;
-       this->pin = NULL;
-
-       return &this->public;
 }
 
index 53ec44b..079dfa4 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef OPENSSL_RSA_PRIVATE_KEY_H_
 #define OPENSSL_RSA_PRIVATE_KEY_H_
 
+#include <credentials/builder.h>
 #include <credentials/keys/private_key.h>
 
 typedef struct openssl_rsa_private_key_t openssl_rsa_private_key_t;
@@ -37,11 +38,40 @@ struct openssl_rsa_private_key_t {
 };
 
 /**
- * Create the builder for a private key.
+ * Generate a RSA private key using OpenSSL.
+ *
+ * Accepts the BUILD_KEY_SIZE argument.
+ *
+ * @param type         type of the key, must be KEY_RSA
+ * @param args         builder_part_t argument list
+ * @return                     generated key, NULL on failure
+ */
+openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type,
+                                                                                                          va_list args);
+
+/**
+ * Load a RSA private key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
+ *
+ * @param type         type of the key, must be KEY_RSA
+ * @param args         builder_part_t argument list
+ * @return                     loaded key, NULL on failure
+ */
+openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
+                                                                                                               va_list args);
+
+/**
+ * Connect to a RSA private key on a smartcard.
+ *
+ * Accepts the BUILD_SMARTCARD_KEYID and the BUILD_SMARTCARD_PIN
+ * arguments.
  *
  * @param type         type of the key, must be KEY_RSA
- * @return                     builder instance
+ * @param args         builder_part_t argument list
+ * @return                     loaded key, NULL on failure
  */
-builder_t *openssl_rsa_private_key_builder(key_type_t type);
+openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
+                                                                                                                  va_list args);
 
 #endif /** OPENSSL_RSA_PRIVATE_KEY_H_ @}*/
index e30ab85..67c2e47 100644 (file)
@@ -298,93 +298,36 @@ static private_openssl_rsa_public_key_t *create_empty()
 }
 
 /**
- * Load a public key from an ASN1 encoded blob
+ * See header.
  */
-static openssl_rsa_public_key_t *load(chunk_t blob)
+openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type,
+                                                                                                         va_list args)
 {
-       u_char *p = blob.ptr;
-       private_openssl_rsa_public_key_t *this = create_empty();
+       private_openssl_rsa_public_key_t *this;
+       chunk_t blob;
 
-       this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len);
-       if (!this->rsa)
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
-typedef struct private_builder_t private_builder_t;
-
-/**
- * Builder implementation for key loading
- */
-struct private_builder_t {
-       /** implements the builder interface */
-       builder_t public;
-       /** loaded public key */
-       openssl_rsa_public_key_t *key;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static openssl_rsa_public_key_t *build(private_builder_t *this)
-{
-       openssl_rsa_public_key_t *key = this->key;
-
-       free(this);
-       return key;
-}
-
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
-       if (!this->key)
+       while (TRUE)
        {
-               va_list args;
-
-               switch (part)
+               switch (va_arg(args, builder_part_t))
                {
                        case BUILD_BLOB_ASN1_DER:
-                       {
-                               va_start(args, part);
-                               this->key = load(va_arg(args, chunk_t));
-                               va_end(args);
-                               return;
-                       }
-                       default:
+                               blob = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_END:
                                break;
+                       default:
+                               return NULL;
                }
+               break;
        }
-       if (this->key)
-       {
-               destroy((private_openssl_rsa_public_key_t*)this->key);
-       }
-       builder_cancel(&this->public);
-}
 
-/**
- * Builder construction function
- */
-builder_t *openssl_rsa_public_key_builder(key_type_t type)
-{
-       private_builder_t *this;
-
-       if (type != KEY_RSA)
+       this = create_empty();
+       this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&blob.ptr, blob.len);
+       if (!this->rsa)
        {
+               destroy(this);
                return NULL;
        }
-
-       this = malloc_thing(private_builder_t);
-
-       this->key = NULL;
-       this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
-       this->public.build = (void*(*)(builder_t *this))build;
-
        return &this->public;
 }
 
index ff99ddb..620aa51 100644 (file)
@@ -37,11 +37,15 @@ struct openssl_rsa_public_key_t {
 };
 
 /**
- * Create the builder for a public key.
+ * Load a RSA public key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
  *
  * @param type         type of the key, must be KEY_RSA
- * @return                     builder instance
+ * @param args         builder_part_t argument list
+ * @return                     loaded key, NULL on failure
  */
-builder_t *openssl_rsa_public_key_builder(key_type_t type);
+openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type,
+                                                                                                         va_list args);
 
 #endif /** OPENSSL_RSA_PUBLIC_KEY_H_ @}*/