Updated pem plugin to the new builder API
authorMartin Willi <martin@strongswan.org>
Wed, 9 Sep 2009 14:22:42 +0000 (16:22 +0200)
committerMartin Willi <martin@strongswan.org>
Thu, 10 Sep 2009 14:20:19 +0000 (16:20 +0200)
src/libstrongswan/plugins/pem/pem_builder.c
src/libstrongswan/plugins/pem/pem_builder.h
src/libstrongswan/plugins/pem/pem_plugin.c

index 7320bae..c53e1e9 100644 (file)
 #include <asn1/asn1.h>
 #include <crypto/hashers/hasher.h>
 #include <crypto/crypters/crypter.h>
+#include <credentials/certificates/x509.h>
 
 #define PKCS5_SALT_LEN 8       /* bytes */
 
-typedef struct private_builder_t private_builder_t;
-
-/**
- * Builder implementation for PEM decoding
- */
-struct private_builder_t {
-       /** implements the builder interface */
-       builder_t public;
-       /** credential type we are building */
-       credential_type_t type;
-       /** subtype (keytype, certtype) of the credential we build */
-       int subtype;
-       /** path to file, if we are reading from a file */
-       char *file;
-       /** file description, if we are reading from a fd */
-       int fd;
-       /** PEM encoding of the credential */
-       chunk_t pem;
-       /** PEM decryption passphrase, if given */
-       chunk_t passphrase;
-       /** supplied callback to read passphrase */
-       chunk_t (*cb)(void *data, int try);
-       /** user data to callback */
-       void *data;
-       /** X509 flags to pass along */
-       int flags;
-};
-
 /**
  * check the presence of a pattern in a character string, skip if found
  */
@@ -194,7 +167,8 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
 /**
  * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934)
  */
-status_t pem_to_bin(chunk_t *blob, private_builder_t *this, bool *pgp)
+static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data,
+                                                  bool *pgp)
 {
        typedef enum {
                PEM_PRE    = 0,
@@ -351,14 +325,14 @@ status_t pem_to_bin(chunk_t *blob, private_builder_t *this, bool *pgp)
        {
                return SUCCESS;
        }
-       if (!this->cb)
+       if (!cb)
        {
                DBG1("  missing passphrase");
                return INVALID_ARG;
        }
        while (TRUE)
        {
-               passphrase = this->cb(this->data, ++try);
+               passphrase = cb(cb_data, ++try);
                if (!passphrase.len || !passphrase.ptr)
                {
                        return INVALID_ARG;
@@ -377,9 +351,11 @@ status_t pem_to_bin(chunk_t *blob, private_builder_t *this, bool *pgp)
 }
 
 /**
- * build the credential from a blob
+ * load the credential from a blob
  */
-static void *build_from_blob(private_builder_t *this, chunk_t blob)
+static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
+                                                       chunk_t(*cb)(void*,int), void *cb_data,
+                                                       x509_flag_t flags)
 {
        void *cred = NULL;
        bool pgp = FALSE;
@@ -387,31 +363,33 @@ static void *build_from_blob(private_builder_t *this, chunk_t blob)
        blob = chunk_clone(blob);
        if (!is_asn1(blob))
        {
-               if (pem_to_bin(&blob, this, &pgp) != SUCCESS)
+               if (pem_to_bin(&blob, cb, cb_data, &pgp) != SUCCESS)
                {
                        chunk_clear(&blob);
                        return NULL;
                }
-               if (pgp && this->type == CRED_PRIVATE_KEY)
+               if (pgp && type == CRED_PRIVATE_KEY)
                {
                        /* PGP encoded keys are parsed with a KEY_ANY key type, as it
                         * can contain any type of key. However, ipsec.secrets uses
                         * RSA for PGP keys, which is actually wrong. */
-                       this->subtype = KEY_ANY;
+                       subtype = KEY_ANY;
                }
        }
-       cred = lib->creds->create(lib->creds, this->type, this->subtype,
+       cred = lib->creds->create(lib->creds, type, subtype,
                                                          pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob,
-                                                         this->flags ? BUILD_X509_FLAG : BUILD_END,
-                                                         this->flags, BUILD_END);
+                                                         flags ? BUILD_X509_FLAG : BUILD_END,
+                                                         flags, BUILD_END);
        chunk_clear(&blob);
        return cred;
 }
 
 /**
- * build the credential from a file
+ * load the credential from a file
  */
-static void *build_from_file(private_builder_t *this, char *file)
+static void *load_from_file(char *file, credential_type_t type, int subtype,
+                                                       chunk_t(*cb)(void*,int), void *cb_data,
+                                                       x509_flag_t flags)
 {
        void *cred = NULL;
        struct stat sb;
@@ -440,7 +418,8 @@ static void *build_from_file(private_builder_t *this, char *file)
                return NULL;
        }
 
-       cred = build_from_blob(this, chunk_create(addr, sb.st_size));
+       cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype,
+                                                 cb, cb_data, flags);
 
        munmap(addr, sb.st_size);
        close(fd);
@@ -448,9 +427,11 @@ static void *build_from_file(private_builder_t *this, char *file)
 }
 
 /**
- * build the credential from a file
+ * load the credential from a file descriptor
  */
