diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.in | 2 | ||||
-rw-r--r-- | test/Makefile.win | 4 | ||||
-rw-r--r-- | test/NWGNUaputest | 1 | ||||
-rw-r--r-- | test/abts_tests.h | 4 | ||||
-rw-r--r-- | test/testall.dsw | 17 | ||||
-rw-r--r-- | test/testcrypto.c | 909 | ||||
-rw-r--r-- | test/testredis.c | 552 | ||||
-rw-r--r-- | test/testsiphash.c | 148 | ||||
-rw-r--r-- | test/testutil.h | 2 |
9 files changed, 1492 insertions, 147 deletions
diff --git a/test/Makefile.in b/test/Makefile.in index 5f4cf91b9b130..e1b4d7c20333d 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -17,7 +17,7 @@ STDTEST_PORTABLE = dbd testall TESTS = teststrmatch.lo testuri.lo testuuid.lo testbuckets.lo testpass.lo \ testmd4.lo testmd5.lo testldap.lo testdate.lo testdbm.lo testdbd.lo \ testxml.lo testrmm.lo testreslist.lo testqueue.lo testxlate.lo \ - testmemcache.lo testcrypto.lo + testmemcache.lo testcrypto.lo testsiphash.lo testredis.lo PROGRAMS = $(STDTEST_PORTABLE) diff --git a/test/Makefile.win b/test/Makefile.win index a30f39e2b5209..fa3d2eba5c2f3 100644 --- a/test/Makefile.win +++ b/test/Makefile.win @@ -62,6 +62,7 @@ ALL_TESTS = $(INTDIR)\teststrmatch.obj $(INTDIR)\testuri.obj \ $(INTDIR)\testxml.obj $(INTDIR)\testqueue.obj \ $(INTDIR)\testrmm.obj $(INTDIR)\testxlate.obj \ $(INTDIR)\testdate.obj $(INTDIR)\testmemcache.obj \ + $(INTDIR)\testredis.obj $(INTDIR)\testsiphash.obj \ $(INTDIR)\testcrypto.obj CLEAN_DATA = manyfile.bin testfile.txt data\sqlite*.db @@ -89,10 +90,9 @@ APROUTDIR=$(OUTDIR) PROGRAM_DEPENDENCIES = \ $(APR_PATH)\$(APROUTDIR)\apr-1.lib \ $(API_PATH)\$(OUTDIR)\apriconv-1.lib \ - ..\xml\expat\lib\$(OUTDIR)\xml.lib \ ..\$(OUTDIR)\aprutil-1.lib STATIC_CFLAGS = /D APR_DECLARE_STATIC /D APU_DECLARE_STATIC -STATIC_LIBS = odbc32.lib odbccp32.lib wldap32.lib +STATIC_LIBS = libexpatMT.lib odbc32.lib odbccp32.lib wldap32.lib !ELSE PROGRAM_DEPENDENCIES = \ $(APR_PATH)\$(APROUTDIR)\libapr-1.lib \ diff --git a/test/NWGNUaputest b/test/NWGNUaputest index 6b710ad84d535..caf3cd49f6f53 100644 --- a/test/NWGNUaputest +++ b/test/NWGNUaputest @@ -185,6 +185,7 @@ FILES_nlm_objs = \ $(OBJDIR)/testqueue.o \ $(OBJDIR)/testreslist.o \ $(OBJDIR)/testrmm.o \ + $(OBJDIR)/testsiphash.o \ $(OBJDIR)/teststrmatch.o \ $(OBJDIR)/testuri.o \ $(OBJDIR)/testutil.o \ diff --git a/test/abts_tests.h b/test/abts_tests.h index b612d31b8fa52..cb4e113fe8b68 100644 --- a/test/abts_tests.h +++ b/test/abts_tests.h @@ -35,12 +35,14 @@ const struct testlist { {testdbd}, {testdate}, {testmemcache}, + {testredis}, {testxml}, {testxlate}, {testrmm}, {testdbm}, {testqueue}, - {testreslist} + {testreslist}, + {testsiphash} }; #endif /* APR_TEST_INCLUDES */ diff --git a/test/testall.dsw b/test/testall.dsw index 0a640c8be2960..7fde202c2b07e 100644 --- a/test/testall.dsw +++ b/test/testall.dsw @@ -28,23 +28,6 @@ Package=<4> End Project Dependency }}} -############################################################################### - -Project: "apr_dbd_freetds"="..\dbd\apr_dbd_freetds.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libapr - End Project Dependency - Begin Project Dependency - Project_Dep_Name libaprutil - End Project Dependency -}}} ############################################################################### diff --git a/test/testcrypto.c b/test/testcrypto.c index 335c3ae65d775..865cffc6d5ede 100644 --- a/test/testcrypto.c +++ b/test/testcrypto.c @@ -33,22 +33,32 @@ static const apr_crypto_driver_t *get_driver(abts_case *tc, apr_pool_t *pool, { const apr_crypto_driver_t *driver = NULL; - const apu_err_t *err = NULL; + const apu_err_t *result = NULL; apr_status_t rv; rv = apr_crypto_init(pool); ABTS_ASSERT(tc, "failed to init apr_crypto", rv == APR_SUCCESS); - rv = apr_crypto_get_driver(&driver, name, params, &err, pool); - if (APR_SUCCESS != rv && err) { - ABTS_NOT_IMPL(tc, err->msg); + rv = apr_crypto_get_driver(&driver, name, params, &result, pool); + if (APR_ENOTIMPL == rv) { + ABTS_NOT_IMPL(tc, + apr_psprintf(pool, "Crypto driver '%s' not implemented", (char *)name)); return NULL; } - if (APR_ENOTIMPL == rv) { - ABTS_NOT_IMPL(tc, (char *)driver); + if (APR_EDSOOPEN == rv) { + ABTS_NOT_IMPL(tc, + apr_psprintf(pool, "Crypto driver '%s' DSO could not be opened", (char *)name)); return NULL; } - ABTS_ASSERT(tc, "failed to apr_crypto_get_driver", rv == APR_SUCCESS); + if (APR_SUCCESS != rv && result) { + char err[1024]; + apr_strerror(rv, err, sizeof(err) - 1); + fprintf(stderr, "get_driver error %d: %s: '%s' native error %d: %s (%s),", + rv, err, name, result->rc, result->reason ? result->reason : "", + result->msg ? result->msg : ""); + } + ABTS_ASSERT(tc, apr_psprintf(pool, "failed to apr_crypto_get_driver for '%s' with %d", + name, rv), rv == APR_SUCCESS); ABTS_ASSERT(tc, "apr_crypto_get_driver returned NULL", driver != NULL); if (!driver || rv) { return NULL; @@ -63,7 +73,7 @@ static const apr_crypto_driver_t *get_nss_driver(abts_case *tc, { /* initialise NSS */ - return get_driver(tc, pool, "nss", "dir=data"); + return get_driver(tc, pool, "nss", ""); } @@ -75,6 +85,14 @@ static const apr_crypto_driver_t *get_openssl_driver(abts_case *tc, } +static const apr_crypto_driver_t *get_commoncrypto_driver(abts_case *tc, + apr_pool_t *pool) +{ + + return get_driver(tc, pool, "commoncrypto", NULL); + +} + static apr_crypto_t *make(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t *driver) { @@ -93,6 +111,59 @@ static apr_crypto_t *make(abts_case *tc, apr_pool_t *pool, } +static const apr_crypto_key_t *keysecret(abts_case *tc, apr_pool_t *pool, + const apr_crypto_driver_t *driver, const apr_crypto_t *f, + apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode, + int doPad, apr_size_t secretLen, const char *description) +{ + apr_crypto_key_t *key = NULL; + const apu_err_t *result = NULL; + apr_crypto_key_rec_t *rec = apr_pcalloc(pool, sizeof(apr_crypto_key_rec_t)); + apr_status_t rv; + + if (!f) { + return NULL; + } + + rec->ktype = APR_CRYPTO_KTYPE_SECRET; + rec->type = type; + rec->mode = mode; + rec->pad = doPad; + rec->k.secret.secret = apr_pcalloc(pool, secretLen); + rec->k.secret.secretLen = secretLen; + + /* init the passphrase */ + rv = apr_crypto_key(&key, rec, f, pool); + if (APR_ENOCIPHER == rv) { + apr_crypto_error(&result, f); + ABTS_NOT_IMPL(tc, + apr_psprintf(pool, "skipped: %s %s key return APR_ENOCIPHER: error %d: %s (%s)\n", description, apr_crypto_driver_name(driver), result->rc, result->reason ? result->reason : "", result->msg ? result->msg : "")); + return NULL; + } + else { + if (APR_SUCCESS != rv) { + apr_crypto_error(&result, f); + fprintf(stderr, "key: %s %s apr error %d / native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); + } + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EKEYLENGTH", rv != APR_EKEYLENGTH); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_ENOKEY", rv != APR_ENOKEY); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EPADDING", + rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EKEYTYPE", + rv != APR_EKEYTYPE); + ABTS_ASSERT(tc, "failed to apr_crypto_key", rv == APR_SUCCESS); + ABTS_ASSERT(tc, "apr_crypto_key returned NULL context", key != NULL); + } + if (rv) { + return NULL; + } + return key; + +} + static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t *driver, const apr_crypto_t *f, apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode, @@ -124,8 +195,8 @@ static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool, else { if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "passphrase: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, + fprintf(stderr, "passphrase: %s %s apr error %d / native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, result->reason ? result->reason : "", result->msg ? result->msg : ""); } @@ -142,6 +213,64 @@ static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool, } +static const apr_crypto_key_t *keypassphrase(abts_case *tc, apr_pool_t *pool, + const apr_crypto_driver_t *driver, const apr_crypto_t *f, + apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode, + int doPad, const char *description) +{ + + apr_crypto_key_t *key = NULL; + const apu_err_t *result = NULL; + const char *pass = "secret"; + const char *salt = "salt"; + apr_crypto_key_rec_t *rec = apr_pcalloc(pool, sizeof(apr_crypto_key_rec_t)); + apr_status_t rv; + + if (!f) { + return NULL; + } + + rec->ktype = APR_CRYPTO_KTYPE_PASSPHRASE; + rec->type = type; + rec->mode = mode; + rec->pad = doPad; + rec->k.passphrase.pass = pass; + rec->k.passphrase.passLen = strlen(pass); + rec->k.passphrase.salt = (unsigned char *)salt; + rec->k.passphrase.saltLen = strlen(salt); + rec->k.passphrase.iterations = 4096; + + /* init the passphrase */ + rv = apr_crypto_key(&key, rec, f, pool); + if (APR_ENOCIPHER == rv) { + apr_crypto_error(&result, f); + ABTS_NOT_IMPL(tc, apr_psprintf(pool, + "skipped: %s %s key passphrase return APR_ENOCIPHER: error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), result->rc, + result->reason ? result->reason : "", result->msg ? result->msg : "")); + return NULL; + } + else { + if (APR_SUCCESS != rv) { + apr_crypto_error(&result, f); + fprintf(stderr, "key passphrase: %s %s apr error %d / native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); + } + ABTS_ASSERT(tc, "apr_crypto_key returned APR_ENOKEY", rv != APR_ENOKEY); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EPADDING", rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_key returned APR_EKEYTYPE", rv != APR_EKEYTYPE); + ABTS_ASSERT(tc, "failed to apr_crypto_key", rv == APR_SUCCESS); + ABTS_ASSERT(tc, "apr_crypto_key returned NULL context", key != NULL); + } + if (rv) { + return NULL; + } + return key; + +} + static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t *driver, const apr_crypto_t *f, const apr_crypto_key_t *key, const unsigned char *in, @@ -167,17 +296,27 @@ static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, else { if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "encrypt_init: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, + fprintf(stderr, + "encrypt_init: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, result->reason ? result->reason : "", result->msg ? result->msg : ""); } - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOKEY", rv != APR_ENOKEY); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOIV", rv != APR_ENOIV); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYTYPE", rv != APR_EKEYTYPE); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYLENGTH", rv != APR_EKEYLENGTH); - ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_init", rv == APR_SUCCESS); - ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned NULL context", block != NULL); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOKEY", + rv != APR_ENOKEY); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOIV", + rv != APR_ENOIV); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYTYPE", + rv != APR_EKEYTYPE); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_EKEYLENGTH", + rv != APR_EKEYLENGTH); + ABTS_ASSERT(tc, + "apr_crypto_block_encrypt_init returned APR_ENOTENOUGHENTROPY", + rv != APR_ENOTENOUGHENTROPY); + ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_init", + rv == APR_SUCCESS); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned NULL context", + block != NULL); } if (!block || rv) { return NULL; @@ -187,10 +326,10 @@ static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, rv = apr_crypto_block_encrypt(cipherText, cipherTextLen, in, inlen, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "encrypt: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, "encrypt: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_encrypt returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt", rv == APR_SUCCESS); @@ -204,13 +343,15 @@ static unsigned char *encrypt_block(abts_case *tc, apr_pool_t *pool, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "encrypt_finish: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, + "encrypt_finish: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_EPADDING", rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_ENOSPACE", rv != APR_ENOSPACE); ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_finish", rv == APR_SUCCESS); *cipherTextLen += len; apr_crypto_block_cleanup(block); @@ -247,8 +388,9 @@ static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool, else { if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "decrypt_init: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, + fprintf(stderr, + "decrypt_init: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, result->reason ? result->reason : "", result->msg ? result->msg : ""); } @@ -268,10 +410,10 @@ static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool, cipherTextLen, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "decrypt: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, "decrypt: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_decrypt returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt", rv == APR_SUCCESS); @@ -285,13 +427,15 @@ static unsigned char *decrypt_block(abts_case *tc, apr_pool_t *pool, block); if (APR_SUCCESS != rv) { apr_crypto_error(&result, f); - fprintf(stderr, "decrypt_finish: %s %s native error %d: %s (%s)\n", - description, apr_crypto_driver_name(driver), result->rc, - result->reason ? result->reason : "", result->msg ? result->msg - : ""); + fprintf(stderr, + "decrypt_finish: %s %s (APR %d) native error %d: %s (%s)\n", + description, apr_crypto_driver_name(driver), rv, result->rc, + result->reason ? result->reason : "", + result->msg ? result->msg : ""); } ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT); ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_EPADDING", rv != APR_EPADDING); + ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_ENOSPACE", rv != APR_ENOSPACE); ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt_finish", rv == APR_SUCCESS); if (rv) { return NULL; @@ -316,7 +460,8 @@ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t **drivers, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, int doPad, - const unsigned char *in, apr_size_t inlen, const char *description) + const unsigned char *in, apr_size_t inlen, apr_size_t secretLen, + const char *description) { const apr_crypto_driver_t *driver1 = drivers[0]; const apr_crypto_driver_t *driver2 = drivers[1]; @@ -324,6 +469,10 @@ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, apr_crypto_t *f2 = NULL; const apr_crypto_key_t *key1 = NULL; const apr_crypto_key_t *key2 = NULL; + const apr_crypto_key_t *key3 = NULL; + const apr_crypto_key_t *key4 = NULL; + const apr_crypto_key_t *key5 = NULL; + const apr_crypto_key_t *key6 = NULL; unsigned char *cipherText = NULL; apr_size_t cipherTextLen = 0; @@ -345,7 +494,51 @@ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, if (cipherText && plainText) { if (memcmp(in, plainText, inlen)) { - fprintf(stderr, "cross mismatch: %s %s/%s\n", description, + fprintf(stderr, "passphrase cross mismatch: %s %s/%s\n", description, + apr_crypto_driver_name(driver1), apr_crypto_driver_name( + driver2)); + } + ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); + } + + key3 = keysecret(tc, pool, driver1, f1, type, mode, doPad, secretLen, description); + key4 = keysecret(tc, pool, driver2, f2, type, mode, doPad, secretLen, description); + + iv = NULL; + blockSize = 0; + cipherText = NULL; + plainText = NULL; + cipherText = encrypt_block(tc, pool, driver1, f1, key3, in, inlen, + &cipherText, &cipherTextLen, &iv, &blockSize, description); + plainText = decrypt_block(tc, pool, driver2, f2, key4, cipherText, + cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, + description); + + if (cipherText && plainText) { + if (memcmp(in, plainText, inlen)) { + fprintf(stderr, "key secret cross mismatch: %s %s/%s\n", description, + apr_crypto_driver_name(driver1), apr_crypto_driver_name( + driver2)); + } + ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); + } + + key5 = keypassphrase(tc, pool, driver1, f1, type, mode, doPad, description); + key6 = keypassphrase(tc, pool, driver2, f2, type, mode, doPad, description); + + iv = NULL; + blockSize = 0; + cipherText = NULL; + plainText = NULL; + cipherText = encrypt_block(tc, pool, driver1, f1, key5, in, inlen, + &cipherText, &cipherTextLen, &iv, &blockSize, description); + plainText = decrypt_block(tc, pool, driver2, f2, key6, cipherText, + cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, + description); + + if (cipherText && plainText) { + if (memcmp(in, plainText, inlen)) { + fprintf(stderr, "key passphrase cross mismatch: %s %s/%s\n", description, apr_crypto_driver_name(driver1), apr_crypto_driver_name( driver2)); } @@ -372,6 +565,63 @@ static void test_crypto_init(abts_case *tc, void *data) } /** + * Simple test of OpenSSL key. + */ +static void test_crypto_key_openssl(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f = NULL; + + apr_pool_create(&pool, NULL); + driver = get_openssl_driver(tc, pool); + + f = make(tc, pool, driver); + keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32, + "KEY_AES_256/MODE_CBC"); + apr_pool_destroy(pool); + +} + +/** + * Simple test of NSS key. + */ +static void test_crypto_key_nss(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f = NULL; + + apr_pool_create(&pool, NULL); + driver = get_nss_driver(tc, pool); + + f = make(tc, pool, driver); + keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32, + "KEY_AES_256/MODE_CBC"); + apr_pool_destroy(pool); + +} + +/** + * Simple test of CommonCrypto key. + */ +static void test_crypto_key_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *driver; + apr_crypto_t *f = NULL; + + apr_pool_create(&pool, NULL); + driver = get_commoncrypto_driver(tc, pool); + + f = make(tc, pool, driver); + keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32, + "KEY_AES_256/MODE_CBC"); + apr_pool_destroy(pool); + +} + +/** * Simple test of OpenSSL block crypt. */ static void test_crypto_block_openssl(abts_case *tc, void *data) @@ -386,21 +636,21 @@ static void test_crypto_block_openssl(abts_case *tc, void *data) drivers[0] = get_openssl_driver(tc, pool); drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, - in, inlen, "KEY_3DES_192/MODE_ECB"); + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_192/MODE_ECB"); + inlen, 24, "KEY_AES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_128/MODE_ECB"); + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -420,21 +670,55 @@ static void test_crypto_block_nss(abts_case *tc, void *data) drivers[0] = get_nss_driver(tc, pool); drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + apr_pool_destroy(pool); + +} + +/** + * Simple test of Common Crypto block crypt. + */ +static void test_crypto_block_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) ALIGNED_STRING; + apr_size_t inlen = sizeof(ALIGNED_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_192/MODE_ECB"); + inlen, 24, "KEY_AES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_128/MODE_ECB"); + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -455,25 +739,22 @@ static void test_crypto_block_nss_openssl(abts_case *tc, void *data) drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); - - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen, "KEY_AES_128/MODE_ECB"); - */ + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -493,26 +774,95 @@ static void test_crypto_block_openssl_nss(abts_case *tc, void *data) drivers[0] = get_openssl_driver(tc, pool); drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + apr_pool_destroy(pool); - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen, "KEY_AES_128/MODE_ECB"); - */ +} + +/** + * Encrypt OpenSSL, decrypt CommonCrypto. + */ +static void test_crypto_block_openssl_commoncrypto(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) ALIGNED_STRING; + apr_size_t inlen = sizeof(ALIGNED_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_openssl_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + apr_pool_destroy(pool); + +} + +/** + * Encrypt OpenSSL, decrypt CommonCrypto. + */ +static void test_crypto_block_commoncrypto_openssl(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) ALIGNED_STRING; + apr_size_t inlen = sizeof(ALIGNED_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_openssl_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); } @@ -533,21 +883,21 @@ static void test_crypto_block_openssl_pad(abts_case *tc, void *data) drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, - in, inlen, "KEY_3DES_192/MODE_ECB"); + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, - inlen, "KEY_AES_256/MODE_ECB"); + inlen, 32, "KEY_AES_256/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, - inlen, "KEY_AES_192/MODE_ECB"); + inlen, 24, "KEY_AES_192/MODE_ECB"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, - inlen, "KEY_AES_128/MODE_ECB"); + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); @@ -570,27 +920,63 @@ static void test_crypto_block_nss_pad(abts_case *tc, void *data) drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, 32, "KEY_AES_256/MODE_ECB");*/ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_192/MODE_CBC"); + inlen, 24, "KEY_AES_192/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, 24, "KEY_AES_192/MODE_ECB");*/ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_128/MODE_CBC"); + inlen, 16, "KEY_AES_128/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, 16, "KEY_AES_128/MODE_ECB");*/ + + apr_pool_destroy(pool); + +} + +/** + * Simple test of Common Crypto block crypt. + */ +static void test_crypto_block_commoncrypto_pad(abts_case *tc, void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) TEST_STRING; + apr_size_t inlen = sizeof(TEST_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, + in, inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); apr_pool_destroy(pool); @@ -612,27 +998,31 @@ static void test_crypto_block_nss_openssl_pad(abts_case *tc, void *data) drivers[1] = get_openssl_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, 32, "KEY_AES_256/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + + /* KEY_AES_192 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + + /* KEY_AES_192 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB");*/ - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB"); - */ apr_pool_destroy(pool); } @@ -652,27 +1042,107 @@ static void test_crypto_block_openssl_nss_pad(abts_case *tc, void *data) drivers[0] = get_openssl_driver(tc, pool); drivers[1] = get_nss_driver(tc, pool); crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, - in, inlen, "KEY_3DES_192/MODE_CBC"); + in, inlen, 24, "KEY_3DES_192/MODE_CBC"); /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */ - /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */ + /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, 24, "KEY_3DES_192/MODE_ECB"); */ crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, - inlen, "KEY_AES_256/MODE_CBC"); + inlen, 32, "KEY_AES_256/MODE_CBC"); /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */ - /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/ + /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, 32, "KEY_AES_256/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, inlen, + 24, "KEY_AES_192/MODE_CBC"); + + /* KEY_AES_192 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, inlen, + 24, "KEY_AES_192/MODE_ECB");*/ + + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, inlen, + 16, "KEY_AES_128/MODE_CBC"); + + /* KEY_AES_128 / MODE_ECB doesn't support padding on NSS */ + /*crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, inlen, + 16, "KEY_AES_128/MODE_ECB");*/ + + apr_pool_destroy(pool); + +} + +/** + * Encrypt CommonCrypto, decrypt OpenSSL. + */ +static void test_crypto_block_commoncrypto_openssl_pad(abts_case *tc, + void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) TEST_STRING; + apr_size_t inlen = sizeof(TEST_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_commoncrypto_driver(tc, pool); + drivers[1] = get_openssl_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); + + apr_pool_destroy(pool); + +} + +/** + * Encrypt OpenSSL, decrypt CommonCrypto. + */ +static void test_crypto_block_openssl_commoncrypto_pad(abts_case *tc, + void *data) +{ + apr_pool_t *pool = NULL; + const apr_crypto_driver_t *drivers[] = + { NULL, NULL }; + + const unsigned char *in = (const unsigned char *) TEST_STRING; + apr_size_t inlen = sizeof(TEST_STRING); + + apr_pool_create(&pool, NULL); + drivers[0] = get_openssl_driver(tc, pool); + drivers[1] = get_commoncrypto_driver(tc, pool); + + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_3DES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_3DES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in, + inlen, 32, "KEY_AES_256/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in, + inlen, 32, "KEY_AES_256/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in, + inlen, 24, "KEY_AES_192/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in, + inlen, 24, "KEY_AES_192/MODE_ECB"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in, + inlen, 16, "KEY_AES_128/MODE_CBC"); + crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in, + inlen, 16, "KEY_AES_128/MODE_ECB"); - /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that - * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be - * investigated. - */ - /* - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen, "KEY_AES_192/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen, "KEY_AES_128/MODE_CBC"); - crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB"); - */ apr_pool_destroy(pool); } @@ -764,6 +1234,49 @@ static void test_crypto_get_block_key_types_nss(abts_case *tc, void *data) } /** + * Get Types, Common Crypto. + */ +static void test_crypto_get_block_key_types_commoncrypto(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_commoncrypto_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) @@ -829,6 +1342,114 @@ static void test_crypto_get_block_key_modes_nss(abts_case *tc, void *data) } +/** + * Get Modes, Common Crypto. + */ +static void test_crypto_get_block_key_modes_commoncrypto(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_commoncrypto_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); + +} + +static void test_crypto_memzero(abts_case *tc, void *data) +{ + /* Aligned message */ + struct { + char buf[7 * sizeof(int)]; + int untouched; + } msg; + /* A bit of type punning such that 'msg' might look unused + * after the call to apr_crypto_memzero(). + */ + int *ptr = (int *)&msg; + int i; + + /* Fill buf with non-zeros (odds) */ + for (i = 1; i < 2 * sizeof(msg.buf); i += 2) { + msg.buf[i / 2] = (char)i; + ABTS_ASSERT(tc, "test_crypto_memzero() barrier", msg.buf[i / 2] != 0); + } + + /* Zero out the whole, and check it */ + apr_crypto_memzero(&msg, sizeof msg); + for (i = 0; i < sizeof(msg) / sizeof(*ptr); ++i) { + ABTS_ASSERT(tc, "test_crypto_memzero() optimized out", ptr[i] == 0); + } +} + +static void test_crypto_equals(abts_case *tc, void *data) +{ + /* Buffers of each type of scalar */ + union { + char c; + short s; + int i; + long l; + float f; + double d; + void *p; + } buf0[7], buf1[7], buf[7]; + char *ptr = (char *)buf; + int i; + +#define TEST_SCALAR_MATCH(i, x, r) \ + ABTS_ASSERT(tc, "test_crypto_equals(" APR_STRINGIFY(x) ")" \ + " != " APR_STRINGIFY(r), \ + apr_crypto_equals(&buf##r[i].x, &buf[i].x, \ + sizeof(buf[i].x)) == r) + + /* Fill buf with non-zeros (odds) */ + for (i = 1; i < 2 * sizeof(buf); i += 2) { + ptr[i / 2] = (char)i; + } + /* Set buf1 = buf */ + memcpy(buf1, buf, sizeof buf); + /* Set buf0 = {0} */ + memset(buf0, 0, sizeof buf0); + + /* Check that buf1 == buf for each scalar */ + TEST_SCALAR_MATCH(0, c, 1); + TEST_SCALAR_MATCH(1, s, 1); + TEST_SCALAR_MATCH(2, i, 1); + TEST_SCALAR_MATCH(3, l, 1); + TEST_SCALAR_MATCH(4, f, 1); + TEST_SCALAR_MATCH(5, d, 1); + TEST_SCALAR_MATCH(6, p, 1); + + /* Check that buf0 != buf for each scalar */ + TEST_SCALAR_MATCH(0, c, 0); + TEST_SCALAR_MATCH(1, s, 0); + TEST_SCALAR_MATCH(2, i, 0); + TEST_SCALAR_MATCH(3, l, 0); + TEST_SCALAR_MATCH(4, f, 0); + TEST_SCALAR_MATCH(5, d, 0); + TEST_SCALAR_MATCH(6, p, 0); +} + abts_suite *testcrypto(abts_suite *suite) { suite = ADD_SUITE(suite); @@ -836,6 +1457,15 @@ abts_suite *testcrypto(abts_suite *suite) /* test simple init and shutdown */ abts_run_test(suite, test_crypto_init, NULL); + /* test key parsing - openssl */ + abts_run_test(suite, test_crypto_key_openssl, NULL); + + /* test key parsing - nss */ + abts_run_test(suite, test_crypto_key_nss, NULL); + + /* test key parsing - commoncrypto */ + abts_run_test(suite, test_crypto_key_commoncrypto, NULL); + /* test a simple encrypt / decrypt operation - openssl */ abts_run_test(suite, test_crypto_block_openssl, NULL); @@ -848,6 +1478,12 @@ abts_suite *testcrypto(abts_suite *suite) /* test a padded encrypt / decrypt operation - nss */ abts_run_test(suite, test_crypto_block_nss_pad, NULL); + /* test a simple encrypt / decrypt operation - commoncrypto */ + abts_run_test(suite, test_crypto_block_commoncrypto, NULL); + + /* test a padded encrypt / decrypt operation - commoncrypto */ + abts_run_test(suite, test_crypto_block_commoncrypto_pad, NULL); + /* test encrypt nss / decrypt openssl */ abts_run_test(suite, test_crypto_block_nss_openssl, NULL); @@ -860,18 +1496,39 @@ abts_suite *testcrypto(abts_suite *suite) /* test padded encrypt openssl / decrypt nss */ abts_run_test(suite, test_crypto_block_openssl_nss_pad, NULL); + /* test encrypt openssl / decrypt commoncrypto */ + abts_run_test(suite, test_crypto_block_openssl_commoncrypto, NULL); + + /* test padded encrypt openssl / decrypt commoncrypto */ + abts_run_test(suite, test_crypto_block_openssl_commoncrypto_pad, NULL); + + /* test encrypt commoncrypto / decrypt openssl */ + abts_run_test(suite, test_crypto_block_commoncrypto_openssl, NULL); + + /* test padded encrypt commoncrypto / decrypt openssl */ + abts_run_test(suite, test_crypto_block_commoncrypto_openssl_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 types commoncrypto */ + abts_run_test(suite, test_crypto_get_block_key_types_commoncrypto, 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); + /* test block key modes commoncrypto */ + abts_run_test(suite, test_crypto_get_block_key_modes_commoncrypto, NULL); + + abts_run_test(suite, test_crypto_memzero, NULL); + abts_run_test(suite, test_crypto_equals, NULL); + return suite; } diff --git a/test/testredis.c b/test/testredis.c new file mode 100644 index 0000000000000..4b654322f54e4 --- /dev/null +++ b/test/testredis.c @@ -0,0 +1,552 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "testutil.h" +#include "apr.h" +#include "apu.h" +#include "apr_general.h" +#include "apr_strings.h" +#include "apr_hash.h" +#include "apr_redis.h" +#include "apr_network_io.h" + +#include <stdio.h> +#if APR_HAVE_STDLIB_H +#include <stdlib.h> /* for exit() */ +#endif + +#define HOST "localhost" +#define PORT 6379 + +/* the total number of items to use for set/get testing */ +#define TDATA_SIZE 3000 + +/* some smaller subset of TDATA_SIZE used for multiget testing */ +#define TDATA_SET 100 + +/* our custom hash function just returns this all the time */ +#define HASH_FUNC_RESULT 510 + +/* all keys will be prefixed with this */ +static const char prefix[] = "testredis"; + +/* text for values we store */ +static const char txt[] = +"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis at" +"lacus in ligula hendrerit consectetuer. Vestibulum tristique odio" +"iaculis leo. In massa arcu, ultricies a, laoreet nec, hendrerit non," +"neque. Nulla sagittis sapien ac risus. Morbi ligula dolor, vestibulum" +"nec, viverra id, placerat dapibus, arcu. Curabitur egestas feugiat" +"tellus. Donec dignissim. Nunc ante. Curabitur id lorem. In mollis" +"tortor sit amet eros auctor dapibus. Proin nulla sem, tristique in," +"convallis id, iaculis feugiat cras amet."; + +/* + * this datatype is for our custom server determination function. this might + * be useful if you don't want to rely on simply hashing keys to determine + * where a key belongs, but instead want to write something fancy, or use some + * other kind of configuration data, i.e. a hash plus some data about a + * namespace, or whatever. see my_server_func, and test_redis_user_funcs + * for the examples. + */ +typedef struct { + const char *someval; + apr_uint32_t which_server; +} my_hash_server_baton; + + +/* this could do something fancy and return some hash result. + * for simplicity, just return the same value, so we can test it later on. + * if you wanted to use some external hashing library or functions for + * consistent hashing, for example, this would be a good place to do it. + */ +static apr_uint32_t my_hash_func(void *baton, const char *data, + apr_size_t data_len) +{ + + return HASH_FUNC_RESULT; +} + +/* + * a fancy function to determine which server to use given some kind of data + * and a hash value. this example actually ignores the hash value itself + * and pulls some number from the *baton, which is a struct that has some + * kind of meaningful stuff in it. + */ +static apr_redis_server_t *my_server_func(void *baton, + apr_redis_t *mc, + const apr_uint32_t hash) +{ + apr_redis_server_t *ms = NULL; + my_hash_server_baton *mhsb = (my_hash_server_baton *)baton; + + if(mc->ntotal == 0) { + return NULL; + } + + if(mc->ntotal < mhsb->which_server) { + return NULL; + } + + ms = mc->live_servers[mhsb->which_server - 1]; + + return ms; +} + +static apr_uint16_t firsttime = 0; +static int randval(apr_uint32_t high) +{ + apr_uint32_t i = 0; + double d = 0; + + if (firsttime == 0) { + srand((unsigned) (getpid())); + firsttime = 1; + } + + d = (double) rand() / ((double) RAND_MAX + 1); + i = (int) (d * (high - 0 + 1)); + + return i > 0 ? i : 1; +} + +/* + * general test to make sure we can create the redis struct and add + * some servers, but not more than we tell it we can add + */ + +static void test_redis_create(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server, *s; + apr_uint32_t max_servers = 10; + apr_uint32_t i; + apr_uint32_t hash; + + rv = apr_redis_create(pool, max_servers, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + for (i = 1; i <= max_servers; i++) { + apr_port_t port; + + port = PORT + i; + rv = + apr_redis_server_create(pool, HOST, PORT + i, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + s = apr_redis_find_server(redis, HOST, port); + ABTS_PTR_EQUAL(tc, server, s); + + rv = apr_redis_disable_server(redis, s); + ABTS_ASSERT(tc, "server disable failed", rv == APR_SUCCESS); + + rv = apr_redis_enable_server(redis, s); + ABTS_ASSERT(tc, "server enable failed", rv == APR_SUCCESS); + + hash = apr_redis_hash(redis, prefix, strlen(prefix)); + ABTS_ASSERT(tc, "hash failed", hash > 0); + + s = apr_redis_find_server_hash(redis, hash); + ABTS_PTR_NOTNULL(tc, s); + } + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add should have failed", rv != APR_SUCCESS); + +} + +/* install our own custom hashing and server selection routines. */ + +static int create_test_hash(apr_pool_t *p, apr_hash_t *h) +{ + int i; + + for (i = 0; i < TDATA_SIZE; i++) { + char *k, *v; + + k = apr_pstrcat(p, prefix, apr_itoa(p, i), NULL); + v = apr_pstrndup(p, txt, randval((apr_uint32_t)strlen(txt))); + + apr_hash_set(h, k, APR_HASH_KEY_STRING, v); + } + + return i; +} + +static void test_redis_user_funcs(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *found; + apr_uint32_t max_servers = 10; + apr_uint32_t hres; + apr_uint32_t i; + my_hash_server_baton *baton = + apr_pcalloc(pool, sizeof(my_hash_server_baton)); + + rv = apr_redis_create(pool, max_servers, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + /* as noted above, install our custom hash function, and call + * apr_redis_hash. the return value should be our predefined number, + * and our function just ignores the other args, for simplicity. + */ + redis->hash_func = my_hash_func; + + hres = apr_redis_hash(redis, "whatever", sizeof("whatever") - 1); + ABTS_INT_EQUAL(tc, HASH_FUNC_RESULT, hres); + + /* add some servers */ + for(i = 1; i <= 10; i++) { + apr_redis_server_t *ms; + + rv = apr_redis_server_create(pool, HOST, i, 0, 1, 1, 60, 60, &ms); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, ms); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + } + + /* + * set 'which_server' in our server_baton to find the third server + * which should have the same port. + */ + baton->which_server = 3; + redis->server_func = my_server_func; + redis->server_baton = baton; + found = apr_redis_find_server_hash(redis, 0); + ABTS_ASSERT(tc, "wrong server found", found->port == baton->which_server); +} + +/* test non data related commands like stats and version */ +static void test_redis_meta(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_redis_stats_t *stats; + char *result; + apr_status_t rv; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + rv = apr_redis_version(server, pool, &result); + ABTS_PTR_NOTNULL(tc, result); + + rv = apr_redis_stats(server, p, &stats); + ABTS_PTR_NOTNULL(tc, stats); + + /* + * no way to know exactly what will be in most of these, so + * just make sure there is something. + */ + ABTS_ASSERT(tc, "major", stats->major >= 1); + ABTS_ASSERT(tc, "minor", stats->minor >= 0); + ABTS_ASSERT(tc, "patch", stats->patch >= 0); + ABTS_ASSERT(tc, "process_id", stats->process_id >= 0); + ABTS_ASSERT(tc, "uptime_in_seconds", stats->uptime_in_seconds >= 0); + ABTS_ASSERT(tc, "arch_bits", stats->arch_bits >= 0); + ABTS_ASSERT(tc, "connected_clients", stats->connected_clients >= 0); + ABTS_ASSERT(tc, "blocked_clients", stats->blocked_clients >= 0); + ABTS_ASSERT(tc, "maxmemory", stats->maxmemory >= 0); + ABTS_ASSERT(tc, "used_memory", stats->used_memory >= 0); + ABTS_ASSERT(tc, "total_system_memory", stats->total_system_memory >= 0); + ABTS_ASSERT(tc, "total_connections_received", stats->total_connections_received >= 0); + ABTS_ASSERT(tc, "total_commands_processed", stats->total_commands_processed >= 0); + ABTS_ASSERT(tc, "total_net_input_bytes", stats->total_net_input_bytes >= 0); + ABTS_ASSERT(tc, "total_net_output_bytes", stats->total_net_output_bytes >= 0); + ABTS_ASSERT(tc, "keyspace_hits", stats->keyspace_hits >= 0); + ABTS_ASSERT(tc, "keyspace_misses", stats->keyspace_misses >= 0); + ABTS_ASSERT(tc, "role", stats->role >= 0); + ABTS_ASSERT(tc, "connected_slaves", stats->connected_slaves >= 0); + ABTS_ASSERT(tc, "used_cpu_sys", stats->used_cpu_sys >= 0); + ABTS_ASSERT(tc, "used_cpu_user", stats->used_cpu_user >= 0); + ABTS_ASSERT(tc, "cluster_enabled", stats->cluster_enabled >= 0); +} + + +/* basic tests of the increment and decrement commands */ +static void test_redis_incrdecr(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_uint32_t new; + char *result; + apr_size_t len; + apr_uint32_t i; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + rv = apr_redis_set(redis, prefix, "271", sizeof("271") - 1, 27); + ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS); + + for( i = 1; i <= TDATA_SIZE; i++) { + apr_uint32_t expect; + + rv = apr_redis_getp(redis, pool, prefix, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + + expect = i + atoi(result); + + rv = apr_redis_incr(redis, prefix, i, &new); + ABTS_ASSERT(tc, "incr failed", rv == APR_SUCCESS); + + ABTS_INT_EQUAL(tc, expect, new); + + rv = apr_redis_decr(redis, prefix, i, &new); + ABTS_ASSERT(tc, "decr failed", rv == APR_SUCCESS); + + ABTS_INT_EQUAL(tc, atoi(result), new); + + } + + rv = apr_redis_getp(redis, pool, prefix, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + + ABTS_INT_EQUAL(tc, 271, atoi(result)); + + rv = apr_redis_delete(redis, prefix, 0); + ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS); +} + + +/* test setting and getting */ + +static void test_redis_setget(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_hash_t *tdata; + apr_hash_index_t *hi; + char *result; + apr_size_t len; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + tdata = apr_hash_make(pool); + + create_test_hash(pool, tdata); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + void *v; + const char *key; + + apr_hash_this(hi, &k, NULL, &v); + key = k; + + rv = apr_redis_set(redis, key, v, strlen(v), 27); + ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS); + rv = apr_redis_getp(redis, pool, key, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + } + + rv = apr_redis_getp(redis, pool, "nothere3423", &result, &len, NULL); + + ABTS_ASSERT(tc, "get should have failed", rv != APR_SUCCESS); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + const char *key; + + apr_hash_this(hi, &k, NULL, NULL); + key = k; + + rv = apr_redis_delete(redis, key, 0); + ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS); + } +} + +/* test setting and getting */ + +static void test_redis_setexget(abts_case * tc, void *data) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_redis_t *redis; + apr_redis_server_t *server; + apr_hash_t *tdata; + apr_hash_index_t *hi; + char *result; + apr_size_t len; + + rv = apr_redis_create(pool, 1, 0, &redis); + ABTS_ASSERT(tc, "redis create failed", rv == APR_SUCCESS); + + rv = apr_redis_server_create(pool, HOST, PORT, 0, 1, 1, 60, 60, &server); + ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS); + + rv = apr_redis_add_server(redis, server); + ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS); + + tdata = apr_hash_make(pool); + + create_test_hash(pool, tdata); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + void *v; + const char *key; + + apr_hash_this(hi, &k, NULL, &v); + key = k; + + rv = apr_redis_ping(server); + ABTS_ASSERT(tc, "ping failed", rv == APR_SUCCESS); + rv = apr_redis_setex(redis, key, v, strlen(v), 10, 27); + ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS); + rv = apr_redis_getp(redis, pool, key, &result, &len, NULL); + ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS); + } + + rv = apr_redis_getp(redis, pool, "nothere3423", &result, &len, NULL); + + ABTS_ASSERT(tc, "get should have failed", rv != APR_SUCCESS); + + for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) { + const void *k; + const char *key; + + apr_hash_this(hi, &k, NULL, NULL); + key = k; + + rv = apr_redis_delete(redis, key, 0); + ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS); + } +} + +/* use apr_socket stuff to see if there is in fact a Redis server + * running on PORT. + */ +static apr_status_t check_redis(void) +{ + apr_pool_t *pool = p; + apr_status_t rv; + apr_socket_t *sock = NULL; + apr_sockaddr_t *sa; + struct iovec vec[2]; + apr_size_t written; + char buf[128]; + apr_size_t len; + + rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, 0, pool); + if(rv != APR_SUCCESS) { + return rv; + } + + rv = apr_sockaddr_info_get(&sa, HOST, APR_INET, PORT, 0, pool); + if(rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_set(sock, 1 * APR_USEC_PER_SEC); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_connect(sock, sa); + if (rv != APR_SUCCESS) { + return rv; + } + + rv = apr_socket_timeout_set(sock, -1); + if (rv != APR_SUCCESS) { + return rv; + } + + vec[0].iov_base = "PING"; + vec[0].iov_len = sizeof("PING") - 1; + + vec[1].iov_base = "\r\n"; + vec[1].iov_len = sizeof("\r\n") -1; + + rv = apr_socket_sendv(sock, vec, 2, &written); + if (rv != APR_SUCCESS) { + return rv; + } + + len = sizeof(buf); + rv = apr_socket_recv(sock, buf, &len); + if(rv != APR_SUCCESS) { + return rv; + } + if(strncmp(buf, "+PONG", sizeof("+PONG")-1) != 0) { + rv = APR_EGENERAL; + } + + apr_socket_close(sock); + return rv; +} + +abts_suite *testredis(abts_suite * suite) +{ + apr_status_t rv; + suite = ADD_SUITE(suite); + /* check for a running redis on the typical port before + * trying to run the tests. succeed if we don't find one. + */ + rv = check_redis(); + if (rv == APR_SUCCESS) { + abts_run_test(suite, test_redis_create, NULL); + abts_run_test(suite, test_redis_user_funcs, NULL); + abts_run_test(suite, test_redis_meta, NULL); + abts_run_test(suite, test_redis_setget, NULL); + abts_run_test(suite, test_redis_setexget, NULL); + /* abts_run_test(suite, test_redis_multiget, NULL); */ + abts_run_test(suite, test_redis_incrdecr, NULL); + } + else { + abts_log_message("Error %d occurred attempting to reach Redis " + "on %s:%d. Skipping apr_redis tests...", + rv, HOST, PORT); + } + + return suite; +} diff --git a/test/testsiphash.c b/test/testsiphash.c new file mode 100644 index 0000000000000..58321adebd854 --- /dev/null +++ b/test/testsiphash.c @@ -0,0 +1,148 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "apr_siphash.h" + +#include "abts.h" +#include "testutil.h" + +/* + * Wrapped test vectors from the authors, see + * https://131002.net/siphash/siphash24.c + */ +typedef unsigned char u8; +#define crypto_auth apr_siphash24_auth + +#define MAXLEN 64 + +/* + SipHash-2-4 output with + k = 00 01 02 ... + and + in = (empty string) + in = 00 (1 byte) + in = 00 01 (2 bytes) + in = 00 01 02 (3 bytes) + ... + in = 00 01 02 ... 3e (63 bytes) +*/ +static const u8 vectors[MAXLEN][8] = +{ + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } +}; + +static int test_vectors(void) +{ + u8 in[MAXLEN], out[8], k[16]; + int i; + int ok = 1; + + for( i = 0; i < 16; ++i ) k[i] = i; + + for( i = 0; i < MAXLEN; ++i ) + { + in[i] = i; + crypto_auth( out, in, i, k ); + + if ( memcmp( out, vectors[i], 8 ) ) + { + printf( "test vector failed for %d bytes\n", i ); + ok = 0; + } + } + + return ok; +} + +static void test_siphash_vectors(abts_case *tc, void *data) +{ + ABTS_ASSERT(tc, "SipHash-2-4 test vectors", test_vectors()); +} + +abts_suite *testsiphash(abts_suite *suite) +{ + suite = ADD_SUITE(suite); + + abts_run_test(suite, test_siphash_vectors, NULL); + + return suite; +} diff --git a/test/testutil.h b/test/testutil.h index c471af40a4a66..eaa7e75905725 100644 --- a/test/testutil.h +++ b/test/testutil.h @@ -61,11 +61,13 @@ abts_suite *testldap(abts_suite *suite); abts_suite *testdbd(abts_suite *suite); abts_suite *testdate(abts_suite *suite); abts_suite *testmemcache(abts_suite *suite); +abts_suite *testredis(abts_suite *suite); abts_suite *testreslist(abts_suite *suite); abts_suite *testqueue(abts_suite *suite); abts_suite *testxml(abts_suite *suite); abts_suite *testxlate(abts_suite *suite); abts_suite *testrmm(abts_suite *suite); abts_suite *testdbm(abts_suite *suite); +abts_suite *testsiphash(abts_suite *suite); #endif /* APR_TEST_INCLUDES */ |