diff options
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_builder.c | 232 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_builder.h | 35 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_plugin.c | 44 |
3 files changed, 128 insertions, 183 deletions
diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index 7320bae88..c53e1e9cd 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -33,37 +33,10 @@ #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); } diff --git a/src/libstrongswan/plugins/pem/pem_builder.h b/src/libstrongswan/plugins/pem/pem_builder.h index 22099ee39..cfff39125 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.h +++ b/src/libstrongswan/plugins/pem/pem_builder.h @@ -21,40 +21,37 @@ #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_ @}*/ diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index a0ecec826..2a24e681c 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -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; } |