summaryrefslogtreecommitdiff
path: root/contrib/apr-util/crypto/apr_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/apr-util/crypto/apr_crypto.c')
-rw-r--r--contrib/apr-util/crypto/apr_crypto.c95
1 files changed, 87 insertions, 8 deletions
diff --git a/contrib/apr-util/crypto/apr_crypto.c b/contrib/apr-util/crypto/apr_crypto.c
index fe66582d124f..9e6e0beebec6 100644
--- a/contrib/apr-util/crypto/apr_crypto.c
+++ b/contrib/apr-util/crypto/apr_crypto.c
@@ -120,7 +120,7 @@ static apr_status_t crypto_clear(void *ptr)
{
apr_crypto_clear_t *clear = (apr_crypto_clear_t *)ptr;
- memset(clear->buffer, 0, clear->size);
+ apr_crypto_memzero(clear->buffer, clear->size);
clear->buffer = NULL;
clear->size = 0;
@@ -141,6 +141,53 @@ APU_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool,
return APR_SUCCESS;
}
+#if defined(HAVE_WEAK_SYMBOLS)
+void apr__memzero_explicit(void *buffer, apr_size_t size);
+
+__attribute__ ((weak))
+void apr__memzero_explicit(void *buffer, apr_size_t size)
+{
+ memset(buffer, 0, size);
+}
+#endif
+
+APU_DECLARE(apr_status_t) apr_crypto_memzero(void *buffer, apr_size_t size)
+{
+#if defined(WIN32)
+ SecureZeroMemory(buffer, size);
+#elif defined(HAVE_MEMSET_S)
+ if (size) {
+ return memset_s(buffer, (rsize_t)size, 0, (rsize_t)size);
+ }
+#elif defined(HAVE_EXPLICIT_BZERO)
+ explicit_bzero(buffer, size);
+#elif defined(HAVE_WEAK_SYMBOLS)
+ apr__memzero_explicit(buffer, size);
+#else
+ apr_size_t i;
+ volatile unsigned char *volatile ptr = buffer;
+ for (i = 0; i < size; ++i) {
+ ptr[i] = 0;
+ }
+#endif
+ return APR_SUCCESS;
+}
+
+APU_DECLARE(int) apr_crypto_equals(const void *buf1, const void *buf2,
+ apr_size_t size)
+{
+ const unsigned char *p1 = buf1;
+ const unsigned char *p2 = buf2;
+ unsigned char diff = 0;
+ apr_size_t i;
+
+ for (i = 0; i < size; ++i) {
+ diff |= p1[i] ^ p2[i];
+ }
+
+ return 1 & ((diff - 1) >> 8);
+}
+
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)
@@ -188,12 +235,15 @@ APU_DECLARE(apr_status_t) apr_crypto_get_driver(
apr_snprintf(symname, sizeof(symname), "apr_crypto_%s_driver", name);
rv = apu_dso_load(&dso, &symbol, modname, symname, pool);
if (rv == APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */
- *driver = symbol;
- name = apr_pstrdup(pool, name);
- apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver);
+ apr_crypto_driver_t *d = symbol;
rv = APR_SUCCESS;
- if ((*driver)->init) {
- rv = (*driver)->init(pool, params, result);
+ if (d->init) {
+ rv = d->init(pool, params, result);
+ }
+ if (APR_SUCCESS == rv) {
+ *driver = symbol;
+ name = apr_pstrdup(pool, name);
+ apr_hash_set(drivers, name, APR_HASH_KEY_STRING, *driver);
}
}
apu_dso_mutex_unlock();
@@ -223,6 +273,11 @@ APU_DECLARE(apr_status_t) apr_crypto_get_driver(
DRIVER_LOAD("nss", apr_crypto_nss_driver, pool, params, rv, result);
}
#endif
+#if APU_HAVE_COMMONCRYPTO
+ if (name[0] == 'c' && !strcmp(name, "commoncrypto")) {
+ DRIVER_LOAD("commoncrypto", apr_crypto_commoncrypto_driver, pool, params, rv, result);
+ }
+#endif
#if APU_HAVE_MSCAPI
if (name[0] == 'm' && !strcmp(name, "mscapi")) {
DRIVER_LOAD("mscapi", apr_crypto_mscapi_driver, pool, params, rv, result);
@@ -287,7 +342,8 @@ APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f,
/**
* @brief Get a hash table of key types, keyed by the name of the type against
- * an integer pointer constant.
+ * a pointer to apr_crypto_block_key_type_t, which in turn begins with an
+ * integer.
*
* @param types - hashtable of key types keyed to constants.
* @param f - encryption context
@@ -301,7 +357,8 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types,
/**
* @brief Get a hash table of key modes, keyed by the name of the mode against
- * an integer pointer constant.
+ * a pointer to apr_crypto_block_key_mode_t, which in turn begins with an
+ * integer.
*
* @param modes - hashtable of key modes keyed to constants.
* @param f - encryption context
@@ -314,6 +371,28 @@ APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes,
}
/**
+ * @brief Create a key from the provided secret or passphrase. The key is cleaned
+ * up when the context is cleaned, and may be reused with multiple encryption
+ * or decryption operations.
+ * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
+ * *key is not NULL, *key must point at a previously created structure.
+ * @param key The key returned, see note.
+ * @param rec The key record, from which the key will be derived.
+ * @param f The context to use.
+ * @param p The pool to use.
+ * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
+ * error occurred while generating the key. APR_ENOCIPHER if the type or mode
+ * is not supported by the particular backend. APR_EKEYTYPE if the key type is
+ * not known. APR_EPADDING if padding was requested but is not supported.
+ * APR_ENOTIMPL if not implemented.
+ */
+APU_DECLARE(apr_status_t) apr_crypto_key(apr_crypto_key_t **key,
+ const apr_crypto_key_rec_t *rec, const apr_crypto_t *f, apr_pool_t *p)
+{
+ return f->provider->key(key, rec, f, p);
+}
+
+/**
* @brief Create a key from the given passphrase. By default, the PBKDF2
* algorithm is used to generate the key from the passphrase. It is expected
* that the same pass phrase will generate the same key, regardless of the