-static void *build_from_fd(private_builder_t *this, int fd)
+static void *load_from_fd(int fd, credential_type_t type, int subtype,
+                                                 chunk_t(*cb)(void*,int), void *cb_data,
+                                                 x509_flag_t flags)
 {
        char buf[8096];
        char *pos = buf;
@@ -475,30 +456,8 @@ static void *build_from_fd(private_builder_t *this, int fd)
                        return NULL;
                }
        }
-       return build_from_blob(this, chunk_create(buf, total));
-}
-
-/**
- * Implementation of builder_t.build
- */
-static void *build(private_builder_t *this)
-{
-       void *cred = NULL;
-
-       if (this->pem.ptr)
-       {
-               cred = build_from_blob(this, this->pem);
-       }
-       else if (this->file)
-       {
-               cred = build_from_file(this, this->file);
-       }
-       else if (this->fd != -1)
-       {
-               cred = build_from_fd(this, this->fd);
-       }
-       free(this);
-       return cred;
+       return load_from_blob(chunk_create(buf, total), type, subtype,
+                                                 cb, cb_data, flags);
 }
 
 /**
@@ -514,100 +473,89 @@ static chunk_t given_passphrase_cb(chunk_t *passphrase, int try)
 }
 
 /**
- * Implementation of builder_t.add
+ * Load all kind of PEM encoded credentials.
  */
