JNI: add synchronization around native ecc_key/RsaKey/DhKey pointer access in Ecc/Rsa/Dh class

pull/53/head
Chris Conlon 2023-08-04 16:45:38 -06:00
parent 8606e9e14e
commit f6ffb7489e
10 changed files with 1313 additions and 273 deletions

View File

@ -11,10 +11,10 @@ extern "C" {
#define com_wolfssl_wolfcrypt_Dh_NULL 0LL #define com_wolfssl_wolfcrypt_Dh_NULL 0LL
/* /*
* Class: com_wolfssl_wolfcrypt_Dh * Class: com_wolfssl_wolfcrypt_Dh
* Method: mallocNativeStruct * Method: mallocNativeStruct_internal
* Signature: ()J * Signature: ()J
*/ */
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct_1internal
(JNIEnv *, jobject); (JNIEnv *, jobject);
/* /*

View File

@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdint.h>
#ifdef WOLFSSL_USER_SETTINGS #ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h> #include <wolfssl/wolfcrypt/settings.h>
#elif !defined(__ANDROID__) #elif !defined(__ANDROID__)
@ -37,23 +39,29 @@
#define RNG WC_RNG #define RNG WC_RNG
#endif #endif
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct( JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct_1internal(
JNIEnv* env, jobject this) JNIEnv* env, jobject this)
{ {
jlong ret = 0;
#ifndef NO_DH #ifndef NO_DH
ret = (jlong) XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); DhKey* dh = NULL;
if (!ret) dh = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (dh == NULL) {
throwOutOfMemoryException(env, "Failed to allocate Dh object"); throwOutOfMemoryException(env, "Failed to allocate Dh object");
}
else {
XMEMSET(dh, 0, sizeof(DhKey));
}
LogStr("new Dh() = %p\n", (void*)ret); LogStr("new Dh() = %p\n", dh);
return (jlong)(uintptr_t)dh;
#else #else
throwNotCompiledInException(env); throwNotCompiledInException(env);
#endif
return ret; return (jlong)0;
#endif
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
@ -61,13 +69,17 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1InitDhKey(
JNIEnv* env, jobject this) JNIEnv* env, jobject this)
{ {
#ifndef NO_DH #ifndef NO_DH
int ret = 0;
DhKey* key = (DhKey*) getNativeStruct(env, this); DhKey* key = (DhKey*) getNativeStruct(env, this);
if ((*env)->ExceptionOccurred(env)) { if ((*env)->ExceptionOccurred(env)) {
/* getNativeStruct may throw exception */ /* getNativeStruct may throw exception */
return; return;
} }
wc_InitDhKey(key); ret = wc_InitDhKey(key);
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_InitDhKey(key=%p)\n", key); LogStr("wc_InitDhKey(key=%p)\n", key);
#else #else
@ -80,13 +92,17 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1FreeDhKey(
JNIEnv* env, jobject this) JNIEnv* env, jobject this)
{ {
#ifndef NO_DH #ifndef NO_DH
int ret = 0;
DhKey* key = (DhKey*) getNativeStruct(env, this); DhKey* key = (DhKey*) getNativeStruct(env, this);
if ((*env)->ExceptionOccurred(env)) { if ((*env)->ExceptionOccurred(env)) {
/* getNativeStruct may throw exception */ /* getNativeStruct may throw exception */
return; return;
} }
wc_FreeDhKey(key); ret = wc_FreeDhKey(key);
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_FreeDhKey(key=%p)\n", key); LogStr("wc_FreeDhKey(key=%p)\n", key);
#else #else
@ -116,12 +132,16 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhSetKey(
g = getByteArray(env, g_object); g = getByteArray(env, g_object);
gSz = getByteArrayLength(env, g_object); gSz = getByteArrayLength(env, g_object);
ret = (!key || !p || !g) if (key == NULL || p == NULL || g == NULL) {
? BAD_FUNC_ARG ret = BAD_FUNC_ARG;
: wc_DhSetKey(key, p, pSz, g, gSz); }
else {
ret = wc_DhSetKey(key, p, pSz, g, gSz);
}
if (ret != 0) if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret); throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_DhSetKey(key=%p, p, pSz, g, gSz) = %d\n", key, ret); LogStr("wc_DhSetKey(key=%p, p, pSz, g, gSz) = %d\n", key, ret);
LogStr("p[%u]: [%p]\n", (word32)pSz, p); LogStr("p[%u]: [%p]\n", (word32)pSz, p);
@ -164,26 +184,29 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
return; return;
} }
if (!key || !rng || (size < 0)) if (key == NULL || rng == NULL || (size < 0)) {
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
}
if (ret == 0) { if (ret == 0) {
priv = XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); priv = XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (priv == NULL) { if (priv == NULL) {
throwOutOfMemoryException(env, throwOutOfMemoryException(env,
"Failed to allocate private key buffer"); "Failed to allocate private key buffer");
return; return;
} }
XMEMSET(priv, 0, privSz);
pub = XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); pub = XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (pub == NULL) { if (pub == NULL) {
XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
throwOutOfMemoryException(env, throwOutOfMemoryException(env,
"Failed to allocate public key buffer"); "Failed to allocate public key buffer");
return; return;
} }
XMEMSET(pub, 0, pubSz);
ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz);
} }
@ -191,11 +214,13 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
if (ret == 0) { if (ret == 0) {
/* keys should be positive, if leading bit is set, add zero byte */ /* keys should be positive, if leading bit is set, add zero byte */
if (priv[0] & 0x80) if (priv[0] & 0x80) {
lBitPriv = 1; lBitPriv = 1;
}
if (pub[0] & 0x80) if (pub[0] & 0x80) {
lBitPub = 1; lBitPub = 1;
}
jbyteArray privateKey = (*env)->NewByteArray(env, lBitPriv + privSz); jbyteArray privateKey = (*env)->NewByteArray(env, lBitPriv + privSz);
jbyteArray publicKey = (*env)->NewByteArray(env, lBitPub + pubSz); jbyteArray publicKey = (*env)->NewByteArray(env, lBitPub + pubSz);
@ -219,6 +244,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
} else { } else {
throwWolfCryptException(env, "Failed to allocate privateKey"); throwWolfCryptException(env, "Failed to allocate privateKey");
exceptionThrown = 1;
} }
if (publicKey && (exceptionThrown == 0)) { if (publicKey && (exceptionThrown == 0)) {
@ -247,10 +273,14 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
LogStr("public[%u]: [%p]\n", pubSz, pub); LogStr("public[%u]: [%p]\n", pubSz, pub);
LogHex(pub, 0, pubSz); LogHex(pub, 0, pubSz);
if (priv) if (priv != NULL) {
XMEMSET(priv, 0, privSz);
XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (pub) }
if (pub != NULL) {
XMEMSET(pub, 0, pubSz);
XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
#else #else
throwNotCompiledInException(env); throwNotCompiledInException(env);
#endif #endif
@ -275,12 +305,16 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhCheckPubKey(
pub = getByteArray(env, pub_object); pub = getByteArray(env, pub_object);
pubSz = getByteArrayLength(env, pub_object); pubSz = getByteArrayLength(env, pub_object);
ret = (!key || !pub) if (key == NULL || pub == NULL) {
? BAD_FUNC_ARG ret = BAD_FUNC_ARG;
: wc_DhCheckPubKey(key, pub, pubSz); }
else {
ret = wc_DhCheckPubKey(key, pub, pubSz);
}
if (ret != 0) if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret); throwWolfCryptExceptionFromError(env, ret);
}
LogStr("wc_DhCheckPubKey(key=%p, pub, pubSz) = %d\n", key, ret); LogStr("wc_DhCheckPubKey(key=%p, pub, pubSz) = %d\n", key, ret);
LogStr("p[%u]: [%p]\n", (word32)pubSz, pub); LogStr("p[%u]: [%p]\n", (word32)pubSz, pub);
@ -327,10 +361,14 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
return result; return result;
} }
XMEMSET(secret, 0, pubSz);
ret = (!key || !priv || !pub) if (key == NULL || priv == NULL || pub == NULL) {
? BAD_FUNC_ARG ret = BAD_FUNC_ARG;
: wc_DhAgree(key, secret, &secretSz, priv, privSz, pub, pubSz); }
else {
ret = wc_DhAgree(key, secret, &secretSz, priv, privSz, pub, pubSz);
}
if (ret == 0) { if (ret == 0) {
result = (*env)->NewByteArray(env, secretSz); result = (*env)->NewByteArray(env, secretSz);
@ -350,7 +388,10 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
LogStr("secret[%u]: [%p]\n", secretSz, secret); LogStr("secret[%u]: [%p]\n", secretSz, secret);
LogHex(secret, 0, secretSz); LogHex(secret, 0, secretSz);
XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (secret != NULL) {
XMEMSET(secret, 0, secretSz);
XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
releaseByteArray(env, priv_object, priv, JNI_ABORT); releaseByteArray(env, priv_object, priv, JNI_ABORT);
releaseByteArray(env, pub_object, pub, JNI_ABORT); releaseByteArray(env, pub_object, pub, JNI_ABORT);
@ -360,3 +401,4 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
return result; return result;
} }

View File

@ -31,6 +31,9 @@ public class Dh extends NativeStruct {
private byte[] publicKey = null; private byte[] publicKey = null;
private int pSize = 0; private int pSize = 0;
/* Lock around object state */
protected final Object stateLock = new Object();
/** /**
* Create new Dh object * Create new Dh object
*/ */
@ -50,12 +53,19 @@ public class Dh extends NativeStruct {
} }
@Override @Override
public void releaseNativeStruct() { public synchronized void releaseNativeStruct() {
free(); free();
super.releaseNativeStruct(); super.releaseNativeStruct();
} }
private native long mallocNativeStruct_internal() throws OutOfMemoryError;
private native void wc_InitDhKey();
private native void wc_FreeDhKey();
private native void wc_DhSetKey(byte[] p, byte[] g);
private native void wc_DhGenerateKeyPair(Rng rng, int pSize);
private native byte[] wc_DhAgree(byte[] priv, byte[] pub);
/** /**
* Malloc native JNI DH structure * Malloc native JNI DH structure
* *
@ -63,34 +73,46 @@ public class Dh extends NativeStruct {
* *
* @throws OutOfMemoryError when malloc fails with memory error * @throws OutOfMemoryError when malloc fails with memory error
*/ */
protected native long mallocNativeStruct() throws OutOfMemoryError; protected long mallocNativeStruct()
throws OutOfMemoryError {
synchronized (pointerLock) {
return mallocNativeStruct_internal();
}
}
private native void wc_InitDhKey();
private native void wc_FreeDhKey();
private native void wc_DhSetKey(byte[] p, byte[] g);
private native void wc_DhGenerateKeyPair(Rng rng, int pSize);
private native byte[] wc_DhAgree(byte[] priv, byte[] pub);
/** Initialize Dh object */ /** Initialize Dh object */
protected void init() { protected void init() {
if (state == WolfCryptState.UNINITIALIZED) {
wc_InitDhKey(); synchronized (stateLock) {
state = WolfCryptState.INITIALIZED; if (state == WolfCryptState.UNINITIALIZED) {
} else {
throw new IllegalStateException( synchronized (pointerLock) {
"Native resources already initialized."); wc_InitDhKey();
}
state = WolfCryptState.INITIALIZED;
} else {
throw new IllegalStateException(
"Native resources already initialized");
}
} }
} }
/** Free Dh object */ /** Free Dh object */
protected void free() { protected synchronized void free() {
if (state != WolfCryptState.UNINITIALIZED) {
wc_FreeDhKey();
setPrivateKey(new byte[0]); synchronized (stateLock) {
setPublicKey(new byte[0]); if (state != WolfCryptState.UNINITIALIZED) {
state = WolfCryptState.UNINITIALIZED; synchronized (pointerLock) {
wc_FreeDhKey();
}
setPrivateKey(new byte[0]);
setPublicKey(new byte[0]);
state = WolfCryptState.UNINITIALIZED;
}
} }
} }
@ -101,16 +123,22 @@ public class Dh extends NativeStruct {
* *
* @throws IllegalStateException if object uninitialized * @throws IllegalStateException if object uninitialized
*/ */
public void setPrivateKey(byte[] priv) { public synchronized void setPrivateKey(byte[] priv)
if (state != WolfCryptState.UNINITIALIZED) { throws IllegalStateException {
if (privateKey != null)
for (int i = 0; i < privateKey.length; i++)
privateKey[i] = 0;
privateKey = priv.clone(); synchronized (stateLock) {
} else { if (state != WolfCryptState.UNINITIALIZED) {
throw new IllegalStateException( if (privateKey != null) {
"No available parameters to perform opetarion."); for (int i = 0; i < privateKey.length; i++) {
privateKey[i] = 0;
}
}
privateKey = priv.clone();
} else {
throw new IllegalStateException(
"No available parameters to perform operation");
}
} }
} }
@ -121,16 +149,21 @@ public class Dh extends NativeStruct {
* *
* @throws IllegalStateException if object uninitialized * @throws IllegalStateException if object uninitialized
*/ */
public void setPublicKey(byte[] pub) { public synchronized void setPublicKey(byte[] pub) {
if (state != WolfCryptState.UNINITIALIZED) {
if (publicKey != null)
for (int i = 0; i < publicKey.length; i++)
publicKey[i] = 0;
publicKey = pub.clone(); synchronized (stateLock) {
} else { if (state != WolfCryptState.UNINITIALIZED) {
throw new IllegalStateException( if (publicKey != null) {
"No available parameters to perform opetarion."); for (int i = 0; i < publicKey.length; i++) {
publicKey[i] = 0;
}
}
publicKey = pub.clone();
} else {
throw new IllegalStateException(
"No available parameters to perform operation");
}
} }
} }
@ -139,7 +172,7 @@ public class Dh extends NativeStruct {
* *
* @return public key as byte array * @return public key as byte array
*/ */
public byte[] getPublicKey() { public synchronized byte[] getPublicKey() {
return publicKey; return publicKey;
} }
@ -148,7 +181,7 @@ public class Dh extends NativeStruct {
* *
* @return private key as byte array * @return private key as byte array
*/ */
public byte[] getPrivateKey() { public synchronized byte[] getPrivateKey() {
return privateKey; return privateKey;
} }
@ -161,13 +194,21 @@ public class Dh extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already initialized * @throws IllegalStateException if object already initialized
*/ */
public void setParams(byte[] p, byte[] g) { public synchronized void setParams(byte[] p, byte[] g)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_DhSetKey(p, g);
this.pSize = p.length; synchronized (stateLock) {
state = WolfCryptState.READY; if (state == WolfCryptState.INITIALIZED) {
} else {
throw new IllegalStateException("Object already has parameters."); synchronized (pointerLock) {
wc_DhSetKey(p, g);
}
this.pSize = p.length;
state = WolfCryptState.READY;
} else {
throw new IllegalStateException(
"Object already has parameters");
}
} }
} }
@ -179,12 +220,16 @@ public class Dh extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void makeKey(Rng rng) { public synchronized void makeKey(Rng rng)
throws WolfCryptException, IllegalStateException {
if (privateKey == null) { if (privateKey == null) {
/* use size of P to allocate key buffer size */ /* use size of P to allocate key buffer size */
wc_DhGenerateKeyPair(rng, this.pSize); synchronized (pointerLock) {
wc_DhGenerateKeyPair(rng, this.pSize);
}
} else { } else {
throw new IllegalStateException("Object already has a key."); throw new IllegalStateException("Object already has a key");
} }
} }
@ -198,14 +243,18 @@ public class Dh extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] makeSharedSecret(Dh pubKey) { public synchronized byte[] makeSharedSecret(Dh pubKey)
throws WolfCryptException, IllegalStateException {
byte[] publicKey = pubKey.getPublicKey(); byte[] publicKey = pubKey.getPublicKey();
if (privateKey != null || publicKey != null) { if (privateKey != null || publicKey != null) {
return wc_DhAgree(privateKey, publicKey); synchronized (pointerLock) {
return wc_DhAgree(privateKey, publicKey);
}
} else { } else {
throw new IllegalStateException( throw new IllegalStateException(
"No available key to perform the opperation."); "No available key to perform the operation");
} }
} }
} }

