Author: minfrin Date: Mon Jun 6 23:00:05 2011 New Revision: 1132827 URL: http://svn.apache.org/viewvc?rev=1132827&view=rev Log: Backport: apr_crypto: Add apr_crypto_get_block_key_types() and apr_crypto_get_block_key_modes() to provide a way to programmatically query what key types and modes are supported by a provider, either per mode/type, or by iterating through a hashtable. Modified: apr/apr-util/branches/1.5.x/ (props changed) apr/apr-util/branches/1.5.x/crypto/apr_crypto.c apr/apr-util/branches/1.5.x/crypto/apr_crypto_nss.c apr/apr-util/branches/1.5.x/crypto/apr_crypto_openssl.c apr/apr-util/branches/1.5.x/include/apr_crypto.h apr/apr-util/branches/1.5.x/include/private/apr_crypto_internal.h apr/apr-util/branches/1.5.x/test/testcrypto.c Propchange: apr/apr-util/branches/1.5.x/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon Jun 6 23:00:05 2011 @@ -1,3 +1,3 @@ -/apr/apr/trunk:781403,781409,784519,784592,789965,794508,917837-917838 +/apr/apr/trunk:781403,781409,784519,784592,789965,794508,917837-917838,1127648,1128838,1129433 /apr/apr-util/branches/1.3.x:896410 /apr/apr-util/trunk:731033-731034,731225,731236,731291,731293,731379,743986,744009,745771,747612,747623,747630 Modified: apr/apr-util/branches/1.5.x/crypto/apr_crypto.c URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/crypto/apr_crypto.c?rev=1132827&r1=1132826&r2=1132827&view=diff ============================================================================== --- apr/apr-util/branches/1.5.x/crypto/apr_crypto.c (original) +++ apr/apr-util/branches/1.5.x/crypto/apr_crypto.c Mon Jun 6 23:00:05 2011 @@ -241,6 +241,34 @@ APU_DECLARE(apr_status_t) apr_crypto_mak } /** + * @brief Get a hash table of key types, keyed by the name of the type against + * an integer pointer constant. + * + * @param types - hashtable of key types keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +APR_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types, + const apr_crypto_t *f) +{ + return f->provider->get_block_key_types(types, f); +} + +/** + * @brief Get a hash table of key modes, keyed by the name of the mode against + * an integer pointer constant. + * + * @param modes - hashtable of key modes keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +APR_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes, + const apr_crypto_t *f) +{ + return f->provider->get_block_key_modes(modes, f); +} + +/** * @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 Modified: apr/apr-util/branches/1.5.x/crypto/apr_crypto_nss.c URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/crypto/apr_crypto_nss.c?rev=1132827&r1=1132826&r2=1132827&view=diff ============================================================================== --- apr/apr-util/branches/1.5.x/crypto/apr_crypto_nss.c (original) +++ apr/apr-util/branches/1.5.x/crypto/apr_crypto_nss.c Mon Jun 6 23:00:05 2011 @@ -51,6 +51,8 @@ struct apr_crypto_t { apu_err_t *result; apr_array_header_t *keys; apr_crypto_config_t *config; + apr_hash_t *types; + apr_hash_t *modes; }; struct apr_crypto_config_t { @@ -75,6 +77,14 @@ struct apr_crypto_block_t { int blockSize; }; +static int key_3des_192 = APR_KEY_3DES_192; +static int key_aes_128 = APR_KEY_AES_128; +static int key_aes_192 = APR_KEY_AES_192; +static int key_aes_256 = APR_KEY_AES_256; + +static int mode_ecb = APR_MODE_ECB; +static int mode_cbc = APR_MODE_CBC; + /** * Fetch the most recent error from this driver. */ @@ -255,6 +265,22 @@ static apr_status_t crypto_make(apr_cryp f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t)); + f->types = apr_hash_make(pool); + if (!f->types) { + return APR_ENOMEM; + } + apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192)); + apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128)); + apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192)); + apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256)); + + f->modes = apr_hash_make(pool); + if (!f->modes) { + return APR_ENOMEM; + } + apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb)); + apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc)); + apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, apr_pool_cleanup_null); @@ -277,6 +303,34 @@ static apr_status_t crypto_make(apr_cryp } /** + * @brief Get a hash table of key types, keyed by the name of the type against + * an integer pointer constant. + * + * @param types - hashtable of key types keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +static apr_status_t crypto_get_block_key_types(apr_hash_t **types, + const apr_crypto_t *f) +{ + *types = f->types; +} + +/** + * @brief Get a hash table of key modes, keyed by the name of the mode against + * an integer pointer constant. + * + * @param modes - hashtable of key modes keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes, + const apr_crypto_t *f) +{ + *modes = f->modes; +} + +/** * @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 @@ -767,6 +821,8 @@ APU_MODULE_DECLARE_DATA const apr_crypto "nss", crypto_init, crypto_make, + crypto_get_block_key_types, + crypto_get_block_key_modes, crypto_passphrase, crypto_block_encrypt_init, crypto_block_encrypt, Modified: apr/apr-util/branches/1.5.x/crypto/apr_crypto_openssl.c URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/crypto/apr_crypto_openssl.c?rev=1132827&r1=1132826&r2=1132827&view=diff ============================================================================== --- apr/apr-util/branches/1.5.x/crypto/apr_crypto_openssl.c (original) +++ apr/apr-util/branches/1.5.x/crypto/apr_crypto_openssl.c Mon Jun 6 23:00:05 2011 @@ -40,6 +40,8 @@ struct apr_crypto_t { apu_err_t *result; apr_array_header_t *keys; apr_crypto_config_t *config; + apr_hash_t *types; + apr_hash_t *modes; }; struct apr_crypto_config_t { @@ -68,6 +70,14 @@ struct apr_crypto_block_t { int doPad; }; +static int key_3des_192 = APR_KEY_3DES_192; +static int key_aes_128 = APR_KEY_AES_128; +static int key_aes_192 = APR_KEY_AES_192; +static int key_aes_256 = APR_KEY_AES_256; + +static int mode_ecb = APR_MODE_ECB; +static int mode_cbc = APR_MODE_CBC; + /** * Fetch the most recent error from this driver. */ @@ -183,11 +193,32 @@ static apr_status_t crypto_make(apr_cryp if (!config) { return APR_ENOMEM; } + f->result = apr_pcalloc(pool, sizeof(apu_err_t)); if (!f->result) { return APR_ENOMEM; } + f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t)); + if (!f->keys) { + return APR_ENOMEM; + } + + f->types = apr_hash_make(pool); + if (!f->types) { + return APR_ENOMEM; + } + apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192)); + apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128)); + apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192)); + apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256)); + + f->modes = apr_hash_make(pool); + if (!f->modes) { + return APR_ENOMEM; + } + apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb)); + apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc)); apr_pool_cleanup_register(pool, f, crypto_cleanup_helper, apr_pool_cleanup_null); @@ -213,6 +244,34 @@ static apr_status_t crypto_make(apr_cryp } /** + * @brief Get a hash table of key types, keyed by the name of the type against + * an integer pointer constant. + * + * @param types - hashtable of key types keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +static apr_status_t crypto_get_block_key_types(apr_hash_t **types, + const apr_crypto_t *f) +{ + *types = f->types; +} + +/** + * @brief Get a hash table of key modes, keyed by the name of the mode against + * an integer pointer constant. + * + * @param modes - hashtable of key modes keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes, + const apr_crypto_t *f) +{ + *modes = f->modes; +} + +/** * @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 @@ -663,11 +722,13 @@ static apr_status_t crypto_block_decrypt /** * OpenSSL module. */ -APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_openssl_driver = { - "openssl", crypto_init, crypto_make, crypto_passphrase, +APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_openssl_driver = +{ "openssl", crypto_init, crypto_make, crypto_get_block_key_types, + crypto_get_block_key_modes, crypto_passphrase, crypto_block_encrypt_init, crypto_block_encrypt, crypto_block_encrypt_finish, crypto_block_decrypt_init, crypto_block_decrypt, crypto_block_decrypt_finish, - crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error }; + crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error +}; #endif Modified: apr/apr-util/branches/1.5.x/include/apr_crypto.h URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/include/apr_crypto.h?rev=1132827&r1=1132826&r2=1132827&view=diff ============================================================================== --- apr/apr-util/branches/1.5.x/include/apr_crypto.h (original) +++ apr/apr-util/branches/1.5.x/include/apr_crypto.h Mon Jun 6 23:00:05 2011 @@ -20,6 +20,7 @@ #include "apu.h" #include "apr_pools.h" #include "apr_tables.h" +#include "apr_hash.h" #include "apu_errno.h" #ifdef __cplusplus @@ -242,6 +243,28 @@ APU_DECLARE(apr_status_t) apr_crypto_mak const apr_array_header_t *params, apr_pool_t *pool); /** + * @brief Get a hash table of key types, keyed by the name of the type against + * an integer pointer constant. + * + * @param types - hashtable of key types keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +APR_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types, + const apr_crypto_t *f); + +/** + * @brief Get a hash table of key modes, keyed by the name of the mode against + * an integer pointer constant. + * + * @param modes - hashtable of key modes keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ +APR_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes, + const apr_crypto_t *f); + +/** * @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 Modified: apr/apr-util/branches/1.5.x/include/private/apr_crypto_internal.h URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/include/private/apr_crypto_internal.h?rev=1132827&r1=1132826&r2=1132827&view=diff ============================================================================== --- apr/apr-util/branches/1.5.x/include/private/apr_crypto_internal.h (original) +++ apr/apr-util/branches/1.5.x/include/private/apr_crypto_internal.h Mon Jun 6 23:00:05 2011 @@ -57,6 +57,28 @@ struct apr_crypto_driver_t { const apr_array_header_t *params, apr_pool_t *pool); /** + * @brief Get a hash table of key types, keyed by the name of the type against + * an integer pointer constant. + * + * @param types - hashtable of key types keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ + apr_status_t (*get_block_key_types)(apr_hash_t **types, + const apr_crypto_t *f); + + /** + * @brief Get a hash table of key modes, keyed by the name of the mode against + * an integer pointer constant. + * + * @param modes - hashtable of key modes keyed to constants. + * @param f - encryption context + * @return APR_SUCCESS for success + */ + apr_status_t (*get_block_key_modes)(apr_hash_t **modes, + const apr_crypto_t *f); + + /** * @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 Modified: apr/apr-util/branches/1.5.x/test/testcrypto.c URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/test/testcrypto.c?rev=1132827&r1=1132826&r2=1132827&view=diff ============================================================================== --- apr/apr-util/branches/1.5.x/test/testcrypto.c (original) +++ apr/apr-util/branches/1.5.x/test/testcrypto.c Mon Jun 6 23:00:05 2011 @@ -662,6 +662,158 @@ static void test_crypto_block_openssl_ns } +/** + * Get Types, OpenSSL. + */ +static void test_crypto_get_block_key_types_openssl(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f; + apr_hash_t *types; + int *key_3des_192; + int *key_aes_128; + int *key_aes_192; + int *key_aes_256; + + apr_pool_create(&pool, NULL); + driver = get_openssl_driver(tc, pool); + if (driver) { + + f = make(tc, pool, driver); + apr_crypto_get_block_key_types(&types, f); + + key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_3des_192); + ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192); + + key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_128); + ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128); + + key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_192); + ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192); + + key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_256); + ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256); + + } + + apr_pool_destroy(pool); + +} + +/** + * Get Types, NSS. + */ +static void test_crypto_get_block_key_types_nss(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f; + apr_hash_t *types; + int *key_3des_192; + int *key_aes_128; + int *key_aes_192; + int *key_aes_256; + + apr_pool_create(&pool, NULL); + driver = get_nss_driver(tc, pool); + if (driver) { + + f = make(tc, pool, driver); + apr_crypto_get_block_key_types(&types, f); + + key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_3des_192); + ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192); + + key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_128); + ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128); + + key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_192); + ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192); + + key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, key_aes_256); + ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256); + + } + + apr_pool_destroy(pool); + +} + +/** + * Get Modes, OpenSSL. + */ +static void test_crypto_get_block_key_modes_openssl(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f; + apr_hash_t *modes; + int *mode_ecb; + int *mode_cbc; + + apr_pool_create(&pool, NULL); + driver = get_openssl_driver(tc, pool); + if (driver) { + + f = make(tc, pool, driver); + apr_crypto_get_block_key_modes(&modes, f); + + mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, mode_ecb); + ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB); + + mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, mode_cbc); + ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC); + + } + + apr_pool_destroy(pool); + +} + +/** + * Get Modes, NSS. + */ +static void test_crypto_get_block_key_modes_nss(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f; + apr_hash_t *modes; + int *mode_ecb; + int *mode_cbc; + + apr_pool_create(&pool, NULL); + driver = get_nss_driver(tc, pool); + if (driver) { + + f = make(tc, pool, driver); + apr_crypto_get_block_key_modes(&modes, f); + + mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, mode_ecb); + ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB); + + mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING); + ABTS_PTR_NOTNULL(tc, mode_cbc); + ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC); + + } + + apr_pool_destroy(pool); + +} + abts_suite *testcrypto(abts_suite *suite) { suite = ADD_SUITE(suite); @@ -692,6 +844,18 @@ abts_suite *testcrypto(abts_suite *suite /* test padded encrypt openssl / decrypt nss */ abts_run_test(suite, test_crypto_block_openssl_nss_pad, NULL); + /* test block key types openssl */ + abts_run_test(suite, test_crypto_get_block_key_types_openssl, NULL); + + /* test block key types nss */ + abts_run_test(suite, test_crypto_get_block_key_types_nss, NULL); + + /* test block key modes openssl */ + abts_run_test(suite, test_crypto_get_block_key_modes_openssl, NULL); + + /* test block key modes nss */ + abts_run_test(suite, test_crypto_get_block_key_modes_nss, NULL); + return suite; }