-static void add(private_builder_t *this, builder_part_t part, ...)
+static void *pem_load(credential_type_t type, int subtype, va_list args)
 {
-       va_list args;
+       char *file = NULL;
+       int fd = -1;
+       chunk_t pem = chunk_empty, passphrase = chunk_empty;
+       chunk_t (*cb)(void *data, int try) = NULL;
+       void *cb_data = NULL;
+       int flags = 0;
 
-       switch (part)
+       while (TRUE)
        {
-               case BUILD_FROM_FILE:
-                       va_start(args, part);
-                       this->file = va_arg(args, char*);
-                       va_end(args);
-                       break;
-               case BUILD_FROM_FD:
-                       va_start(args, part);
-                       this->fd = va_arg(args, int);
-                       va_end(args);
-                       break;
-               case BUILD_BLOB_PEM:
-                       va_start(args, part);
-                       this->pem = va_arg(args, chunk_t);
-                       va_end(args);
-                       break;
-               case BUILD_PASSPHRASE:
-                       va_start(args, part);
-                       this->passphrase = va_arg(args, chunk_t);
-                       va_end(args);
-                       if (this->passphrase.len && this->passphrase.ptr)
-                       {
-                               this->cb = (void*)given_passphrase_cb;
-                               this->data = &this->passphrase;
-                       }
-                       break;
-               case BUILD_PASSPHRASE_CALLBACK:
-                       va_start(args, part);
-                       this->cb = va_arg(args, chunk_t(*)(void*,int));
-                       this->data = va_arg(args, void*);
-                       va_end(args);
-                       break;
-               case BUILD_X509_FLAG:
-                       va_start(args, part);
-                       this->flags = va_arg(args, int);
-                       va_end(args);
-                       break;
-               default:
-                       builder_cancel(&this->public);
-                       break;
+               switch (va_arg(args, builder_part_t))
+               {
+                       case BUILD_FROM_FILE:
+                               file = va_arg(args, char*);
+                               continue;
+                       case BUILD_FROM_FD:
+                               fd = va_arg(args, int);
+                               continue;
+                       case BUILD_BLOB_PEM:
+                               pem = va_arg(args, chunk_t);
+                               continue;
+                       case BUILD_PASSPHRASE:
+                               passphrase = va_arg(args, chunk_t);
+                               if (passphrase.len && passphrase.ptr)
+                               {
+                                       cb = (void*)given_passphrase_cb;
+                                       cb_data = &passphrase;
+                               }
+                               continue;
+                       case BUILD_PASSPHRASE_CALLBACK:
+                               cb = va_arg(args, chunk_t(*)(void*,int));
+                               cb_data = va_arg(args, void*);
+                               continue;
+                       case BUILD_X509_FLAG:
+                               flags = va_arg(args, int);
+                               continue;
+                       case BUILD_END:
+                               break;
+                       default:
+                               return NULL;
+               }
+               break;
        }
-}
 
-/**
- * Generic PEM builder.
- */
-static builder_t *pem_builder(credential_type_t type, int subtype)
-{
-       private_builder_t *this = malloc_thing(private_builder_t);
-
-       this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
-       this->public.build = (void*(*)(builder_t *this))build;
-
-       this->type = type;
-       this->subtype = subtype;
-       this->file = NULL;
-       this->fd = -1;
-       this->pem = chunk_empty;
-       this->passphrase = chunk_empty;
-       this->cb = NULL;
-       this->data = NULL;
-       this->flags = 0;
-
-       return &this->public;
+       if (pem.ptr)
+       {
+               return load_from_blob(pem, type, subtype, cb, cb_data, flags);
+       }
+       if (file)
+       {
+               return load_from_file(file, type, subtype, cb, cb_data, flags);
+       }
+       if (fd != -1)
+       {
+               return load_from_fd(fd, type, subtype, cb, cb_data, flags);
+       }
+       return NULL;
 }
 
 /**
- * Private key PEM builder.
+ * Private key PEM loader.
  */
-builder_t *private_key_pem_builder(key_type_t type)
+private_key_t *pem_private_key_load(key_type_t type, va_list args)
 {
-       return pem_builder(CRED_PRIVATE_KEY, type);
+       return pem_load(CRED_PRIVATE_KEY, type, args);
 }
 
 /**
- * Public key PEM builder.
+ * Public key PEM loader.
  */
-builder_t *public_key_pem_builder(key_type_t type)
+public_key_t *pem_public_key_load(key_type_t type, va_list args)
 {
-       return pem_builder(CRED_PUBLIC_KEY, type);
+       return pem_load(CRED_PUBLIC_KEY, type, args);
 }
 
 /**
- * Certificate PEM builder.
+ * Certificate PEM loader.
  */
-builder_t *certificate_pem_builder(certificate_type_t type)
+certificate_t *pem_certificate_load(certificate_type_t type, va_list args)
 {
-       return pem_builder(CRED_CERTIFICATE, type);
+       return pem_load(CRED_CERTIFICATE, type, args);
 }
 
index 22099ee..cfff391 100644 (file)
 #ifndef PEM_PRIVATE_KEY_H_
 #define PEM_PRIVATE_KEY_H_
 
-#include <credentials/certificates/certificate.h>
+#include <credentials/builder.h>
 #include <credentials/credential_factory.h>
