You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by mi...@apache.org on 2011/10/23 18:39:31 UTC

svn commit: r1187924 - in /apr/apr-util/branches/1.4.x: crypto/apr_crypto.c crypto/apr_crypto_nss.c crypto/apr_crypto_openssl.c include/apr_crypto.h include/private/apr_crypto_internal.h test/testcrypto.c

Author: minfrin
Date: Sun Oct 23 16:39:31 2011
New Revision: 1187924

URL: http://svn.apache.org/viewvc?rev=1187924&view=rev
Log:
Backport to apr-util v1.4 from apr-util v1.5:
apr_crypto: Replace the LDAP inspired constant-based parameter passing with
the apr_dbd inspired string passing, and simplify configuration.

Modified:
    apr/apr-util/branches/1.4.x/crypto/apr_crypto.c
    apr/apr-util/branches/1.4.x/crypto/apr_crypto_nss.c
    apr/apr-util/branches/1.4.x/crypto/apr_crypto_openssl.c
    apr/apr-util/branches/1.4.x/include/apr_crypto.h
    apr/apr-util/branches/1.4.x/include/private/apr_crypto_internal.h
    apr/apr-util/branches/1.4.x/test/testcrypto.c

Modified: apr/apr-util/branches/1.4.x/crypto/apr_crypto.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/crypto/apr_crypto.c?rev=1187924&r1=1187923&r2=1187924&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/crypto/apr_crypto.c (original)
+++ apr/apr-util/branches/1.4.x/crypto/apr_crypto.c Sun Oct 23 16:39:31 2011
@@ -122,9 +122,9 @@ APU_DECLARE(apr_status_t) apr_crypto_ini
     return ret;
 }
 
-APU_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) {
+APU_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 APU_DSO_BUILD
     char modname[32];
     char symname[34];
@@ -233,9 +233,12 @@ APU_DECLARE(apr_status_t) apr_crypto_err
  * @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.
  */
 APU_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);
 }
 

Modified: apr/apr-util/branches/1.4.x/crypto/apr_crypto_nss.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/crypto/apr_crypto_nss.c?rev=1187924&r1=1187923&r2=1187924&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/crypto/apr_crypto_nss.c (original)
+++ apr/apr-util/branches/1.4.x/crypto/apr_crypto_nss.c Sun Oct 23 16:39:31 2011
@@ -118,7 +118,7 @@ static apr_status_t crypto_shutdown_help
 /**
  * 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
     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_helpe
  *        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_cryp
                               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;
 
 }

Modified: apr/apr-util/branches/1.4.x/crypto/apr_crypto_openssl.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/crypto/apr_crypto_openssl.c?rev=1187924&r1=1187923&r2=1187924&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/crypto/apr_crypto_openssl.c (original)
+++ apr/apr-util/branches/1.4.x/crypto/apr_crypto_openssl.c Sun Oct 23 16:39:31 2011
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
+#include "apr_lib.h"
 #include "apu.h"
-#include "apr_private.h"
 #include "apu_errno.h"
 
 #include <ctype.h>
@@ -106,7 +106,7 @@ static apr_status_t crypto_shutdown_help
  * 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(); */
@@ -177,13 +177,27 @@ static apr_status_t crypto_cleanup_helpe
  * 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;
     }
@@ -224,19 +238,47 @@ static apr_status_t crypto_make(apr_cryp
     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;
         }
     }
 