View File

@ -38,6 +38,9 @@ public class Ecc extends NativeStruct {
/* used with native wc_ecc_set_rng() */ /* used with native wc_ecc_set_rng() */
private Rng rng = null; private Rng rng = null;
/* Lock around object state */
protected final Object stateLock = new Object();
/** /**
* Create new Ecc object * Create new Ecc object
*/ */
@ -46,7 +49,7 @@ public class Ecc extends NativeStruct {
} }
@Override @Override
public void releaseNativeStruct() { public synchronized void releaseNativeStruct() {
free(); free();
super.releaseNativeStruct(); super.releaseNativeStruct();
@ -89,19 +92,24 @@ public class Ecc extends NativeStruct {
* Initialize Ecc object * Initialize Ecc object
*/ */
protected void init() { protected void init() {
if (state == WolfCryptState.UNINITIALIZED) { synchronized (stateLock) {
wc_ecc_init(); if (state == WolfCryptState.UNINITIALIZED) {
/* used with native wc_ecc_set_rng() */ synchronized (pointerLock) {
if (rng == null) { wc_ecc_init();
rng = new Rng(); }
rng.init();
/* used with native wc_ecc_set_rng() */
if (rng == null) {
rng = new Rng();
rng.init();
}
state = WolfCryptState.INITIALIZED;
} else {
throw new IllegalStateException(
"Native resources already initialized.");
} }
state = WolfCryptState.INITIALIZED;
} else {
throw new IllegalStateException(
"Native resources already initialized.");
} }
} }
@ -109,15 +117,20 @@ public class Ecc extends NativeStruct {
* Free Ecc object * Free Ecc object
*/ */
protected void free() { protected void free() {
if (state != WolfCryptState.UNINITIALIZED) { synchronized (stateLock) {
wc_ecc_free(); if (state != WolfCryptState.UNINITIALIZED) {
if (this.rng != null) { synchronized (pointerLock) {
rng.free(); wc_ecc_free();
rng.releaseNativeStruct(); }
if (this.rng != null) {
rng.free();
rng.releaseNativeStruct();
}
state = WolfCryptState.UNINITIALIZED;
} }
state = WolfCryptState.UNINITIALIZED;
} }
} }
@ -130,12 +143,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void makeKey(Rng rng, int size) { public synchronized void makeKey(Rng rng, int size)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_ecc_make_key(rng, size);
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_ecc_make_key(rng, size);
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -149,12 +169,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void makeKeyOnCurve(Rng rng, int size, String curveName) { public synchronized void makeKeyOnCurve(Rng rng, int size, String curveName)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_ecc_make_key_ex(rng, size, curveName.toUpperCase());
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_ecc_make_key_ex(rng, size, curveName.toUpperCase());
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -165,12 +192,19 @@ public class Ecc extends NativeStruct {
* incorrect or invalid * incorrect or invalid
* @throws IllegalStateException if object does not have a key * @throws IllegalStateException if object does not have a key
*/ */
public void checkKey() { public synchronized void checkKey()
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
wc_ecc_check_key();
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
wc_ecc_check_key();
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -183,12 +217,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void importPrivate(byte[] privKey, byte[] x963Key) { public synchronized void importPrivate(byte[] privKey, byte[] x963Key)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_ecc_import_private(privKey, x963Key, null);
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_ecc_import_private(privKey, x963Key, null);
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -202,13 +243,20 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void importPrivateOnCurve(byte[] privKey, byte[] x963Key, public synchronized void importPrivateOnCurve(byte[] privKey,
String curveName) { byte[] x963Key, String curveName)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_ecc_import_private(privKey, x963Key, curveName);
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_ecc_import_private(privKey, x963Key, curveName);
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -220,12 +268,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] exportPrivate() { public synchronized byte[] exportPrivate()
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
return wc_ecc_export_private();
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
return wc_ecc_export_private();
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -237,12 +292,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void importX963(byte[] key) { public synchronized void importX963(byte[] key)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_ecc_import_x963(key);
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_ecc_import_x963(key);
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -254,12 +316,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] exportX963() { public synchronized byte[] exportX963()
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
return wc_ecc_export_x963();
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
return wc_ecc_export_x963();
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -271,12 +340,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void privateKeyDecode(byte[] key) { public synchronized void privateKeyDecode(byte[] key)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_EccPrivateKeyDecode(key);
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_EccPrivateKeyDecode(key);
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -288,12 +364,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] privateKeyEncode() { public synchronized byte[] privateKeyEncode()
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
return wc_EccKeyToDer();
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
return wc_EccKeyToDer();
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -305,12 +388,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object already has a key * @throws IllegalStateException if object already has a key
*/ */
public void publicKeyDecode(byte[] key) { public synchronized void publicKeyDecode(byte[] key)
if (state == WolfCryptState.INITIALIZED) { throws WolfCryptException, IllegalStateException {
wc_EccPublicKeyDecode(key);
state = WolfCryptState.READY; synchronized (stateLock) {
} else { if (state == WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key.");
synchronized (pointerLock) {
wc_EccPublicKeyDecode(key);
}
state = WolfCryptState.READY;
} else {
throw new IllegalStateException("Object already has a key.");
}
} }
} }
@ -322,12 +412,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] publicKeyEncode() { public synchronized byte[] publicKeyEncode()
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
return wc_EccPublicKeyToDer();
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
return wc_EccPublicKeyToDer();
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -341,12 +438,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] makeSharedSecret(Ecc pubKey) { public synchronized byte[] makeSharedSecret(Ecc pubKey)
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
return wc_ecc_shared_secret(pubKey, this.rng);
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
return wc_ecc_shared_secret(pubKey, this.rng);
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -361,14 +465,20 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] sign(byte[] hash, Rng rng) { public synchronized byte[] sign(byte[] hash, Rng rng)
throws WolfCryptException, IllegalStateException {
byte[] signature = new byte[0]; byte[] signature = new byte[0];
if (state == WolfCryptState.READY) { synchronized (stateLock) {
signature = wc_ecc_sign_hash(hash, rng); if (state == WolfCryptState.READY) {
} else { synchronized (pointerLock) {
throw new IllegalStateException( signature = wc_ecc_sign_hash(hash, rng);
"No available key to perform the operation."); }
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
return signature; return signature;
@ -385,14 +495,21 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public boolean verify(byte[] hash, byte[] signature) { public synchronized boolean verify(byte[] hash, byte[] signature)
throws WolfCryptException, IllegalStateException {
boolean result = false; boolean result = false;
if (state == WolfCryptState.READY) { synchronized (stateLock) {
result = wc_ecc_verify_hash(hash, signature); if (state == WolfCryptState.READY) {
} else {
throw new IllegalStateException( synchronized (pointerLock) {
"No available key to perform the operation."); result = wc_ecc_verify_hash(hash, signature);
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
return result; return result;
@ -408,9 +525,10 @@ public class Ecc extends NativeStruct {
* @return size of ECC curve * @return size of ECC curve
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key
*/ */
public static int getCurveSizeFromName(String curveName) { public static int getCurveSizeFromName(String curveName)
throws WolfCryptException {
/* Ecc object doesn't need to be initialied before call */ /* Ecc object doesn't need to be initialied before call */
return wc_ecc_get_curve_size_from_name(curveName); return wc_ecc_get_curve_size_from_name(curveName);
} }
@ -423,12 +541,19 @@ public class Ecc extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object has no key * @throws IllegalStateException if object has no key
*/ */
public byte[] privateKeyEncodePKCS8() { public synchronized byte[] privateKeyEncodePKCS8()
if (state == WolfCryptState.READY) { throws WolfCryptException, IllegalStateException {
return wc_ecc_private_key_to_pkcs8();
} else { synchronized (stateLock) {
throw new IllegalStateException( if (state == WolfCryptState.READY) {
"No available key to perform the operation.");
synchronized (pointerLock) {
return wc_ecc_private_key_to_pkcs8();
}
} else {
throw new IllegalStateException(
"No available key to perform the operation.");
}
} }
} }
@ -444,8 +569,8 @@ public class Ecc extends NativeStruct {
* is not an instance of ECFieldFp * is not an instance of ECFieldFp
*/ */
public static String getCurveName(ECParameterSpec spec) public static String getCurveName(ECParameterSpec spec)
throws InvalidAlgorithmParameterException throws WolfCryptException, InvalidAlgorithmParameterException {
{
int curve_id; int curve_id;
/* Ecc object doesn't need to be initialied before call */ /* Ecc object doesn't need to be initialied before call */

View File

@ -32,6 +32,9 @@ public class Rsa extends NativeStruct {
private boolean hasPrivateKey = false; private boolean hasPrivateKey = false;
private Rng rng; private Rng rng;
/* Lock around object state */
protected final Object stateLock = new Object();
/** /**
* Malloc native JNI Rsa structure * Malloc native JNI Rsa structure
* *
@ -135,15 +138,18 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public void setRng(Rng rng) throws WolfCryptException { public synchronized void setRng(Rng rng) throws WolfCryptException {
init(); init();
if (wc_RsaSetRNG(rng)) synchronized (pointerLock) {
this.rng = rng; if (wc_RsaSetRNG(rng)) {
this.rng = rng;
}
}
} }
@Override @Override
public void releaseNativeStruct() { public synchronized void releaseNativeStruct() {
free(); free();
super.releaseNativeStruct(); super.releaseNativeStruct();
@ -155,9 +161,15 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
protected void init() throws WolfCryptException { protected void init() throws WolfCryptException {
if (state == WolfCryptState.UNINITIALIZED) {
wc_InitRsaKey(); synchronized (stateLock) {
state = WolfCryptState.INITIALIZED; if (state == WolfCryptState.UNINITIALIZED) {
synchronized (pointerLock) {
wc_InitRsaKey();
}
state = WolfCryptState.INITIALIZED;
}
} }
} }
@ -172,8 +184,11 @@ public class Rsa extends NativeStruct {
init(); init();
if (state != WolfCryptState.INITIALIZED) synchronized (stateLock) {
throw new IllegalStateException("Object already has a key."); if (state != WolfCryptState.INITIALIZED) {
throw new IllegalStateException("Object already has a key");
}
}
} }
/** /**
@ -185,13 +200,18 @@ public class Rsa extends NativeStruct {
* @throws IllegalStateException if object has no public key * @throws IllegalStateException if object has no public key
*/ */
protected void willUseKey(boolean priv) throws IllegalStateException { protected void willUseKey(boolean priv) throws IllegalStateException {
if (priv && !hasPrivateKey)
throw new IllegalStateException(
"No available private key to perform the operation.");
if (state != WolfCryptState.READY) if (priv && !hasPrivateKey) {
throw new IllegalStateException( throw new IllegalStateException(
"No available key to perform the operation."); "No available private key to perform the operation");
}
synchronized (stateLock) {
if (state != WolfCryptState.READY) {
throw new IllegalStateException(
"No available key to perform the operation");
}
}
} }
/** /**
@ -200,9 +220,15 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
protected void free() throws WolfCryptException { protected void free() throws WolfCryptException {
if (state != WolfCryptState.UNINITIALIZED) {
wc_FreeRsaKey(); synchronized (stateLock) {
state = WolfCryptState.UNINITIALIZED; if (state != WolfCryptState.UNINITIALIZED) {
synchronized (pointerLock) {
wc_FreeRsaKey();
}
state = WolfCryptState.UNINITIALIZED;
}
} }
} }
@ -216,14 +242,19 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void makeKey(int size, long e, Rng rng) public synchronized void makeKey(int size, long e, Rng rng)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
willSetKey(); willSetKey();
MakeRsaKey(size, e, rng); synchronized (stateLock) {
synchronized (pointerLock) {
MakeRsaKey(size, e, rng);
}
state = WolfCryptState.READY; state = WolfCryptState.READY;
hasPrivateKey = true; hasPrivateKey = true;
}
} }
/** /**
@ -234,12 +265,17 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodePublicKey(byte[] key) public synchronized void decodePublicKey(byte[] key)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
willSetKey(); willSetKey();
wc_RsaPublicKeyDecode(key); synchronized (stateLock) {
state = WolfCryptState.READY; synchronized (pointerLock) {
wc_RsaPublicKeyDecode(key);
}
state = WolfCryptState.READY;
}
} }
/** /**
@ -250,13 +286,18 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodePrivateKey(byte[] key) public synchronized void decodePrivateKey(byte[] key)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
willSetKey(); willSetKey();
wc_RsaPrivateKeyDecode(key); synchronized (stateLock) {
state = WolfCryptState.READY; synchronized (pointerLock) {
hasPrivateKey = true; wc_RsaPrivateKeyDecode(key);
}
state = WolfCryptState.READY;
hasPrivateKey = true;
}
} }
/** /**
@ -267,14 +308,19 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodePrivateKeyPKCS8(byte[] key) public synchronized void decodePrivateKeyPKCS8(byte[] key)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
willSetKey(); willSetKey();
wc_RsaPrivateKeyDecodePKCS8(key); synchronized (stateLock) {
synchronized (pointerLock) {
wc_RsaPrivateKeyDecodePKCS8(key);
}
state = WolfCryptState.READY; state = WolfCryptState.READY;
hasPrivateKey = true; hasPrivateKey = true;
}
} }
/** /**
@ -286,8 +332,9 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodeRawPublicKey(byte[] n, byte[] e) public synchronized void decodeRawPublicKey(byte[] n, byte[] e)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
decodeRawPublicKey(n, n.length, e, e.length); decodeRawPublicKey(n, n.length, e, e.length);
} }
@ -302,12 +349,18 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodeRawPublicKey(byte[] n, long nSize, byte[] e, long eSize) public synchronized void decodeRawPublicKey(byte[] n, long nSize,
byte[] e, long eSize)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
willSetKey(); willSetKey();
wc_RsaPublicKeyDecodeRaw(n, nSize, e, eSize); synchronized (stateLock) {
state = WolfCryptState.READY; synchronized (pointerLock) {
wc_RsaPublicKeyDecodeRaw(n, nSize, e, eSize);
}
state = WolfCryptState.READY;
}
} }
/** /**
@ -319,8 +372,9 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodeRawPublicKey(ByteBuffer n, ByteBuffer e) public synchronized void decodeRawPublicKey(ByteBuffer n, ByteBuffer e)
throws WolfCryptException, IllegalStateException { throws WolfCryptException, IllegalStateException {
decodeRawPublicKey(n, n.limit(), e, e.limit()); decodeRawPublicKey(n, n.limit(), e, e.limit());
} }
@ -335,12 +389,18 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object is already initialized * @throws IllegalStateException if object is already initialized
*/ */
public void decodeRawPublicKey(ByteBuffer n, long nSz, ByteBuffer e, public synchronized void decodeRawPublicKey(ByteBuffer n, long nSz,
long eSz) throws WolfCryptException, IllegalStateException { ByteBuffer e, long eSz)
throws WolfCryptException, IllegalStateException {
willSetKey(); willSetKey();
wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz); synchronized (stateLock) {
state = WolfCryptState.READY; synchronized (pointerLock) {
wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz);
}
state = WolfCryptState.READY;
}
} }
/** /**
@ -355,11 +415,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public void exportRawPublicKey(byte[] n, long[] nSz, byte[] e, long[] eSz) public synchronized void exportRawPublicKey(byte[] n, long[] nSz, byte[] e,
throws WolfCryptException { long[] eSz) throws WolfCryptException {
willUseKey(false); willUseKey(false);
RsaFlattenPublicKey(n, nSz, e, eSz); synchronized (pointerLock) {
RsaFlattenPublicKey(n, nSz, e, eSz);
}
} }
/** /**
@ -370,11 +433,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public void exportRawPublicKey(ByteBuffer n, ByteBuffer e) public synchronized void exportRawPublicKey(ByteBuffer n, ByteBuffer e)
throws WolfCryptException { throws WolfCryptException {
willUseKey(false); willUseKey(false);
RsaFlattenPublicKey(n, e); synchronized (pointerLock) {
RsaFlattenPublicKey(n, e);
}
} }
/** /**
@ -384,10 +450,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public byte[] exportPrivateDer() throws WolfCryptException { public synchronized byte[] exportPrivateDer()
throws WolfCryptException {
willUseKey(true); willUseKey(true);
return wc_RsaKeyToDer(); synchronized (pointerLock) {
return wc_RsaKeyToDer();
}
} }
/** /**
@ -397,10 +467,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public byte[] exportPublicDer() throws WolfCryptException { public synchronized byte[] exportPublicDer()
throws WolfCryptException {
willUseKey(false); willUseKey(false);
return wc_RsaKeyToPublicDer(); synchronized (pointerLock) {
return wc_RsaKeyToPublicDer();
}
} }
/** /**
@ -410,10 +484,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public byte[] privateKeyEncodePKCS8() throws WolfCryptException { public synchronized byte[] privateKeyEncodePKCS8()
throws WolfCryptException {
willUseKey(true); willUseKey(true);
return wc_RsaPrivateKeyToPkcs8(); synchronized (pointerLock) {
return wc_RsaPrivateKeyToPkcs8();
}
} }
/** /**
@ -423,10 +501,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public int getEncryptSize() throws WolfCryptException { public synchronized int getEncryptSize()
throws WolfCryptException {
willUseKey(false); willUseKey(false);
return wc_RsaEncryptSize(); synchronized (pointerLock) {
return wc_RsaEncryptSize();
}
} }
/** /**
@ -439,10 +521,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public byte[] encrypt(byte[] plain, Rng rng) throws WolfCryptException { public synchronized byte[] encrypt(byte[] plain, Rng rng)
throws WolfCryptException {
willUseKey(false); willUseKey(false);
return wc_RsaPublicEncrypt(plain, rng); synchronized (pointerLock) {
return wc_RsaPublicEncrypt(plain, rng);
}
} }
/** /**
@ -454,10 +540,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public byte[] decrypt(byte[] ciphertext) throws WolfCryptException { public synchronized byte[] decrypt(byte[] ciphertext)
throws WolfCryptException {
willUseKey(true); willUseKey(true);
return wc_RsaPrivateDecrypt(ciphertext); synchronized (pointerLock) {
return wc_RsaPrivateDecrypt(ciphertext);
}
} }
/** /**
@ -471,10 +561,14 @@ public class Rsa extends NativeStruct {
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
* @throws IllegalStateException if object does not have key * @throws IllegalStateException if object does not have key
*/ */
public byte[] sign(byte[] data, Rng rng) throws WolfCryptException { public synchronized byte[] sign(byte[] data, Rng rng)
throws WolfCryptException {
willUseKey(true); willUseKey(true);
return wc_RsaSSL_Sign(data, rng); synchronized (pointerLock) {
return wc_RsaSSL_Sign(data, rng);
}
} }
/** /**
@ -486,10 +580,14 @@ public class Rsa extends NativeStruct {
* *
* @throws WolfCryptException if native operation fails * @throws WolfCryptException if native operation fails
*/ */
public byte[] verify(byte[] signature) throws WolfCryptException { public synchronized byte[] verify(byte[] signature)
throws WolfCryptException {
willUseKey(false); willUseKey(false);
return wc_RsaSSL_Verify(signature); synchronized (pointerLock) {
return wc_RsaSSL_Verify(signature);
}
} }
} }

View File

@ -27,6 +27,12 @@ import org.junit.BeforeClass;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import javax.crypto.KeyAgreement; import javax.crypto.KeyAgreement;
import javax.crypto.ShortBufferException; import javax.crypto.ShortBufferException;
@ -494,5 +500,136 @@ public class WolfCryptKeyAgreementTest {
assertArrayEquals(secretA2, secretC); assertArrayEquals(secretA2, secretC);
} }
private void threadRunnerKeyAgreeTest(String algo)
throws InterruptedException, NoSuchAlgorithmException {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final String currentAlgo = algo;
/* DH Tests */
AlgorithmParameterGenerator paramGen =
AlgorithmParameterGenerator.getInstance("DH");
paramGen.init(512);
final AlgorithmParameters params = paramGen.generateParameters();
/* Do encrypt/decrypt and sign/verify in parallel across numThreads
* threads, all operations should pass */
for (int i = 0; i < numThreads; i++) {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
KeyPairGenerator keyGen = null;
KeyAgreement aKeyAgree = null;
KeyAgreement bKeyAgree = null;
KeyAgreement cKeyAgree = null;
KeyPair aPair = null;
KeyPair bPair = null;
KeyPair cPair = null;
try {
/* Set up KeyPairGenerator */
if (currentAlgo.equals("DH")) {
DHParameterSpec dhParams =
(DHParameterSpec)params.getParameterSpec(
DHParameterSpec.class);
keyGen = KeyPairGenerator.getInstance(
"DH", "wolfJCE");
keyGen.initialize(dhParams, secureRandom);
} else {
ECGenParameterSpec ecsp =
new ECGenParameterSpec("secp256r1");
keyGen = KeyPairGenerator.getInstance(
"EC", "wolfJCE");
keyGen.initialize(ecsp);
}
/* Get KeyAgreement objects */
aKeyAgree = KeyAgreement.getInstance(
currentAlgo, "wolfJCE");
bKeyAgree = KeyAgreement.getInstance(
currentAlgo, "wolfJCE");
/* Generate key pairs */
aPair = keyGen.generateKeyPair();
bPair = keyGen.generateKeyPair();
/* Initialize KeyAgreement objects with private keys */
aKeyAgree.init(aPair.getPrivate());
bKeyAgree.init(bPair.getPrivate());
aKeyAgree.doPhase(bPair.getPublic(), true);
bKeyAgree.doPhase(aPair.getPublic(), true);
/* Generate shared secrets */
byte secretA[] = aKeyAgree.generateSecret();
byte secretB[] = bKeyAgree.generateSecret();
if (!Arrays.equals(secretA, secretB)) {
failed = 1;
}
if (failed == 0) {
cKeyAgree = KeyAgreement.getInstance(
currentAlgo, "wolfJCE");
cPair = keyGen.generateKeyPair();
cKeyAgree.init(cPair.getPrivate());
aKeyAgree.doPhase(cPair.getPublic(), true);
cKeyAgree.doPhase(aPair.getPublic(), true);
byte secretA2[] = aKeyAgree.generateSecret();
byte secretC[] = cKeyAgree.generateSecret();
if (!Arrays.equals(secretA2, secretC)) {
failed = 1;
}
}
} catch (Exception e) {
e.printStackTrace();
failed = 1;
} finally {
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in KeyAgreement thread test");
}
}
}
@Test
public void testThreadedKeyAgreement()
throws InterruptedException, NoSuchAlgorithmException {
threadRunnerKeyAgreeTest("DH");
threadRunnerKeyAgreeTest("ECDH");
}
} }

View File

@ -27,6 +27,12 @@ import org.junit.BeforeClass;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.security.Security; import java.security.Security;
import java.security.Provider; import java.security.Provider;
@ -349,5 +355,125 @@ public class WolfCryptSignatureTest {
return pair; return pair;
} }
private void threadRunnerSignVerify(byte[] inBuf, String algo)
throws InterruptedException {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final String currentAlgo = algo;
final byte[] toSignBuf = inBuf;
/* Do encrypt/decrypt and sign/verify in parallel across numThreads
* threads, all operations should pass */
for (int i = 0; i < numThreads; i++) {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
KeyPair pair = null;
KeyPairGenerator keyGen = null;
PrivateKey priv = null;
PublicKey pub = null;
Signature signer = null;
Signature verifier = null;
byte[] signature = null;
try {
signer = Signature.getInstance(
currentAlgo, "wolfJCE");
verifier = Signature.getInstance(
currentAlgo, "wolfJCE");
if (signer == null || verifier == null) {
failed = 1;
}
/* generate key pair */
if (failed == 0) {
if (currentAlgo.contains("RSA")) {
keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048, secureRandom);
pair = keyGen.generateKeyPair();
} else if (currentAlgo.contains("ECDSA")) {
keyGen = KeyPairGenerator.getInstance("EC",
"wolfJCE");
ECGenParameterSpec ecSpec =
new ECGenParameterSpec("secp521r1");
keyGen.initialize(ecSpec);
pair = keyGen.generateKeyPair();
}
if (pair == null) {
failed = 1;
}
else {
priv = pair.getPrivate();
pub = pair.getPublic();
}
}
if (failed == 0) {
/* generate signature */
signer.initSign(priv);
signer.update(toSignBuf, 0, toSignBuf.length);
signature = signer.sign();
/* verify signature */
verifier.initVerify(pub);
verifier.update(toSignBuf, 0, toSignBuf.length);
boolean verified = verifier.verify(signature);
if (verified == false) {
failed = 1;
}
}
} catch (Exception e) {
e.printStackTrace();
failed = 1;
} finally {
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in RSA sign/verify thread test");
}
}
}
@Test
public void testThreadedWolfSignWolfVerify() throws InterruptedException {
final String toSign = "Hello World";
final byte[] toSignBuf = toSign.getBytes();
/* run threaded test for each enabled Signature algorithm */
for (int i = 0; i < enabledAlgos.size(); i++) {
threadRunnerSignVerify(toSignBuf, enabledAlgos.get(i));
}
}
} }

View File

@ -27,6 +27,14 @@ import org.junit.Assume;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import com.wolfssl.wolfcrypt.Dh; import com.wolfssl.wolfcrypt.Dh;
import com.wolfssl.wolfcrypt.Rng; import com.wolfssl.wolfcrypt.Rng;
import com.wolfssl.wolfcrypt.WolfCryptError; import com.wolfssl.wolfcrypt.WolfCryptError;
@ -35,6 +43,7 @@ import com.wolfssl.wolfcrypt.Fips;
public class DhTest { public class DhTest {
private static Rng rng = new Rng(); private static Rng rng = new Rng();
private final Object rngLock = new Rng();
@BeforeClass @BeforeClass
public static void setUpRng() { public static void setUpRng() {
@ -74,8 +83,10 @@ public class DhTest {
assertNull(alice.getPublicKey()); assertNull(alice.getPublicKey());
assertNull(bob.getPublicKey()); assertNull(bob.getPublicKey());
alice.makeKey(rng); synchronized (rngLock) {
bob.makeKey(rng); alice.makeKey(rng);
bob.makeKey(rng);
}
assertNotNull(alice.getPublicKey()); assertNotNull(alice.getPublicKey());
assertNotNull(bob.getPublicKey()); assertNotNull(bob.getPublicKey());
@ -87,4 +98,102 @@ public class DhTest {
assertNotNull(sharedSecretB); assertNotNull(sharedSecretB);
assertArrayEquals(sharedSecretA, sharedSecretB); assertArrayEquals(sharedSecretA, sharedSecretB);
} }
@Test
public void threadedDhSharedSecretTest() throws InterruptedException {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final byte[] p = Util.h2b(
"E6969D3D495BE32C7CF180C3BDD4798E91B7818251BB055E"
+ "2A2064904A79A770FA15A259CBD523A6A6EF09C43048D5A22F971F3C20"
+ "129B48000E6EDD061CBC053E371D794E5327DF611EBBBE1BAC9B5C6044"
+ "CF023D76E05EEA9BAD991B13A63C974E9EF1839EB5DB125136F7262E56"
+ "A8871538DFD823C6505085E21F0DD5C86B");
final byte[] g = Util.h2b("02");
/* make sure alice and bob shared secret generation matches when done
* in parallel over numThreads threads */
for (int i = 0; i < numThreads; i++) {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
Dh alice = null;
Dh bob = null;
try {
alice = new Dh(p, g);
bob = new Dh();
bob.setParams(p, g);
/* keys should be null before generation */
if (alice.getPublicKey() != null ||
bob.getPublicKey() != null) {
failed = 1;
}
/* generate Dh keys */
if (failed == 0) {
synchronized (rngLock) {
alice.makeKey(rng);
bob.makeKey(rng);
}
}
/* keys should not be null after generation */
if (failed == 0) {
if (alice.getPublicKey() == null ||
bob.getPublicKey() == null) {
failed = 1;
}
}
if (failed == 0) {
byte[] sharedSecretA = alice.makeSharedSecret(bob);
byte[] sharedSecretB = bob.makeSharedSecret(alice);
if (sharedSecretA == null ||
sharedSecretB == null ||
!Arrays.equals(sharedSecretA, sharedSecretB)) {
failed = 1;
}
}
} catch (Exception e) {
e.printStackTrace();
failed = 1;
} finally {
alice.releaseNativeStruct();
bob.releaseNativeStruct();
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in DH shared secret thread test");
}
}
}
} }

View File

@ -27,6 +27,14 @@ import org.junit.Assume;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.spec.ECGenParameterSpec; import java.security.spec.ECGenParameterSpec;
@ -43,10 +51,13 @@ import com.wolfssl.wolfcrypt.WolfCryptException;
public class EccTest { public class EccTest {
private static Rng rng = new Rng(); private static Rng rng = new Rng();
private static final Object rngLock = new Rng();
@BeforeClass @BeforeClass
public static void setUpRng() { public static void setUpRng() {
rng.init(); synchronized (rngLock) {
rng.init();
}
} }
@BeforeClass @BeforeClass
@ -71,8 +82,10 @@ public class EccTest {
Ecc bob = new Ecc(); Ecc bob = new Ecc();
Ecc aliceX963 = new Ecc(); Ecc aliceX963 = new Ecc();
alice.makeKey(rng, 66); synchronized (rngLock) {
bob.makeKey(rng, 66); alice.makeKey(rng, 66);
bob.makeKey(rng, 66);
}
aliceX963.importX963(alice.exportX963()); aliceX963.importX963(alice.exportX963());
byte[] sharedSecretA = alice.makeSharedSecret(bob); byte[] sharedSecretA = alice.makeSharedSecret(bob);
@ -112,7 +125,10 @@ public class EccTest {
byte[] hash = "Everyone gets Friday off. ecc p".getBytes(); byte[] hash = "Everyone gets Friday off. ecc p".getBytes();
byte[] signature = alice.sign(hash, rng); byte[] signature = null;
synchronized (rngLock) {
signature = alice.sign(hash, rng);
}
assertTrue(bob.verify(hash, signature)); assertTrue(bob.verify(hash, signature));
@ -157,11 +173,15 @@ public class EccTest {
@Test @Test
public void eccMakeKeyOnCurve() { public void eccMakeKeyOnCurve() {
Ecc alice = new Ecc(); Ecc alice = new Ecc();
alice.makeKeyOnCurve(rng, 32, "secp256r1"); synchronized (rngLock) {
alice.makeKeyOnCurve(rng, 32, "secp256r1");
}
try { try {
alice = new Ecc(); alice = new Ecc();
alice.makeKeyOnCurve(rng, 32, "BADCURVE"); synchronized (rngLock) {
alice.makeKeyOnCurve(rng, 32, "BADCURVE");
}
fail("Creating ECC key on bad curve should fail with exception"); fail("Creating ECC key on bad curve should fail with exception");
} catch (WolfCryptException e) { } catch (WolfCryptException e) {
/* should throw exception here */ /* should throw exception here */
@ -300,5 +320,199 @@ public class EccTest {
assertEquals(curveName, "SECP256R1"); assertEquals(curveName, "SECP256R1");
} }
@Test
public void threadedEccSharedSecretTest() throws InterruptedException {
int numThreads = 20;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
/* make sure alice and bob shared secret generation matches when done
* in parallel over numThreads threads */
for (int i = 0; i < numThreads; i++) {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
Ecc alice = null;
Ecc bob = null;
Ecc aliceX963 = null;
Ecc alice2 = null;
try {
alice = new Ecc();
bob = new Ecc();
aliceX963 = new Ecc();
synchronized (rngLock) {
alice.makeKey(rng, 66);
bob.makeKey(rng, 66);
}
aliceX963.importX963(alice.exportX963());
byte[] sharedSecretA = alice.makeSharedSecret(bob);
byte[] sharedSecretB = bob.makeSharedSecret(aliceX963);
if (!Arrays.equals(sharedSecretA, sharedSecretB)) {
failed = 1;
}
if (failed == 0) {
alice2 = new Ecc();
alice2.importPrivate(alice.exportPrivate(),
alice.exportX963());
if (!Arrays.equals(sharedSecretA,
alice2.makeSharedSecret(bob))) {
failed = 1;
}
}
} catch (Exception e) {
e.printStackTrace();
failed = 1;
} finally {
alice.releaseNativeStruct();
alice2.releaseNativeStruct();
aliceX963.releaseNativeStruct();
bob.releaseNativeStruct();
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in ECC shared secret thread test");
}
}
}
@Test
public void threadedEccSignVerifyTest() throws InterruptedException {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final byte[] prvKey = Util.h2b("30770201010420F8CF92"
+ "6BBD1E28F1A8ABA1234F3274188850AD7EC7EC92"
+ "F88F974DAF568965C7A00A06082A8648CE3D0301"
+ "07A1440342000455BFF40F44509A3DCE9BB7F0C5"
+ "4DF5707BD4EC248E1980EC5A4CA22403622C9BDA"
+ "EFA2351243847616C6569506CC01A9BDF6751A42"
+ "F7BDA9B236225FC75D7FB4");
final byte[] pubKey = Util.h2b("3059301306072A8648CE"
+ "3D020106082A8648CE3D0301070342000455BFF4"
+ "0F44509A3DCE9BB7F0C54DF5707BD4EC248E1980"
+ "EC5A4CA22403622C9BDAEFA2351243847616C656"
+ "9506CC01A9BDF6751A42F7BDA9B236225FC75D7FB4");
final byte[] hash = "Everyone gets Friday off. ecc p".getBytes();
/* Do sign/verify in each thread, in parallel across numThreads threads,
* all operations should pass */
for (int i = 0; i < numThreads; i++) {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
Ecc alice = null;
Ecc bob = null;
Ecc aliceX963 = null;
Ecc alice2 = null;
try {
alice = new Ecc();
bob = new Ecc();
aliceX963 = new Ecc();
/* import keys */
alice.privateKeyDecode(prvKey);
bob.publicKeyDecode(pubKey);
/* alice sign */
byte[] signature = null;
synchronized (rngLock) {
signature = alice.sign(hash, rng);
}
/* bob verify */
if (bob.verify(hash, signature) != true) {
failed = 1;
}
/* test alice verify with export/import pub key */
if (failed == 0) {
aliceX963.importX963(alice.exportX963());
if (aliceX963.verify(hash, signature) != true) {
failed = 1;
}
}
/* test alice verify with export/import priv key */
if (failed == 0) {
alice2 = new Ecc();
alice2.importPrivate(alice.exportPrivate(),
alice.exportX963());
if (alice2.verify(hash, signature) != true) {
failed = 1;
}
}
} catch (Exception e) {
e.printStackTrace();
failed = 1;
} finally {
alice.releaseNativeStruct();
alice2.releaseNativeStruct();
aliceX963.releaseNativeStruct();
bob.releaseNativeStruct();
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in ECC sign/verify thread test");
}
}
}
} }

View File

@ -29,6 +29,14 @@ import org.junit.Assume;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import com.wolfssl.wolfcrypt.Rsa; import com.wolfssl.wolfcrypt.Rsa;
import com.wolfssl.wolfcrypt.Rng; import com.wolfssl.wolfcrypt.Rng;
import com.wolfssl.wolfcrypt.Fips; import com.wolfssl.wolfcrypt.Fips;
@ -367,4 +375,136 @@ public class RsaTest {
assertArrayEquals(plaintext, pub.verify(signature)); assertArrayEquals(plaintext, pub.verify(signature));
} }
@Test
public void threadedRsaSignVerifyTest() throws InterruptedException {
int numThreads = 20;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final byte[] prvKey = Util
.h2b("308204a40201000282010100c303d12bfe39a432453b53c8842b2a7c"
+ "749abdaa2a520747d6a636b207328ed0ba697bc6c3449ed48148"
+ "fd2d68a28b67bba175c8362c4ad21bf78bbacf0df9efecf1811e"
+ "7b9b03479abf65cc7f652469a6e814895be434f7c5b01493f567"
+ "7b3a7a78e101565691a613428dd23c409c4cefd186df37511b0c"
+ "a13bf5f1a34a35e4e1ce96df1b7ebf4e97d010e8a8083081af20"
+ "0b4314c57467b432826f8d86c28840993683ba1e40722217d752"
+ "652473b0ceef19cdaeff786c7bc01203d44e720d506d3ba33ba3"
+ "995e9dc8d90c85b3d98ad95426db6dfaacbbff254cc4d179f471"
+ "d386401813b063b5724e30c49784862d562fd715f77fc0aef5fc"
+ "5be5fba1bad302030100010282010100a2e6d85f107164089e2e"
+ "6dd16d1e85d20ab18c47ce2c516aa0129e53de914c1d6dea597b"
+ "f277aad9c6d98aabd8e116e46326ffb56c1359b8e3a5c872172e"
+ "0c9f6fe5593f766f49b111c25a2e16290ddeb78edc40d5a2eee0"
+ "1ea1f4be97db86639614cd9809602d30769c3ccde688ee479279"
+ "0b5a00e25e5f117c7df908b72006892a5dfd00ab22e1f0b3bc24"
+ "a95e260e1f002dfe219a535b6dd32bab9482684336d8f62fc622"
+ "fcb5415d0d3360eaa47d7ee84b559156d35c578f1f94172faade"
+ "e99ea8f4cf8a4c8ea0e45673b2cf4f86c5693cf324208b5c960c"
+ "fa6b123b9a67c1dfc696b2a5d5920d9b094268241045d450e417"
+ "3948d0358b946d11de8fca5902818100ea24a7f96933e971dc52"
+ "7d8821282f49deba7216e9cc477a880d94578458163a81b03fa2"
+ "cfa66c1eb00629008fe77776acdbcac7d95e9b3f269052aefc38"
+ "900014bbb40f5894e72f6a7e1c4f4121d431591f4e8a1a8da757"
+ "6c22d8e5f47e32a610cb64a5550387a627058cc3d7b627b24dba"
+ "30da478f54d33d8b848d949858a502818100d5381bc38fc5930c"
+ "470b6f3592c5b08d46c892188ff5800af7efa1fe80b9b52abaca"
+ "18b05da507d0938dd89c041cd4628ea6268101ffce8a2a633435"
+ "40aa6d80de89236a574d9e6ead934e56900b6d9d738b0cae273d"
+ "de4ef0aac56c78676c94529c37676c2defbbafdfa6903cc447cf"
+ "8d969e98a9b49fc5a650dcb3f0fb74170281805e830962bdba7c"
+ "a2bf4274f57c1cd269c9040d857e3e3d2412c3187bf329f35f0e"
+ "766c5975e44184699d32f3cd22abb035ba4ab23ce5d958b6624f"
+ "5ddee59e0aca53b22cf79eb36b0a5b7965ec6e914e9220f6fcfc"
+ "16edd3760ce2ec7fb269136b780e5a4664b45eb725a05a753a4b"
+ "efc73c3ef7fd26b820c4990a9a73bec31902818100ba449314ac"
+ "34193b5f9160acf7b4d681053651533de865dcaf2edc613ec97d"
+ "b87f87f03b9b03822937ce724e11d5b1c10c07a099914a8d7fec"
+ "79cff139b5e985ec62f7da7dbc644d223c0ef2d651f587d899c0"
+ "11205d0f29fd5be2aed91cd921566dfc84d05fed10151c1821e7"
+ "c43d4bd7d09e6a95cf22c9037b9ee36001fc2f02818011d04bcf"
+ "1b67b99f1075478665ae31c2c630ac590650d90fb57006f7f0d3"
+ "c8627ca8da6ef6213fd37f5fea8aab3fd92a5ef351d2c23037e3"
+ "2da3750d1e4d2134d557705c89bf72ec4a6e68d5cd1874334e8c"
+ "3a458fe69640eb63f919863a51dd894bb0f3f99f5d289538be35"
+ "abca5ce7935334a1455d1339654246a19fcdf5bf");
final byte[] plaintext = "Now is the time for all".getBytes();
/* Do encrypt/decrypt and sign/verify in parallel across numThreads
* threads, all operations should pass */
for (int i = 0; i < numThreads; i++) {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
Rsa priv = null;
Rsa pub = null;
byte[] n_out = new byte[256];
byte[] e_out = new byte[3];
long[] n_len = new long[1];
long[] e_len = new long[1];
n_len[0] = n_out.length;
e_len[0] = e_out.length;
try {
priv = new Rsa(prvKey);
priv.exportRawPublicKey(n_out, n_len, e_out, e_len);
priv.setRng(rng);
pub = new Rsa(n_out, e_out);
byte[] ciphertext = pub.encrypt(plaintext, rng);
if (!Arrays.equals(plaintext,
priv.decrypt(ciphertext))) {
failed = 1;
}
if (failed == 0) {
byte[] signature = priv.sign(plaintext, rng);
if (!Arrays.equals(plaintext,
pub.verify(signature))) {
failed = 1;
}
}
} catch (Exception e) {
e.printStackTrace();
failed = 1;
} finally {
priv.releaseNativeStruct();
pub.releaseNativeStruct();
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in RSA sign/verify thread test");
}
}
}
} }