+#include <credentials/keys/private_key.h>
+#include <credentials/certificates/certificate.h>
 
 /**
- * Builder for PEM encoded private keys of all kind.
- *
- * @param type         type of the key
- * @return                     builder instance
- */
-builder_t *private_key_pem_builder(key_type_t type);
-
-/**
- * Builder for PEM encoded public keys of all kind.
+ * Load PEM encoded private keys.
  *
  * @param type         type of the key
- * @return                     builder instance
+ * @param args         builder_part_t argument list
+ * @return                     private key, NULL if failed
  */
-builder_t *public_key_pem_builder(key_type_t type);
+private_key_t *pem_private_key_load(key_type_t type, va_list args);
 
 /**
- * Builder for PEM encoded certificates of all kind.
+ * Load PEM encoded public keys.
  *
  * @param type         type of the key
- * @return                     builder instance
+ * @param args         builder_part_t argument list
+ * @return                     public key, NULL if failed
  */
-builder_t *certificate_pem_builder(certificate_type_t type);
+public_key_t *pem_public_key_load(key_type_t type, va_list args);
 
 /**
- * Builder for PEM encoded pluto certificates of all kind.
+ * Build PEM encoded certificates..
  *
- * @param type         type of the key
- * @return                     builder instance
+ * @param type         type of the certificate
+ * @param args         builder_part_t argument list
+ * @return                     certificate, NULL if failed
  */
-builder_t *pluto_pem_builder(certificate_type_t type);
+certificate_t *pem_certificate_load(certificate_type_t type, va_list args);
 
 #endif /** PEM_PRIVATE_KEY_H_ @}*/
 
index a0ecec8..2a24e68 100644 (file)
@@ -37,11 +37,11 @@ struct private_pem_plugin_t {
 static void destroy(private_pem_plugin_t *this)
 {
        lib->creds->remove_builder(lib->creds,
-                                                          (builder_constructor_t)private_key_pem_builder);
+                                                          (builder_function_t)pem_private_key_load);
        lib->creds->remove_builder(lib->creds,
-                                                          (builder_constructor_t)public_key_pem_builder);
+                                                          (builder_function_t)pem_public_key_load);
        lib->creds->remove_builder(lib->creds,
-                                                          (builder_constructor_t)certificate_pem_builder);
+                                                          (builder_function_t)pem_certificate_load);
        free(this);
 }
 
@@ -56,49 +56,49 @@ plugin_t *plugin_create()
 
        /* register private key PEM decoding builders */
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
-                                                       (builder_constructor_t)private_key_pem_builder);
+                                                       (builder_function_t)pem_private_key_load);
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-                                                       (builder_constructor_t)private_key_pem_builder);
+                                                       (builder_function_t)pem_private_key_load);
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
-                                                       (builder_constructor_t)private_key_pem_builder);
+                                                       (builder_function_t)pem_private_key_load);
        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_DSA,
-                                                       (builder_constructor_t)private_key_pem_builder);
+                                                       (builder_function_t)pem_private_key_load);
 
        /* register public key PEM decoding builders */
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
-                                                       (builder_constructor_t)public_key_pem_builder);
+                                                       (builder_function_t)pem_public_key_load);
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
-                                                       (builder_constructor_t)public_key_pem_builder);
+                                                       (builder_function_t)pem_public_key_load);
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
-                                                       (builder_constructor_t)public_key_pem_builder);
+                                                       (builder_function_t)pem_public_key_load);
        lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_DSA,
-                                                       (builder_constructor_t)public_key_pem_builder);
+                                                       (builder_function_t)pem_public_key_load);
 
        /* register certificate PEM decoding builders */
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_ANY,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_GPG,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
 
        /* register pluto specific certificate formats */
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_AC,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
        lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
-                                                       (builder_constructor_t)certificate_pem_builder);
+                                                       (builder_function_t)pem_certificate_load);
 
        return &this->public.plugin;
 }