Modified: apr/apr-util/branches/1.4.x/include/apr_crypto.h
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/include/apr_crypto.h?rev=1187924&r1=1187923&r2=1187924&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/include/apr_crypto.h (original)
+++ apr/apr-util/branches/1.4.x/include/apr_crypto.h Sun Oct 23 16:39:31 2011
@@ -37,49 +37,6 @@ extern "C" {
  * @{
  */
 
-/** CA certificate type unknown */
-#define APR_CRYPTO_CA_TYPE_UNKNOWN           0
-/** binary DER encoded CA certificate */
-#define APR_CRYPTO_CA_TYPE_DER               1
-/** PEM encoded CA certificate */
-#define APR_CRYPTO_CA_TYPE_BASE64            2
-/** Netscape/Mozilla cert7.db CA certificate database */
-#define APR_CRYPTO_CA_TYPE_CERT7_DB          3
-/** Netscape/Mozilla secmod file */
-#define APR_CRYPTO_CA_TYPE_SECMOD            4
-/** Client certificate type unknown */
-#define APR_CRYPTO_CERT_TYPE_UNKNOWN         5
-/** binary DER encoded client certificate */
-#define APR_CRYPTO_CERT_TYPE_DER             6
-/** PEM encoded client certificate */
-#define APR_CRYPTO_CERT_TYPE_BASE64          7
-/** Netscape/Mozilla key3.db client certificate database */
-#define APR_CRYPTO_CERT_TYPE_KEY3_DB         8
-/** Netscape/Mozilla client certificate nickname */
-#define APR_CRYPTO_CERT_TYPE_NICKNAME        9
-/** Private key type unknown */
-#define APR_CRYPTO_KEY_TYPE_UNKNOWN          10
-/** binary DER encoded private key */
-#define APR_CRYPTO_KEY_TYPE_DER              11
-/** PEM encoded private key */
-#define APR_CRYPTO_KEY_TYPE_BASE64           12
-/** PKCS#12 encoded client certificate */
-#define APR_CRYPTO_CERT_TYPE_PFX             13
-/** PKCS#12 encoded private key */
-#define APR_CRYPTO_KEY_TYPE_PFX              14
-/** Openldap directory full of base64-encoded cert
- * authorities with hashes in corresponding .0 directory
- */
-#define APR_CRYPTO_CA_TYPE_CACERTDIR_BASE64  15
-/** CMS Key Database with private key and cert chain */
-#define APR_CRYPTO_CA_TYPE_CMS               16
-/** Symmetrical key */
-#define APR_CRYPTO_KEY_TYPE_SYM              17
-/** Netscape/Mozilla certificate database directory */
-#define APR_CRYPTO_CA_TYPE_DIR               18
-/** Crypto engine */
-#define APR_CRYPTO_ENGINE                    101
-
 #if APU_HAVE_CRYPTO
 
 #ifndef APU_CRYPTO_RECOMMENDED_DRIVER
@@ -158,23 +115,6 @@ typedef enum {
 /** Cipher Block Chaining */
 } apr_crypto_block_key_mode_e;
 
-/**
- * Certificate and private key structure.
- *
- * The various crypto backends expect certificates and keys in a wide
- * array of formats. This structure is analogous to apr_ldap_opt_tls_cert_t
- * from the LDAP interface. Ultimately that interface should be meshed with
- * this one.
- * @param type Type of certificate APR_CRYPTO_*_TYPE_*
- * @param path Path, file or nickname of the certificate
- * @param password Optional password, can be NULL
- */
-typedef struct apr_crypto_param_t {
-    int type;
-    const char *path;
-    const char *password;
-} apr_crypto_param_t;
-
 /* These are opaque structs.  Instantiation is up to each backend */
 typedef struct apr_crypto_driver_t apr_crypto_driver_t;
 typedef struct apr_crypto_t apr_crypto_t;
@@ -202,9 +142,13 @@ APU_DECLARE(apr_status_t) apr_crypto_ini
  * @return APR_ENOTIMPL for no driver (when DSO not enabled)
  * @return APR_EDSOOPEN if DSO driver file can't be opened
  * @return APR_ESYMNOTFOUND if the driver file doesn't contain a driver
+ * @remarks NSS: the params can have "dir", "key3", "cert7" and "secmod"
+ *  keys, each followed by an equal sign and a value. Such key/value pairs can
+ *  be delimited by space, CR, LF, tab, semicolon, vertical bar or comma.
+ * @remarks OpenSSL: currently no params are supported.
  */
 APU_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,
+        const char *name, const char *params, const apu_err_t **result,
         apr_pool_t *pool);
 
 /**
@@ -236,9 +180,13 @@ APU_DECLARE(apr_status_t) apr_crypto_err
  * @param pool - process pool
  * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
  * if the engine cannot be initialised.
- */
-APU_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);
+ * @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.
+ */
+APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f,
+        const apr_crypto_driver_t *driver,
+        const char *params, apr_pool_t *pool);
 
 /**
  * @brief Get a hash table of key types, keyed by the name of the type against
@@ -248,7 +196,7 @@ APU_DECLARE(apr_status_t) apr_crypto_mak
  * @param f - encryption context
  * @return APR_SUCCESS for success
  */
