diff options
author | Graham Leggett <minfrin@apache.org> | 2011-10-23 16:00:54 +0000 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2011-10-23 16:00:54 +0000 |
commit | 814a1cf0d5da68b15035f30fc88da2f6916ed8dc (patch) | |
tree | 87c99d3386508fb5e709fab9a914f5bf9a1a2977 /crypto | |
parent | 5265fe9c3b7a8df613740cc4965b3f0103744f28 (diff) | |
download | apr-814a1cf0d5da68b15035f30fc88da2f6916ed8dc.tar.gz |
apr_crypto: Replace the LDAP inspired constant-based parameter passing with
the apr_dbd inspired string passing, and simplify configuration.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1187914 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/apr_crypto.c | 11 | ||||
-rw-r--r-- | crypto/apr_crypto_nss.c | 95 | ||||
-rw-r--r-- | crypto/apr_crypto_openssl.c | 75 |
3 files changed, 122 insertions, 59 deletions
diff --git a/crypto/apr_crypto.c b/crypto/apr_crypto.c index 48947478a..6af3bcb7e 100644 --- a/crypto/apr_crypto.c +++ b/crypto/apr_crypto.c @@ -116,9 +116,9 @@ APR_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool) { return ret; } -APR_DECLARE(apr_status_t) apr_crypto_get_driver(const apr_crypto_driver_t **driver, - const char *name, const apr_array_header_t *params, const apu_err_t **result, - apr_pool_t *pool) { +APR_DECLARE(apr_status_t) apr_crypto_get_driver( + const apr_crypto_driver_t **driver, const char *name, + const char *params, const apu_err_t **result, apr_pool_t *pool) { #if APR_HAVE_MODULAR_DSO char modname[32]; char symname[34]; @@ -227,9 +227,12 @@ APR_DECLARE(apr_status_t) apr_crypto_error(const apu_err_t **result, * @param pool - process pool * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE * if the engine cannot be initialised. + * @remarks NSS: currently no params are supported. + * @remarks OpenSSL: the params can have "engine" as a key, followed by an equal + * sign and a value. */ APR_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f, const apr_crypto_driver_t *driver, - const apr_array_header_t *params, apr_pool_t *pool) { + const char *params, apr_pool_t *pool) { return driver->make(f, driver, params, pool); } diff --git a/crypto/apr_crypto_nss.c b/crypto/apr_crypto_nss.c index 153dd5c99..36b18afda 100644 --- a/crypto/apr_crypto_nss.c +++ b/crypto/apr_crypto_nss.c @@ -118,7 +118,7 @@ static apr_status_t crypto_shutdown_helper(void *data) /** * Initialise the crypto library and perform one time initialisation. */ -static apr_status_t crypto_init(apr_pool_t *pool, const apr_array_header_t *params, int *rc) +static apr_status_t crypto_init(apr_pool_t *pool, const char *params, int *rc) { SECStatus s; const char *dir = NULL; @@ -126,37 +126,69 @@ static apr_status_t crypto_init(apr_pool_t *pool, const apr_array_header_t *para const char *certPrefix = NULL; const char *secmod = NULL; PRUint32 flags = 0; - struct apr_crypto_param_t *ents = params ? (struct apr_crypto_param_t *)params->elts : NULL; - int i = 0; + + struct { + const char *field; + char *value; + } fields[] = { + {"dir", NULL}, + {"key3", NULL}, + {"cert7", NULL}, + {"secmod", NULL}, + {NULL, NULL} + }; + int i; + const char *ptr; + const char *key; + size_t klen; + const char *value; + size_t vlen; + static const char *const delims = " \r\n\t;|,"; /* sanity check - we can only initialise NSS once */ if (NSS_IsInitialized()) { return APR_EREINIT; } + /* snitch parsing from the MySQL driver */ + for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { + /* don't dereference memory that may not belong to us */ + if (ptr == params) { + ++ptr; + continue; + } + for (key = ptr-1; apr_isspace(*key); --key); + klen = 0; + while (apr_isalpha(*key)) { + if (key == params) { + /* Don't parse off the front of the params */ + --key; + ++klen; + break; + } + --key; + ++klen; + } + ++key; + for (value = ptr+1; apr_isspace(*value); ++value); + vlen = strcspn(value, delims); + for (i=0; fields[i].field != NULL; ++i) { + if (!strncasecmp(fields[i].field, key, klen)) { + fields[i].value = apr_pstrndup(pool, value, vlen); + break; + } + } + ptr = value+vlen; + } + dir = fields[0].value; + keyPrefix = fields[1].value; + certPrefix = fields[2].value; + secmod = fields[3].value; + apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper, apr_pool_cleanup_null); - for (i = 0; params && i < params->nelts; i++) { - switch (ents[i].type) { - case APR_CRYPTO_CA_TYPE_DIR: - dir = ents[i].path; - break; - case APR_CRYPTO_CERT_TYPE_KEY3_DB: - keyPrefix = ents[i].path; - break; - case APR_CRYPTO_CA_TYPE_CERT7_DB: - certPrefix = ents[i].path; - break; - case APR_CRYPTO_CA_TYPE_SECMOD: - secmod = ents[i].path; - break; - default: - return APR_EINIT; - } - } - if (keyPrefix || certPrefix || secmod) { s = NSS_Initialize(dir, certPrefix, keyPrefix, secmod, flags); } @@ -234,17 +266,15 @@ static apr_status_t crypto_cleanup_helper(void *data) * registered with the given pool to guarantee a graceful shutdown. * @param f - context pointer will be written here * @param provider - provider to use - * @param params - array of key parameters + * @param params - parameter string * @param pool - process pool * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE * if the engine cannot be initialised. */ static apr_status_t crypto_make(apr_crypto_t **ff, const apr_crypto_driver_t *provider, - const apr_array_header_t *params, apr_pool_t *pool) + const char *params, apr_pool_t *pool) { apr_crypto_config_t *config = NULL; - /* struct apr_crypto_param_t *ents = params ? (struct apr_crypto_param_t *)params->elts : NULL; */ - /* int i = 0; */ apr_crypto_t *f; f = apr_pcalloc(pool, sizeof(apr_crypto_t)); @@ -285,19 +315,6 @@ static apr_status_t crypto_make(apr_crypto_t **ff, const apr_crypto_driver_t *pr crypto_cleanup_helper, apr_pool_cleanup_null); - /* - for (i = 0; params && i < params->nelts; i++) { - switch (ents[i].type) { - default: - f->result->rc = -1; - f->result->reason = "The NSS module currently supports " - "no per context initialisation parameters at this time, but " - "may do in future."; - return APR_EINIT; - } - } - */ - return APR_SUCCESS; } diff --git a/crypto/apr_crypto_openssl.c b/crypto/apr_crypto_openssl.c index 084d3cae2..d227284e5 100644 --- a/crypto/apr_crypto_openssl.c +++ b/crypto/apr_crypto_openssl.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "apr_lib.h" #include "apu.h" #include "apr_private.h" #include "apu_errno.h" @@ -105,7 +106,7 @@ static apr_status_t crypto_shutdown_helper(void *data) { * Initialise the crypto library and perform one time initialisation. */ static apr_status_t crypto_init(apr_pool_t *pool, - const apr_array_header_t *params, int *rc) { + const char *params, int *rc) { CRYPTO_malloc_init(); ERR_load_crypto_strings(); /* SSL_load_error_strings(); */ @@ -176,13 +177,27 @@ static apr_status_t crypto_cleanup_helper(void *data) { * if the engine cannot be initialised. */ static apr_status_t crypto_make(apr_crypto_t **ff, const apr_crypto_driver_t *provider, - const apr_array_header_t *params, apr_pool_t *pool) + const char *params, apr_pool_t *pool) { apr_crypto_config_t *config = NULL; - struct apr_crypto_param_t *ents = - params ? (struct apr_crypto_param_t *) params->elts : NULL; - int i = 0; apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t)); + + struct { + const char *field; + char *value; + } fields[] = { + {"engine", NULL}, + {NULL, NULL} + }; + int i; + const char *ptr; + const char *key; + size_t klen; + const char *value; + size_t vlen; + static const char *const delims = " \r\n\t;|,"; + const char *engine; + if (!f) { return APR_ENOMEM; } @@ -223,19 +238,47 @@ static apr_status_t crypto_make(apr_crypto_t **ff, const apr_crypto_driver_t *pr apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, apr_pool_cleanup_null); - for (i = 0; params && i < params->nelts; i++) { - switch (ents[i].type) { - case APR_CRYPTO_ENGINE: - config->engine = ENGINE_by_id(ents[i].path); - if (!config->engine) { - return APR_ENOENGINE; + /* snitch parsing from the MySQL driver */ + for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { + /* don't dereference memory that may not belong to us */ + if (ptr == params) { + ++ptr; + continue; + } + for (key = ptr-1; apr_isspace(*key); --key); + klen = 0; + while (apr_isalpha(*key)) { + if (key == params) { + /* Don't parse off the front of the params */ + --key; + ++klen; + break; } - if (!ENGINE_init(config->engine)) { - ENGINE_free(config->engine); - config->engine = NULL; - return APR_EINITENGINE; + --key; + ++klen; + } + ++key; + for (value = ptr+1; apr_isspace(*value); ++value); + vlen = strcspn(value, delims); + for (i=0; fields[i].field != NULL; ++i) { + if (!strncasecmp(fields[i].field, key, klen)) { + fields[i].value = apr_pstrndup(pool, value, vlen); + break; } - break; + } + ptr = value+vlen; + } + engine = fields[0].value; + + if (engine) { + config->engine = ENGINE_by_id(engine); + if (!config->engine) { + return APR_ENOENGINE; + } + if (!ENGINE_init(config->engine)) { + ENGINE_free(config->engine); + config->engine = NULL; + return APR_EINITENGINE; } } |