http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c ---------------------------------------------------------------------- diff --git a/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c new file mode 100644 index 0000000..58e64fb --- /dev/null +++ b/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c @@ -0,0 +1,335 @@ +/** + * 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 "org_apache_commons_crypto_random.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef UNIX +#include <pthread.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/types.h> +#endif + +#ifdef WINDOWS +#include <windows.h> +#endif + +#include "OpensslCryptoRandomNative.h" + +#ifdef UNIX +static void * (*dlsym_CRYPTO_malloc) (int, const char *, int); +static void (*dlsym_CRYPTO_free) (void *); +static int (*dlsym_CRYPTO_num_locks) (void); +static void (*dlsym_CRYPTO_set_locking_callback) (void (*)()); +static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)()); +static void (*dlsym_ENGINE_load_rdrand) (void); +static ENGINE * (*dlsym_ENGINE_by_id) (const char *); +static int (*dlsym_ENGINE_init) (ENGINE *); +static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int); +static int (*dlsym_ENGINE_finish) (ENGINE *); +static int (*dlsym_ENGINE_free) (ENGINE *); +static void (*dlsym_ENGINE_cleanup) (void); +static int (*dlsym_RAND_bytes) (unsigned char *, int); +static unsigned long (*dlsym_ERR_get_error) (void); +#endif + +#ifdef WINDOWS +typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int); +typedef void (__cdecl *__dlsym_CRYPTO_free) (void *); +typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void); +typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) \ + (void (*)(int, int, char *, int); +typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void); +typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *); +typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *); +typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int); +typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *); +typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *); +typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void); +typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int); +typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void); +static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc; +static __dlsym_CRYPTO_free dlsym_CRYPTO_free; +static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks; +static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback; +static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand; +static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id; +static __dlsym_ENGINE_init dlsym_ENGINE_init; +static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default; +static __dlsym_ENGINE_finish dlsym_ENGINE_finish; +static __dlsym_ENGINE_free dlsym_ENGINE_free; +static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup; +static __dlsym_RAND_bytes dlsym_RAND_bytes; +static __dlsym_ERR_get_error dlsym_ERR_get_error; +#endif + +static ENGINE * openssl_rand_init(void); +static void openssl_rand_clean(ENGINE *eng, int clean_locks); +static int openssl_rand_bytes(unsigned char *buf, int num); + +JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpensslCryptoRandomNative_initSR + (JNIEnv *env, jclass clazz) +{ + char msg[1000]; +#ifdef UNIX + void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL); +#endif + +#ifdef WINDOWS + HMODULE openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY); +#endif + + if (!openssl) { + snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY, \ + dlerror()); + THROW(env, "java/lang/UnsatisfiedLinkError", msg); + return; + } + +#ifdef UNIX + dlerror(); // Clear any existing error + LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc"); + LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free"); + LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks"); + LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, \ + env, openssl, "CRYPTO_set_locking_callback"); + LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, \ + openssl, "CRYPTO_set_id_callback"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, \ + openssl, "ENGINE_load_rdrand"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env, \ + openssl, "ENGINE_set_default"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free"); + LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup"); + LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes"); + LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error"); +#endif + +#ifdef WINDOWS + LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc, \ + env, openssl, "CRYPTO_malloc"); + LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, \ + env, openssl, "CRYPTO_free"); + LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, \ + env, openssl, "CRYPTO_num_locks"); + LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, \ + dlsym_CRYPTO_set_locking_callback, \ + env, openssl, "CRYPTO_set_locking_callback"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, \ + env, openssl, "ENGINE_load_rdrand"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \ + env, openssl, "ENGINE_by_id"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, \ + env, openssl, "ENGINE_init"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default, \ + env, openssl, "ENGINE_set_default"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, \ + env, openssl, "ENGINE_finish"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \ + env, openssl, "ENGINE_free"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, \ + env, openssl, "ENGINE_cleanup"); + LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, \ + env, openssl, "RAND_bytes"); + LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, \ + env, openssl, "ERR_get_error"); +#endif + + openssl_rand_init(); +} + +JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpensslCryptoRandomNative_nextRandBytes___3B + (JNIEnv *env, jobject object, jbyteArray bytes) +{ + if (NULL == bytes) { + THROW(env, "java/lang/NullPointerException", "Buffer cannot be null."); + return JNI_FALSE; + } + jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL); + if (NULL == b) { + THROW(env, "java/lang/InternalError", "Cannot get bytes array."); + return JNI_FALSE; + } + int b_len = (*env)->GetArrayLength(env, bytes); + int ret = openssl_rand_bytes((unsigned char *)b, b_len); + (*env)->ReleaseByteArrayElements(env, bytes, b, 0); + + if (1 != ret) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +/** + * To ensure thread safety for random number generators, we need to call + * CRYPTO_set_locking_callback. + * http://wiki.openssl.org/index.php/Random_Numbers + * Example: crypto/threads/mttest.c + */ + +#ifdef WINDOWS +static void windows_locking_callback(int mode, int type, char *file, int line); +static HANDLE *lock_cs; + +static void locks_setup(void) +{ + int i; + lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE), \ + __FILE__, __LINE__); + + for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { + lock_cs[i] = CreateMutex(NULL, FALSE, NULL); + } + dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) \ + windows_locking_callback); + /* id callback defined */ +} + +static void locks_cleanup(void) +{ + int i; + dlsym_CRYPTO_set_locking_callback(NULL); + + for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { + CloseHandle(lock_cs[i]); + } + dlsym_CRYPTO_free(lock_cs); +} + +static void windows_locking_callback(int mode, int type, char *file, int line) +{ + UNUSED(file), UNUSED(line); + + if (mode & CRYPTO_LOCK) { + WaitForSingleObject(lock_cs[type], INFINITE); + } else { + ReleaseMutex(lock_cs[type]); + } +} +#endif /* WINDOWS */ + +#ifdef UNIX +static void pthreads_locking_callback(int mode, int type, char *file, int line); +static unsigned long pthreads_thread_id(void); +static pthread_mutex_t *lock_cs; + +static void locks_setup(void) +{ + int i; + lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \ + sizeof(pthread_mutex_t), __FILE__, __LINE__); + + for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { + pthread_mutex_init(&(lock_cs[i]), NULL); + } + + dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); + dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); +} + +static void locks_cleanup(void) +{ + int i; + dlsym_CRYPTO_set_locking_callback(NULL); + + for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { + pthread_mutex_destroy(&(lock_cs[i])); + } + + dlsym_CRYPTO_free(lock_cs); +} + +static void pthreads_locking_callback(int mode, int type, char *file, int line) +{ + UNUSED(file), UNUSED(line); + + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&(lock_cs[type])); + } else { + pthread_mutex_unlock(&(lock_cs[type])); + } +} + +static unsigned long pthreads_thread_id(void) +{ + return (unsigned long)syscall(SYS_gettid); +} + +#endif /* UNIX */ + +/** + * If using an Intel chipset with RDRAND, the high-performance hardware + * random number generator will be used. + */ +static ENGINE * openssl_rand_init(void) +{ + locks_setup(); + + dlsym_ENGINE_load_rdrand(); + ENGINE *eng = dlsym_ENGINE_by_id("rdrand"); + + int ret = -1; + do { + if (NULL == eng) { + break; + } + + int rc = dlsym_ENGINE_init(eng); + if (0 == rc) { + break; + } + + rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND); + if (0 == rc) { + break; + } + + ret = 0; + } while(0); + + if (ret == -1) { + openssl_rand_clean(eng, 0); + } + + return eng; +} + +static void openssl_rand_clean(ENGINE *eng, int clean_locks) +{ + if (NULL != eng) { + dlsym_ENGINE_finish(eng); + dlsym_ENGINE_free(eng); + } + + dlsym_ENGINE_cleanup(); + if (clean_locks) { + locks_cleanup(); + } +} + +static int openssl_rand_bytes(unsigned char *buf, int num) +{ + return dlsym_RAND_bytes(buf, num); +}
http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c ---------------------------------------------------------------------- diff --git a/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c deleted file mode 100644 index 5dcfd1f..0000000 --- a/src/main/native/org/apache/commons/crypto/random/OpensslSecureRandomNative.c +++ /dev/null @@ -1,335 +0,0 @@ -/** - * 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 "org_apache_commons_crypto_random.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef UNIX -#include <pthread.h> -#include <unistd.h> -#include <sys/syscall.h> -#include <sys/types.h> -#endif - -#ifdef WINDOWS -#include <windows.h> -#endif - -#include "OpensslSecureRandomNative.h" - -#ifdef UNIX -static void * (*dlsym_CRYPTO_malloc) (int, const char *, int); -static void (*dlsym_CRYPTO_free) (void *); -static int (*dlsym_CRYPTO_num_locks) (void); -static void (*dlsym_CRYPTO_set_locking_callback) (void (*)()); -static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)()); -static void (*dlsym_ENGINE_load_rdrand) (void); -static ENGINE * (*dlsym_ENGINE_by_id) (const char *); -static int (*dlsym_ENGINE_init) (ENGINE *); -static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int); -static int (*dlsym_ENGINE_finish) (ENGINE *); -static int (*dlsym_ENGINE_free) (ENGINE *); -static void (*dlsym_ENGINE_cleanup) (void); -static int (*dlsym_RAND_bytes) (unsigned char *, int); -static unsigned long (*dlsym_ERR_get_error) (void); -#endif - -#ifdef WINDOWS -typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int); -typedef void (__cdecl *__dlsym_CRYPTO_free) (void *); -typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void); -typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) \ - (void (*)(int, int, char *, int); -typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void); -typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *); -typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *); -typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int); -typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *); -typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *); -typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void); -typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int); -typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void); -static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc; -static __dlsym_CRYPTO_free dlsym_CRYPTO_free; -static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks; -static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback; -static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand; -static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id; -static __dlsym_ENGINE_init dlsym_ENGINE_init; -static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default; -static __dlsym_ENGINE_finish dlsym_ENGINE_finish; -static __dlsym_ENGINE_free dlsym_ENGINE_free; -static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup; -static __dlsym_RAND_bytes dlsym_RAND_bytes; -static __dlsym_ERR_get_error dlsym_ERR_get_error; -#endif - -static ENGINE * openssl_rand_init(void); -static void openssl_rand_clean(ENGINE *eng, int clean_locks); -static int openssl_rand_bytes(unsigned char *buf, int num); - -JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpensslSecureRandomNative_initSR - (JNIEnv *env, jclass clazz) -{ - char msg[1000]; -#ifdef UNIX - void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL); -#endif - -#ifdef WINDOWS - HMODULE openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY); -#endif - - if (!openssl) { - snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY, \ - dlerror()); - THROW(env, "java/lang/UnsatisfiedLinkError", msg); - return; - } - -#ifdef UNIX - dlerror(); // Clear any existing error - LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc"); - LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free"); - LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks"); - LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, \ - env, openssl, "CRYPTO_set_locking_callback"); - LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, \ - openssl, "CRYPTO_set_id_callback"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, \ - openssl, "ENGINE_load_rdrand"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env, \ - openssl, "ENGINE_set_default"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free"); - LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup"); - LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes"); - LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error"); -#endif - -#ifdef WINDOWS - LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc, \ - env, openssl, "CRYPTO_malloc"); - LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, \ - env, openssl, "CRYPTO_free"); - LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, \ - env, openssl, "CRYPTO_num_locks"); - LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, \ - dlsym_CRYPTO_set_locking_callback, \ - env, openssl, "CRYPTO_set_locking_callback"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, \ - env, openssl, "ENGINE_load_rdrand"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \ - env, openssl, "ENGINE_by_id"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, \ - env, openssl, "ENGINE_init"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default, \ - env, openssl, "ENGINE_set_default"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, \ - env, openssl, "ENGINE_finish"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \ - env, openssl, "ENGINE_free"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, \ - env, openssl, "ENGINE_cleanup"); - LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, \ - env, openssl, "RAND_bytes"); - LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, \ - env, openssl, "ERR_get_error"); -#endif - - openssl_rand_init(); -} - -JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpensslSecureRandomNative_nextRandBytes___3B - (JNIEnv *env, jobject object, jbyteArray bytes) -{ - if (NULL == bytes) { - THROW(env, "java/lang/NullPointerException", "Buffer cannot be null."); - return JNI_FALSE; - } - jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL); - if (NULL == b) { - THROW(env, "java/lang/InternalError", "Cannot get bytes array."); - return JNI_FALSE; - } - int b_len = (*env)->GetArrayLength(env, bytes); - int ret = openssl_rand_bytes((unsigned char *)b, b_len); - (*env)->ReleaseByteArrayElements(env, bytes, b, 0); - - if (1 != ret) { - return JNI_FALSE; - } - return JNI_TRUE; -} - -/** - * To ensure thread safety for random number generators, we need to call - * CRYPTO_set_locking_callback. - * http://wiki.openssl.org/index.php/Random_Numbers - * Example: crypto/threads/mttest.c - */ - -#ifdef WINDOWS -static void windows_locking_callback(int mode, int type, char *file, int line); -static HANDLE *lock_cs; - -static void locks_setup(void) -{ - int i; - lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE), \ - __FILE__, __LINE__); - - for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { - lock_cs[i] = CreateMutex(NULL, FALSE, NULL); - } - dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) \ - windows_locking_callback); - /* id callback defined */ -} - -static void locks_cleanup(void) -{ - int i; - dlsym_CRYPTO_set_locking_callback(NULL); - - for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { - CloseHandle(lock_cs[i]); - } - dlsym_CRYPTO_free(lock_cs); -} - -static void windows_locking_callback(int mode, int type, char *file, int line) -{ - UNUSED(file), UNUSED(line); - - if (mode & CRYPTO_LOCK) { - WaitForSingleObject(lock_cs[type], INFINITE); - } else { - ReleaseMutex(lock_cs[type]); - } -} -#endif /* WINDOWS */ - -#ifdef UNIX -static void pthreads_locking_callback(int mode, int type, char *file, int line); -static unsigned long pthreads_thread_id(void); -static pthread_mutex_t *lock_cs; - -static void locks_setup(void) -{ - int i; - lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \ - sizeof(pthread_mutex_t), __FILE__, __LINE__); - - for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { - pthread_mutex_init(&(lock_cs[i]), NULL); - } - - dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); - dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); -} - -static void locks_cleanup(void) -{ - int i; - dlsym_CRYPTO_set_locking_callback(NULL); - - for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { - pthread_mutex_destroy(&(lock_cs[i])); - } - - dlsym_CRYPTO_free(lock_cs); -} - -static void pthreads_locking_callback(int mode, int type, char *file, int line) -{ - UNUSED(file), UNUSED(line); - - if (mode & CRYPTO_LOCK) { - pthread_mutex_lock(&(lock_cs[type])); - } else { - pthread_mutex_unlock(&(lock_cs[type])); - } -} - -static unsigned long pthreads_thread_id(void) -{ - return (unsigned long)syscall(SYS_gettid); -} - -#endif /* UNIX */ - -/** - * If using an Intel chipset with RDRAND, the high-performance hardware - * random number generator will be used. - */ -static ENGINE * openssl_rand_init(void) -{ - locks_setup(); - - dlsym_ENGINE_load_rdrand(); - ENGINE *eng = dlsym_ENGINE_by_id("rdrand"); - - int ret = -1; - do { - if (NULL == eng) { - break; - } - - int rc = dlsym_ENGINE_init(eng); - if (0 == rc) { - break; - } - - rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND); - if (0 == rc) { - break; - } - - ret = 0; - } while(0); - - if (ret == -1) { - openssl_rand_clean(eng, 0); - } - - return eng; -} - -static void openssl_rand_clean(ENGINE *eng, int clean_locks) -{ - if (NULL != eng) { - dlsym_ENGINE_finish(eng); - dlsym_ENGINE_free(eng); - } - - dlsym_ENGINE_cleanup(); - if (clean_locks) { - locks_cleanup(); - } -} - -static int openssl_rand_bytes(unsigned char *buf, int num) -{ - return dlsym_RAND_bytes(buf, num); -} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/site/xdoc/userguide.xml ---------------------------------------------------------------------- diff --git a/src/site/xdoc/userguide.xml b/src/site/xdoc/userguide.xml index 0af471d..5accf0e 100644 --- a/src/site/xdoc/userguide.xml +++ b/src/site/xdoc/userguide.xml @@ -32,7 +32,7 @@ </a> </td> <td> - The interface for SecureRandom. + The interface for CryptoRandom. </td> </tr> <tr> @@ -62,7 +62,7 @@ <ol style="list-style-type: decimal"> <h4>Usage of Random API</h4> <p> - SecureRandom provides a cryptographically strong random number generators. + CryptoRandom provides a cryptographically strong random number generators. The default implementation will use Intel� Digital Random Number Generator (DRNG) for accelerating the random generation. </p> @@ -73,13 +73,13 @@ byte[] key = new byte[16];<br/> byte[] iv = new byte[16];<br/> Properties properties = new Properties();<br/> - //Gets the 'SecureRandom' instance.<br/> - SecureRandom secureRandom = SecureRandomFactory.getSecureRandom(properties);<br/> + //Gets the 'CryptoRandom' instance.<br/> + CryptoRandom CryptoRandom = CryptoRandomFactory.getCryptoRandom(properties);<br/> //Generates random bytes and places them into the byte array.<br/> - secureRandom.nextBytes(key);<br/> - secureRandom.nextBytes(iv);<br/> - //Closes the SecureRandom.<br/> - secureRandom.close();<br/> + CryptoRandom.nextBytes(key);<br/> + CryptoRandom.nextBytes(iv);<br/> + //Closes the CryptoRandom.<br/> + CryptoRandom.close();<br/> </td> </tr> </table> @@ -96,8 +96,8 @@ <tr> <td> Properties properties = new Properties();<br/> - //Creates a Cipher instance with the transformation and properties.<br/> - Cipher cipher = Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, properties);<br/><br/> + //Creates a CryptoCipher instance with the transformation and properties.<br/> + CryptoCipher cipher = Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, properties);<br/><br/> String input = "hello world!";<br/> int inputOffset = 0;<br/> int inputLen = input.length();<br/> @@ -121,7 +121,7 @@ <td> Properties properties = new Properties();<br/> //Creates a Cipher instance with the transformation and properties.<br/> - Cipher cipher = Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, properties);<br/><br/> + CryptoCipher cipher = Utils.getCipherInstance(CipherTransformation.AES_CTR_NOPADDING, properties);<br/><br/> int bufferSize = 4096;<br/> ByteBuffer inBuffer = ByteBuffer.allocateDirect(bufferSize);<br/> ByteBuffer outBuffer = ByteBuffer.allocateDirect(bufferSize);<br/> @@ -140,9 +140,9 @@ <h4>Usage of Stream API</h4> <p> - Stream provides the data encryption and decryption in stream manner. We provide CipherInputStream, - CTRCipherInputStream, PositionedCipherInputstream implementations for InputStream and CipherOutputStream, - CTRCipherOutputStream implementations for OutputStream. + Stream provides the data encryption and decryption in stream manner. We provide CryptoInputStream, + CTRCryptoInputStream, PositionedCryptoInputStream implementations for InputStream and CryptoOutputStream, + CTRCryptoOutputStream implementations for OutputStream. </p> <h5>Usage of stream encryption</h5> <table> @@ -151,13 +151,13 @@ int bufferSize = 4096;<br/> String input = "hello world!";<br/> byte[] decryptedData = new byte[1024];<br/> - //Encryption with CipherOutputStream.<br/> + //Encryption with CryptoOutputStream.<br/> //Initializes the cipher with ENCRYPT_MODE,key and iv.<br/> cipher.init(Cipher.ENCRYPT_MODE, key, iv);<br/> // Constructs the original OutputStream.<br/> OutputStream outputStream = new ByteArrayOutputStream();<br/> - //Constructs the instance of CipherOutputStream.<br/> - CipherOutputStream cos = new CipherOutputStream(outputStream, cipher, bufferSize, key, iv);<br/> + //Constructs the instance of CryptoOutputStream.<br/> + CryptoOutputStream cos = new CryptoOutputStream(outputStream, cipher, bufferSize, key, iv);<br/> cos.write(input.getBytes("UTF-8"));<br/> cos.flush();<br/> cos.close();<br/> @@ -168,13 +168,13 @@ <table> <tr> <td> - // Decryption with CipherInputStream.<br/> + // Decryption with CryptoInputStream.<br/> //Initializes the cipher with DECRYPT_MODE,key and iv.<br/> cipher.init(Cipher.DECRYPT_MODE, key, iv);<br/> //Constructs the original InputStream.<br/> InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());<br/> - //Constructs the instance of CipherInputStream.<br/> - CipherInputStream cis = new CipherInputStream(inputStream, cipher, bufferSize, key, iv);<br/> + //Constructs the instance of CryptoInputStream.<br/> + CryptoInputStream cis = new CryptoInputStream(inputStream, cipher, bufferSize, key, iv);<br/> int decryptedLen = cis.read(decryptedData, 0, 1024);<br/> cis.close();<br/> </td> http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java index 67ab5c0..f60f29c 100644 --- a/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java +++ b/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java @@ -48,7 +48,7 @@ public abstract class AbstractCipherTest { 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16}; static final byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - Cipher enc, dec; + CryptoCipher enc, dec; @Before public void setup() { @@ -96,19 +96,19 @@ public abstract class AbstractCipherTest { GeneralSecurityException, IOException { ByteBuffer decResult = ByteBuffer.allocateDirect(BYTEBUFFER_SIZE); ByteBuffer encResult = ByteBuffer.allocateDirect(BYTEBUFFER_SIZE); - Cipher enc, dec; + CryptoCipher enc, dec; enc = getCipher(transformation); dec = getCipher(transformation); try { - enc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); + enc.init(CryptoCipher.ENCRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } catch (Exception e) { Assert.fail("AES failed initialisation - " + e.toString()); } try { - dec.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); + dec.init(CryptoCipher.DECRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } catch (Exception e) { Assert.fail("AES failed initialisation - " + e.toString()); } @@ -219,21 +219,21 @@ public abstract class AbstractCipherTest { dec = getCipher(transformation); try { - enc.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); + enc.init(CryptoCipher.ENCRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } catch (Exception e) { Assert.fail("AES failed initialisation - " + e.toString()); } try { - dec.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); + dec.init(CryptoCipher.DECRYPT_MODE, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } catch (Exception e) { Assert.fail("AES failed initialisation - " + e.toString()); } } - private Cipher getCipher(CipherTransformation transformation) { + private CryptoCipher getCipher(CipherTransformation transformation) { try { - return (Cipher) ReflectionUtils + return (CryptoCipher) ReflectionUtils .newInstance(ReflectionUtils.getClassByName(cipherClass), props, transformation); } catch (ClassNotFoundException e) { http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/cipher/CipherFactoryTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/cipher/CipherFactoryTest.java b/src/test/java/org/apache/commons/crypto/cipher/CipherFactoryTest.java deleted file mode 100644 index cd995df..0000000 --- a/src/test/java/org/apache/commons/crypto/cipher/CipherFactoryTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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. - */ -package org.apache.commons.crypto.cipher; - -import java.security.GeneralSecurityException; -import java.util.Properties; - -import org.apache.commons.crypto.conf.ConfigurationKeys; - -import junit.framework.Assert; -import org.junit.Test; - -public class CipherFactoryTest { - @Test - public void testDefaultCipher() throws GeneralSecurityException { - Cipher defaultCipher = CipherFactory.getInstance( - CipherTransformation.AES_CBC_NOPADDING); - Assert.assertEquals(OpensslCipher.class.getName(), - defaultCipher.getClass().getName()); - } - - @Test - public void testEmptyCipher() throws GeneralSecurityException { - Properties properties = new Properties(); - properties.put(ConfigurationKeys.COMMONS_CRYPTO_CIPHER_CLASSES_KEY, ""); - Cipher defaultCipher = CipherFactory.getInstance( - CipherTransformation.AES_CBC_NOPADDING, properties); - Assert.assertEquals(OpensslCipher.class.getName(), - defaultCipher.getClass().getName()); - } - - @Test - public void testInvalidCipher() throws GeneralSecurityException { - Properties properties = new Properties(); - properties.put(ConfigurationKeys.COMMONS_CRYPTO_CIPHER_CLASSES_KEY, - "InvalidCipherName"); - Cipher defaultCipher = CipherFactory.getInstance( - CipherTransformation.AES_CBC_NOPADDING, properties); - Assert.assertEquals(JceCipher.class.getName(), - defaultCipher.getClass().getName()); - } -} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/cipher/CryptoCipherFactoryTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/cipher/CryptoCipherFactoryTest.java b/src/test/java/org/apache/commons/crypto/cipher/CryptoCipherFactoryTest.java new file mode 100644 index 0000000..3653cf9 --- /dev/null +++ b/src/test/java/org/apache/commons/crypto/cipher/CryptoCipherFactoryTest.java @@ -0,0 +1,57 @@ +/** + * 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. + */ +package org.apache.commons.crypto.cipher; + +import java.security.GeneralSecurityException; +import java.util.Properties; + +import org.apache.commons.crypto.conf.ConfigurationKeys; + +import junit.framework.Assert; +import org.junit.Test; + +public class CryptoCipherFactoryTest { + @Test + public void testDefaultCipher() throws GeneralSecurityException { + CryptoCipher defaultCipher = CryptoCipherFactory.getInstance( + CipherTransformation.AES_CBC_NOPADDING); + Assert.assertEquals(OpensslCipher.class.getName(), + defaultCipher.getClass().getName()); + } + + @Test + public void testEmptyCipher() throws GeneralSecurityException { + Properties properties = new Properties(); + properties.put(ConfigurationKeys.COMMONS_CRYPTO_CIPHER_CLASSES_KEY, ""); + CryptoCipher defaultCipher = CryptoCipherFactory.getInstance( + CipherTransformation.AES_CBC_NOPADDING, properties); + Assert.assertEquals(OpensslCipher.class.getName(), + defaultCipher.getClass().getName()); + } + + @Test + public void testInvalidCipher() throws GeneralSecurityException { + Properties properties = new Properties(); + properties.put(ConfigurationKeys.COMMONS_CRYPTO_CIPHER_CLASSES_KEY, + "InvalidCipherName"); + CryptoCipher defaultCipher = CryptoCipherFactory.getInstance( + CipherTransformation.AES_CBC_NOPADDING, properties); + Assert.assertEquals(JceCipher.class.getName(), + defaultCipher.getClass().getName()); + } +} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java b/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java index d2919ea..1d1db88 100644 --- a/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java +++ b/src/test/java/org/apache/commons/crypto/random/AbstractRandomTest.java @@ -24,11 +24,11 @@ import org.junit.Test; public abstract class AbstractRandomTest { - public abstract SecureRandom getSecureRandom() throws GeneralSecurityException; + public abstract CryptoRandom getCryptoRandom() throws GeneralSecurityException; @Test(timeout=120000) public void testRandomBytes() throws Exception { - SecureRandom random = getSecureRandom(); + CryptoRandom random = getCryptoRandom(); // len = 16 checkRandomBytes(random, 16); // len = 32 @@ -44,7 +44,7 @@ public abstract class AbstractRandomTest { * Test will timeout if secure random implementation always returns a * constant value. */ - private void checkRandomBytes(SecureRandom random, int len) { + private void checkRandomBytes(CryptoRandom random, int len) { byte[] bytes = new byte[len]; byte[] bytes1 = new byte[len]; random.nextBytes(bytes); http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/TestJavaCryptoRandom.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/TestJavaCryptoRandom.java b/src/test/java/org/apache/commons/crypto/random/TestJavaCryptoRandom.java new file mode 100644 index 0000000..bb84bc7 --- /dev/null +++ b/src/test/java/org/apache/commons/crypto/random/TestJavaCryptoRandom.java @@ -0,0 +1,40 @@ +/** + * 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. + */ +package org.apache.commons.crypto.random; + +import java.security.GeneralSecurityException; +import java.util.Properties; + +import org.apache.commons.crypto.conf.ConfigurationKeys; +import static junit.framework.Assert.fail; + +public class TestJavaCryptoRandom extends AbstractRandomTest { + + @Override + public CryptoRandom getCryptoRandom() throws GeneralSecurityException { + Properties props = new Properties(); + props.setProperty(ConfigurationKeys.COMMONS_CRYPTO_SECURE_RANDOM_CLASSES_KEY, + JavaCryptoRandom.class.getName()); + CryptoRandom random = CryptoRandomFactory.getCryptoRandom(props); + if ( !(random instanceof JavaCryptoRandom)) { + fail("The CryptoRandom should be: " + JavaCryptoRandom.class.getName()); + } + return random; + } + +} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java b/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java deleted file mode 100644 index 2bbed66..0000000 --- a/src/test/java/org/apache/commons/crypto/random/TestJavaSecureRandom.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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. - */ -package org.apache.commons.crypto.random; - -import java.security.GeneralSecurityException; -import java.util.Properties; - -import org.apache.commons.crypto.conf.ConfigurationKeys; -import static junit.framework.Assert.fail; - -public class TestJavaSecureRandom extends AbstractRandomTest { - - @Override - public SecureRandom getSecureRandom() throws GeneralSecurityException { - Properties props = new Properties(); - props.setProperty(ConfigurationKeys.COMMONS_CRYPTO_SECURE_RANDOM_CLASSES_KEY, - JavaSecureRandom.class.getName()); - SecureRandom random = SecureRandomFactory.getSecureRandom(props); - if ( !(random instanceof JavaSecureRandom)) { - fail("The SecureRandom should be: " + JavaSecureRandom.class.getName()); - } - return random; - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/TestOpensslCryptoRandom.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/TestOpensslCryptoRandom.java b/src/test/java/org/apache/commons/crypto/random/TestOpensslCryptoRandom.java new file mode 100644 index 0000000..fede249 --- /dev/null +++ b/src/test/java/org/apache/commons/crypto/random/TestOpensslCryptoRandom.java @@ -0,0 +1,40 @@ +/** + * 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. + */ +package org.apache.commons.crypto.random; + +import java.security.GeneralSecurityException; +import java.util.Properties; + +import org.apache.commons.crypto.conf.ConfigurationKeys; +import static junit.framework.Assert.fail; + +public class TestOpensslCryptoRandom extends AbstractRandomTest { + + @Override + public CryptoRandom getCryptoRandom() throws GeneralSecurityException { + Properties props = new Properties(); + props.setProperty(ConfigurationKeys.COMMONS_CRYPTO_SECURE_RANDOM_CLASSES_KEY, + OpensslCryptoRandom.class.getName()); + CryptoRandom random = CryptoRandomFactory.getCryptoRandom(props); + if ( !(random instanceof OpensslCryptoRandom)) { + fail("The CryptoRandom should be: " + OpensslCryptoRandom.class.getName()); + } + return random; + } + +} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java b/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java deleted file mode 100644 index 13224dd..0000000 --- a/src/test/java/org/apache/commons/crypto/random/TestOpensslSecureRandom.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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. - */ -package org.apache.commons.crypto.random; - -import java.security.GeneralSecurityException; -import java.util.Properties; - -import org.apache.commons.crypto.conf.ConfigurationKeys; -import static junit.framework.Assert.fail; - -public class TestOpensslSecureRandom extends AbstractRandomTest { - - @Override - public SecureRandom getSecureRandom() throws GeneralSecurityException { - Properties props = new Properties(); - props.setProperty(ConfigurationKeys.COMMONS_CRYPTO_SECURE_RANDOM_CLASSES_KEY, - OpensslSecureRandom.class.getName()); - SecureRandom random = SecureRandomFactory.getSecureRandom(props); - if ( !(random instanceof OpensslSecureRandom)) { - fail("The SecureRandom should be: " + OpensslSecureRandom.class.getName()); - } - return random; - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/TestOsCryptoRandom.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/TestOsCryptoRandom.java b/src/test/java/org/apache/commons/crypto/random/TestOsCryptoRandom.java new file mode 100644 index 0000000..9968c34 --- /dev/null +++ b/src/test/java/org/apache/commons/crypto/random/TestOsCryptoRandom.java @@ -0,0 +1,28 @@ +/** + * 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. + */ +package org.apache.commons.crypto.random; + +import java.util.Properties; + +public class TestOsCryptoRandom extends AbstractRandomTest{ + + @Override + public CryptoRandom getCryptoRandom() { + return new OsCryptoRandom(new Properties()); + } +} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java b/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java deleted file mode 100644 index de88511..0000000 --- a/src/test/java/org/apache/commons/crypto/random/TestOsSecureRandom.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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. - */ -package org.apache.commons.crypto.random; - -import java.util.Properties; - -public class TestOsSecureRandom extends AbstractRandomTest{ - - @Override - public SecureRandom getSecureRandom() { - return new OsSecureRandom(new Properties()); - } -} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/stream/AbstractCipherStreamTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/stream/AbstractCipherStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/AbstractCipherStreamTest.java index 40b1487..a89e4d1 100644 --- a/src/test/java/org/apache/commons/crypto/stream/AbstractCipherStreamTest.java +++ b/src/test/java/org/apache/commons/crypto/stream/AbstractCipherStreamTest.java @@ -31,11 +31,8 @@ import java.security.SecureRandom; import java.util.Properties; import java.util.Random; -import org.apache.commons.crypto.cipher.Cipher; -import org.apache.commons.crypto.cipher.CipherTransformation; -import org.apache.commons.crypto.cipher.JceCipher; -import org.apache.commons.crypto.cipher.Openssl; -import org.apache.commons.crypto.cipher.OpensslCipher; +import org.apache.commons.crypto.cipher.*; +import org.apache.commons.crypto.cipher.CryptoCipher; import org.apache.commons.crypto.utils.ReflectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -107,7 +104,7 @@ public abstract class AbstractCipherStreamTest { } private void doSkipTest(String cipherClass, boolean withChannel) throws IOException { - InputStream in = getCipherInputStream(new ByteArrayInputStream(encData), + InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), defaultBufferSize, iv, withChannel); byte[] result = new byte[dataLen]; int n1 = readAll(in, result, 0, dataLen / 3); @@ -138,56 +135,56 @@ public abstract class AbstractCipherStreamTest { private void doByteBufferRead(String cipherClass, boolean withChannel) throws Exception { // Default buffer size, initial buffer position is 0 - InputStream in = getCipherInputStream(new ByteArrayInputStream(encData), + InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), defaultBufferSize, iv, withChannel); ByteBuffer buf = ByteBuffer.allocate(dataLen + 100); byteBufferReadCheck(in, buf, 0); in.close(); // Default buffer size, initial buffer position is not 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), defaultBufferSize, iv, withChannel); buf.clear(); byteBufferReadCheck(in, buf, 11); in.close(); // Small buffer size, initial buffer position is 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), smallBufferSize, iv, withChannel); buf.clear(); byteBufferReadCheck(in, buf, 0); in.close(); // Small buffer size, initial buffer position is not 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), smallBufferSize, iv, withChannel); buf.clear(); byteBufferReadCheck(in, buf, 11); in.close(); // Direct buffer, default buffer size, initial buffer position is 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), defaultBufferSize, iv, withChannel); buf = ByteBuffer.allocateDirect(dataLen + 100); byteBufferReadCheck(in, buf, 0); in.close(); // Direct buffer, default buffer size, initial buffer position is not 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), defaultBufferSize, iv, withChannel); buf.clear(); byteBufferReadCheck(in, buf, 11); in.close(); // Direct buffer, small buffer size, initial buffer position is 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), smallBufferSize, iv, withChannel); buf.clear(); byteBufferReadCheck(in, buf, 0); in.close(); // Direct buffer, small buffer size, initial buffer position is not 0 - in = getCipherInputStream(new ByteArrayInputStream(encData), + in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), smallBufferSize, iv, withChannel); buf.clear(); byteBufferReadCheck(in, buf, 11); @@ -198,8 +195,8 @@ public abstract class AbstractCipherStreamTest { boolean withChannel) throws Exception { baos.reset(); - CipherOutputStream out = - getCipherOutputStream(baos, getCipher(cipherClass), defaultBufferSize, + CryptoOutputStream out = + getCryptoOutputStream(baos, getCipher(cipherClass), defaultBufferSize, iv, withChannel); ByteBuffer buf = ByteBuffer.allocateDirect(dataLen / 2); buf.put(data, 0, dataLen / 2); @@ -220,7 +217,7 @@ public abstract class AbstractCipherStreamTest { out.flush(); - InputStream in = getCipherInputStream(new ByteArrayInputStream(encData), + InputStream in = getCryptoInputStream(new ByteArrayInputStream(encData), getCipher(cipherClass), defaultBufferSize, iv, withChannel); buf = ByteBuffer.allocate(dataLen + 100); byteBufferReadCheck(in, buf, 0); @@ -242,16 +239,16 @@ public abstract class AbstractCipherStreamTest { } private void prepareData() throws IOException { - Cipher cipher = null; + CryptoCipher cipher = null; try { - cipher = (Cipher)ReflectionUtils.newInstance( + cipher = (CryptoCipher)ReflectionUtils.newInstance( ReflectionUtils.getClassByName(jceCipherClass), props, transformation); } catch (ClassNotFoundException cnfe) { throw new IOException("Illegal crypto cipher!"); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); - OutputStream out = new CipherOutputStream(baos, cipher, defaultBufferSize, + OutputStream out = new CryptoOutputStream(baos, cipher, defaultBufferSize, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); out.write(data); out.flush(); @@ -259,30 +256,30 @@ public abstract class AbstractCipherStreamTest { encData = baos.toByteArray(); } - protected CipherInputStream getCipherInputStream(ByteArrayInputStream bais, - Cipher cipher, + protected CryptoInputStream getCryptoInputStream(ByteArrayInputStream bais, + CryptoCipher cipher, int bufferSize, byte[] iv, boolean withChannel) throws IOException { if (withChannel) { - return new CipherInputStream(Channels.newChannel(bais), cipher, + return new CryptoInputStream(Channels.newChannel(bais), cipher, bufferSize, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } else { - return new CipherInputStream(bais, cipher, bufferSize, + return new CryptoInputStream(bais, cipher, bufferSize, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } } - protected CipherOutputStream getCipherOutputStream(ByteArrayOutputStream baos, - Cipher cipher, + protected CryptoOutputStream getCryptoOutputStream(ByteArrayOutputStream baos, + CryptoCipher cipher, int bufferSize, byte[] iv, boolean withChannel) throws IOException { if (withChannel) { - return new CipherOutputStream(Channels.newChannel(baos), cipher, + return new CryptoOutputStream(Channels.newChannel(baos), cipher, bufferSize, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } else { - return new CipherOutputStream(baos, cipher, bufferSize, + return new CryptoOutputStream(baos, cipher, bufferSize, new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); } } @@ -302,9 +299,9 @@ public abstract class AbstractCipherStreamTest { return total; } - protected Cipher getCipher(String cipherClass) throws IOException { + protected CryptoCipher getCipher(String cipherClass) throws IOException { try { - return (Cipher)ReflectionUtils.newInstance( + return (CryptoCipher)ReflectionUtils.newInstance( ReflectionUtils.getClassByName(cipherClass), props, transformation); } catch (ClassNotFoundException cnfe) { throw new IOException("Illegal crypto cipher!"); @@ -339,7 +336,7 @@ public abstract class AbstractCipherStreamTest { private void doReadWriteTestForInputStream(int count, String encCipherClass, String decCipherClass, byte[] iv) throws IOException { - Cipher encCipher = getCipher(encCipherClass); + CryptoCipher encCipher = getCipher(encCipherClass); LOG.debug("Created a cipher object of type: " + encCipherClass); // Generate data @@ -351,19 +348,19 @@ public abstract class AbstractCipherStreamTest { // Encrypt data ByteArrayOutputStream encryptedData = new ByteArrayOutputStream(); - CipherOutputStream out = - getCipherOutputStream(encryptedData, encCipher, defaultBufferSize, iv, + CryptoOutputStream out = + getCryptoOutputStream(encryptedData, encCipher, defaultBufferSize, iv, false); out.write(originalData, 0, originalData.length); out.flush(); out.close(); LOG.debug("Finished encrypting data"); - Cipher decCipher = getCipher(decCipherClass); + CryptoCipher decCipher = getCipher(decCipherClass); LOG.debug("Created a cipher object of type: " + decCipherClass); // Decrypt data - CipherInputStream in = getCipherInputStream( + CryptoInputStream in = getCryptoInputStream( new ByteArrayInputStream(encryptedData.toByteArray()), decCipher, defaultBufferSize, iv, false); @@ -382,7 +379,7 @@ public abstract class AbstractCipherStreamTest { originalData, decryptedData); // Decrypt data byte-at-a-time - in = getCipherInputStream( + in = getCryptoInputStream( new ByteArrayInputStream(encryptedData.toByteArray()), decCipher, defaultBufferSize, iv, false); @@ -402,7 +399,7 @@ public abstract class AbstractCipherStreamTest { String encCipherClass, String decCipherClass, byte[] iv) throws IOException { - Cipher encCipher = getCipher(encCipherClass); + CryptoCipher encCipher = getCipher(encCipherClass); LOG.debug("Created a cipher object of type: " + encCipherClass); // Generate data @@ -414,19 +411,19 @@ public abstract class AbstractCipherStreamTest { // Encrypt data ByteArrayOutputStream encryptedData = new ByteArrayOutputStream(); - CipherOutputStream out = - getCipherOutputStream(encryptedData, encCipher, defaultBufferSize, iv, + CryptoOutputStream out = + getCryptoOutputStream(encryptedData, encCipher, defaultBufferSize, iv, true); out.write(originalData, 0, originalData.length); out.flush(); out.close(); LOG.debug("Finished encrypting data"); - Cipher decCipher = getCipher(decCipherClass); + CryptoCipher decCipher = getCipher(decCipherClass); LOG.debug("Created a cipher object of type: " + decCipherClass); // Decrypt data - CipherInputStream in = getCipherInputStream( + CryptoInputStream in = getCryptoInputStream( new ByteArrayInputStream(encryptedData.toByteArray()), decCipher, defaultBufferSize, iv, true); @@ -445,7 +442,7 @@ public abstract class AbstractCipherStreamTest { originalData, decryptedData); // Decrypt data byte-at-a-time - in = getCipherInputStream(new ByteArrayInputStream( + in = getCryptoInputStream(new ByteArrayInputStream( encryptedData.toByteArray()),decCipher,defaultBufferSize,iv,true); // Check http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/stream/CTRCipherStreamTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/stream/CTRCipherStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/CTRCipherStreamTest.java deleted file mode 100644 index 6f9b5f1..0000000 --- a/src/test/java/org/apache/commons/crypto/stream/CTRCipherStreamTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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. - */ -package org.apache.commons.crypto.stream; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.channels.Channels; - -import org.apache.commons.crypto.cipher.Cipher; -import org.apache.commons.crypto.cipher.CipherTransformation; - -public class CTRCipherStreamTest extends AbstractCipherStreamTest { - - @Override -public void setUp() throws IOException { - transformation = CipherTransformation - .AES_CTR_NOPADDING; - } - - @Override - protected CTRCipherInputStream getCipherInputStream - (ByteArrayInputStream bais, Cipher cipher, int - bufferSize,byte[] iv, boolean withChannel) - throws IOException { - if (withChannel) { - return new CTRCipherInputStream(Channels.newChannel(bais), cipher, - bufferSize, key, iv); - } else { - return new CTRCipherInputStream(bais, cipher, bufferSize, key, iv); - } - } - - @Override - protected CTRCipherOutputStream getCipherOutputStream(ByteArrayOutputStream baos, Cipher cipher, int - bufferSize, byte[] iv, boolean withChannel) - throws IOException { - if (withChannel) { - return new CTRCipherOutputStream(Channels.newChannel(baos), cipher, bufferSize, key, iv); - } else { - return new CTRCipherOutputStream(baos, cipher, bufferSize, key, iv); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java new file mode 100644 index 0000000..0953196 --- /dev/null +++ b/src/test/java/org/apache/commons/crypto/stream/CTRCryptoStreamTest.java @@ -0,0 +1,59 @@ +/** + * 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. + */ +package org.apache.commons.crypto.stream; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.channels.Channels; + +import org.apache.commons.crypto.cipher.CryptoCipher; +import org.apache.commons.crypto.cipher.CipherTransformation; + +public class CTRCryptoStreamTest extends AbstractCipherStreamTest { + + @Override +public void setUp() throws IOException { + transformation = CipherTransformation + .AES_CTR_NOPADDING; + } + + @Override + protected CTRCryptoInputStream getCryptoInputStream + (ByteArrayInputStream bais, CryptoCipher cipher, int + bufferSize, byte[] iv, boolean withChannel) + throws IOException { + if (withChannel) { + return new CTRCryptoInputStream(Channels.newChannel(bais), cipher, + bufferSize, key, iv); + } else { + return new CTRCryptoInputStream(bais, cipher, bufferSize, key, iv); + } + } + + @Override + protected CTRCryptoOutputStream getCryptoOutputStream(ByteArrayOutputStream baos, CryptoCipher cipher, + int bufferSize, byte[] iv, boolean withChannel) + throws IOException { + if (withChannel) { + return new CTRCryptoOutputStream(Channels.newChannel(baos), cipher, bufferSize, key, iv); + } else { + return new CTRCryptoOutputStream(baos, cipher, bufferSize, key, iv); + } + } +} http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/ea89d802/src/test/java/org/apache/commons/crypto/stream/PositionedCipherInputStreamTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/crypto/stream/PositionedCipherInputStreamTest.java b/src/test/java/org/apache/commons/crypto/stream/PositionedCipherInputStreamTest.java deleted file mode 100644 index 35bbf7a..0000000 --- a/src/test/java/org/apache/commons/crypto/stream/PositionedCipherInputStreamTest.java +++ /dev/null @@ -1,384 +0,0 @@ -/** - * 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. - */ - -package org.apache.commons.crypto.stream; - -import org.apache.commons.crypto.cipher.Cipher; -import org.apache.commons.crypto.cipher.CipherTransformation; -import org.apache.commons.crypto.cipher.JceCipher; -import org.apache.commons.crypto.cipher.OpensslCipher; -import org.apache.commons.crypto.stream.input.Input; -import org.apache.commons.crypto.utils.ReflectionUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Properties; -import java.util.Random; - -public class PositionedCipherInputStreamTest { - - private final int dataLen = 20000; - private byte[] testData = new byte[dataLen]; - private byte[] encData; - private Properties props = new Properties(); - private byte[] key = new byte[16]; - private byte[] iv = new byte[16]; - int bufferSize = 2048; - int bufferSizeLess = bufferSize - 1; - int bufferSizeMore = bufferSize + 1; - int length = 1024; - int lengthLess = length - 1; - int lengthMore = length + 1; - - private final String jceCipherClass = JceCipher.class.getName(); - private final String opensslCipherClass = OpensslCipher.class.getName(); - private CipherTransformation transformation = - CipherTransformation.AES_CTR_NOPADDING; - - @Before - public void before() throws IOException { - Random random = new SecureRandom(); - random.nextBytes(testData); - random.nextBytes(key); - random.nextBytes(iv); - prepareData(); - } - - private void prepareData() throws IOException { - Cipher cipher = null; - try { - cipher = (Cipher)ReflectionUtils.newInstance( - ReflectionUtils.getClassByName(jceCipherClass), - props, transformation); - } catch (ClassNotFoundException cnfe) { - throw new IOException("Illegal crypto cipher!"); - } - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - // encryption data - OutputStream out = new CipherOutputStream(baos, cipher, bufferSize, - new SecretKeySpec(key,"AES"), new IvParameterSpec(iv)); - out.write(testData); - out.flush(); - out.close(); - encData = baos.toByteArray(); - } - - public void setUp() throws IOException {} - - private PositionedCipherInputStream getCipherInputStream(Cipher cipher, - int bufferSize) throws IOException { - return new PositionedCipherInputStream(new PositionedInputForTest( - Arrays.copyOf(encData, encData.length)), cipher, bufferSize, key, iv, 0); - } - - @Test - public void doTest() throws Exception { - testCipher(jceCipherClass); - testCipher(opensslCipherClass); - } - - private void testCipher(String cipherClass) throws Exception { - doPositionedReadTests(cipherClass); - doReadFullyTests(cipherClass); - doSeekTests(cipherClass); - doMultipleReadTest(cipherClass); - } - - // when there are multiple positioned read actions and one read action, - // they will not interfere each other. - private void doMultipleReadTest(String cipherClass) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - int position = 0; - while (in.available() > 0) { - ByteBuffer buf = ByteBuffer.allocate(length); - byte[] bytes1 = new byte[length]; - byte[] bytes2 = new byte[lengthLess]; - // do the read and position read - int pn1 = in.read(position, bytes1, 0, length); - int n = in.read(buf); - int pn2 = in.read(position, bytes2, 0, lengthLess); - - // verify the result - if (pn1 > 0) { - compareByteArray(testData, position, bytes1, pn1); - } - - if (pn2 > 0) { - compareByteArray(testData, position, bytes2, pn2); - } - - if (n > 0) { - compareByteArray(testData, position, buf.array(), n); - position += n; - } else { - break; - } - } - in.close(); - } - - private void doPositionedReadTests(String cipherClass) throws Exception { - // test with different bufferSize when position = 0 - testPositionedReadLoop(cipherClass, 0, length, bufferSize, dataLen); - testPositionedReadLoop(cipherClass, 0, length, bufferSizeLess, dataLen); - testPositionedReadLoop(cipherClass, 0, length, bufferSizeMore, dataLen); - // test with different position when bufferSize = 2048 - testPositionedReadLoop(cipherClass, dataLen / 2, length, bufferSize, dataLen); - testPositionedReadLoop(cipherClass, dataLen / 2 - 1, length, - bufferSizeLess, dataLen); - testPositionedReadLoop(cipherClass, dataLen / 2 + 1, length, - bufferSizeMore, dataLen); - // position = -1 or position = max length, read nothing and return -1 - testPositionedReadNone(cipherClass, -1, length, bufferSize); - testPositionedReadNone(cipherClass, dataLen, length, bufferSize); - } - - private void doReadFullyTests(String cipherClass) throws Exception { - // test with different bufferSize when position = 0 - testReadFullyLoop(cipherClass, 0, length, bufferSize, dataLen); - testReadFullyLoop(cipherClass, 0, length, bufferSizeLess, dataLen); - testReadFullyLoop(cipherClass, 0, length, bufferSizeMore, dataLen); - // test with different length when position = 0 - testReadFullyLoop(cipherClass, 0, length, bufferSize, dataLen); - testReadFullyLoop(cipherClass, 0, lengthLess, bufferSize, dataLen); - testReadFullyLoop(cipherClass, 0, lengthMore, bufferSize, dataLen); - // test read fully failed - testReadFullyFailed(cipherClass, -1, length, bufferSize); - testReadFullyFailed(cipherClass, dataLen, length, bufferSize); - testReadFullyFailed(cipherClass, dataLen - length + 1, length, bufferSize); - } - - private void doSeekTests(String cipherClass) throws Exception { - // test with different length when position = 0 - testSeekLoop(cipherClass, 0, length, bufferSize); - testSeekLoop(cipherClass, 0, lengthLess, bufferSize); - testSeekLoop(cipherClass, 0, lengthMore, bufferSize); - // there should be none data read when position = dataLen - testSeekLoop(cipherClass, dataLen, length, bufferSize); - // test exception when position = -1 - testSeekFailed(cipherClass, -1, bufferSize); - } - - private void testSeekLoop(String cipherClass, int position, int length, - int bufferSize) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - while (in.available() > 0) { - in.seek(position); - ByteBuffer buf = ByteBuffer.allocate(length); - int n = in.read(buf); - if (n > 0) { - compareByteArray(testData, position, buf.array(), n); - position += n; - } else { - break; - } - } - in.close(); - } - - // test for the out of index position, eg, -1. - private void testSeekFailed(String cipherClass, int position, - int bufferSize) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - try { - in.seek(position); - Assert.fail("Excepted exception for cannot seek to negative offset."); - } catch (IllegalArgumentException iae) { - } - in.close(); - } - - private void testPositionedReadLoop(String cipherClass, int position, - int length, int bufferSize, int total) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - // do the position read until the end of data - while (position < total) { - byte[] bytes = new byte[length]; - int n = in.read(position, bytes, 0, length); - if (n >= 0) { - compareByteArray(testData, position, bytes, n); - position += n; - } else { - break; - } - } - in.close(); - } - - // test for the out of index position, eg, -1. - private void testPositionedReadNone(String cipherClass, int position, - int length, int bufferSize) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - byte[] bytes = new byte[length]; - int n = in.read(position, bytes, 0, length); - Assert.assertEquals(n, -1); - in.close(); - } - - private void testReadFullyLoop(String cipherClass,int position, - int length, int bufferSize, int total) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - - // do the position read full until remain < length - while (position + length <= total) { - byte[] bytes = new byte[length]; - in.readFully(position, bytes, 0, length); - compareByteArray(testData, position, bytes, length); - position += length; - } - - in.close(); - } - - // test for the End of file reached before reading fully - private void testReadFullyFailed(String cipherClass, int position, - int length, int bufferSize) throws Exception { - PositionedCipherInputStream in = getCipherInputStream( - getCipher(cipherClass), bufferSize); - byte[] bytes = new byte[length]; - try { - in.readFully(position, bytes, 0, length); - Assert.fail("Excepted EOFException."); - } catch (IOException ioe) { - // excepted exception - } - in.close(); - } - - // compare the data from pos with length and data2 from 0 with length - private void compareByteArray(byte[] data1, int pos, byte[] data2, int length) { - byte[] expectedData = new byte[length]; - byte[] realData = new byte[length]; - // get the expected data with the position and length - System.arraycopy(data1, pos, expectedData, 0, length); - // get the real data - System.arraycopy(data2, 0, realData, 0, length); - Assert.assertArrayEquals(expectedData, realData); - } - - private Cipher getCipher(String cipherClass) throws IOException { - try { - return (Cipher)ReflectionUtils.newInstance( - ReflectionUtils.getClassByName(cipherClass), props, transformation); - } catch (ClassNotFoundException cnfe) { - throw new IOException("Illegal crypto cipher!"); - } - } - - class PositionedInputForTest implements Input { - - byte[] data; - long pos; - long count; - - public PositionedInputForTest(byte[] data) { - this.data = data; - this.pos = 0; - this.count = data.length; - } - - @Override - public int read(ByteBuffer dst) throws IOException { - int remaining = (int)(count - pos); - if(remaining <= 0) { - return -1; - } - - int length = Math.min(dst.remaining(), remaining); - dst.put(data, (int)pos, length); - pos += length; - return length; - } - - @Override - public long skip(long n) throws IOException { - if (n <= 0) { - return 0; - } - - long remaining = count - pos; - if(remaining < n) { - n = remaining; - } - pos += n; - - return n; - } - - @Override - public int read(long position, byte[] buffer, int offset, int length) - throws IOException { - if (buffer == null) { - throw new NullPointerException(); - } else if (offset < 0 || length < 0 || length > buffer.length - offset) { - throw new IndexOutOfBoundsException(); - } - - if (position < 0 || position >= count) { - return -1; - } - - long avail = count - position; - if (length > avail) { - length = (int)avail; - } - if (length <= 0) { - return 0; - } - System.arraycopy(data, (int)position, buffer, offset, length); - return length; - } - - @Override - public void seek(long position) throws IOException { - if (pos < 0) { - throw new IOException("Negative seek offset"); - } else if (position >= 0 && position < count) { - pos = position; - } else { - // to the end of file - pos = count; - } - } - - @Override - public void close() throws IOException { - } - - @Override - public int available() throws IOException { - return (int)(count - pos); - } - } -}