-APR_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types,
+APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types,
         const apr_crypto_t *f);
 
 /**
@@ -259,7 +207,7 @@ APR_DECLARE(apr_status_t) apr_crypto_get
  * @param f - encryption context
  * @return APR_SUCCESS for success
  */
-APR_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes,
+APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes,
         const apr_crypto_t *f);
 
 /**

Modified: apr/apr-util/branches/1.4.x/include/private/apr_crypto_internal.h
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/include/private/apr_crypto_internal.h?rev=1187924&r1=1187923&r2=1187924&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/include/private/apr_crypto_internal.h (original)
+++ apr/apr-util/branches/1.4.x/include/private/apr_crypto_internal.h Sun Oct 23 16:39:31 2011
@@ -36,10 +36,10 @@ struct apr_crypto_driver_t {
      * @brief: allow driver to perform once-only initialisation.
      * Called once only.
      * @param pool The pool to register the cleanup in.
-     * @param params An array of optional init parameters.
+     * @param params Optional init parameter string.
      * @param rc Driver-specific additional error code
      */
-    apr_status_t (*init)(apr_pool_t *pool, const apr_array_header_t *params, int *rc);
+    apr_status_t (*init)(apr_pool_t *pool, const char *params, int *rc);
 
     /**
      * @brief Create a context for supporting encryption. Keys, certificates,
@@ -54,7 +54,7 @@ struct apr_crypto_driver_t {
      * if the engine cannot be initialised.
      */
     apr_status_t (*make)(apr_crypto_t **f, const apr_crypto_driver_t *provider,
-            const apr_array_header_t *params, apr_pool_t *pool);
+            const char *params, apr_pool_t *pool);
 
     /**
      * @brief Get a hash table of key types, keyed by the name of the type against

Modified: apr/apr-util/branches/1.4.x/test/testcrypto.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/test/testcrypto.c?rev=1187924&r1=1187923&r2=1187924&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/test/testcrypto.c (original)
+++ apr/apr-util/branches/1.4.x/test/testcrypto.c Sun Oct 23 16:39:31 2011
@@ -29,7 +29,7 @@
 #define ALIGNED_STRING "123456789012345"
 
 static const apr_crypto_driver_t *get_driver(abts_case *tc, apr_pool_t *pool,
-        const char *name, const apr_array_header_t *params) {
+        const char *name, const char *params) {
 
     const apr_crypto_driver_t *driver = NULL;
     const apu_err_t *err = NULL;
@@ -60,15 +60,8 @@ static const apr_crypto_driver_t *get_dr
 static const apr_crypto_driver_t *get_nss_driver(abts_case *tc,
         apr_pool_t *pool) {
 
-    apr_array_header_t *params;
-    apr_crypto_param_t *param;
-
     /* initialise NSS */
-    params = apr_array_make(pool, 10, sizeof(apr_crypto_param_t));
-    param = apr_array_push(params);
-    param->type = APR_CRYPTO_CA_TYPE_DIR;
-    param->path = "data";
-    return get_driver(tc, pool, "nss", params);
+    return get_driver(tc, pool, "nss", "dir=data");
 
 }
 
@@ -89,7 +82,7 @@ static apr_crypto_t *make(abts_case *tc,
     }
 
     /* get the context */
-    apr_crypto_make(&f, driver, NULL, pool);
+    apr_crypto_make(&f, driver, "engine=openssl", pool);
     ABTS_ASSERT(tc, "apr_crypto_make returned NULL", f != NULL);
 
     return f;