JNI: add synchronization around native ecc_key/RsaKey/DhKey pointer access in Ecc/Rsa/Dh class
parent
8606e9e14e
commit
f6ffb7489e
|
@ -11,10 +11,10 @@ extern "C" {
|
|||
#define com_wolfssl_wolfcrypt_Dh_NULL 0LL
|
||||
/*
|
||||
* Class: com_wolfssl_wolfcrypt_Dh
|
||||
* Method: mallocNativeStruct
|
||||
* Method: mallocNativeStruct_internal
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct_1internal
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
|
|
100
jni/jni_dh.c
100
jni/jni_dh.c
|
@ -19,6 +19,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef WOLFSSL_USER_SETTINGS
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#elif !defined(__ANDROID__)
|
||||
|
@ -37,23 +39,29 @@
|
|||
#define RNG WC_RNG
|
||||
#endif
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct(
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Dh_mallocNativeStruct_1internal(
|
||||
JNIEnv* env, jobject this)
|
||||
{
|
||||
jlong ret = 0;
|
||||
|
||||
#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");
|
||||
}
|
||||
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
|
||||
throwNotCompiledInException(env);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
return (jlong)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
|
@ -61,13 +69,17 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1InitDhKey(
|
|||
JNIEnv* env, jobject this)
|
||||
{
|
||||
#ifndef NO_DH
|
||||
int ret = 0;
|
||||
DhKey* key = (DhKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
/* getNativeStruct may throw exception */
|
||||
return;
|
||||
}
|
||||
|
||||
wc_InitDhKey(key);
|
||||
ret = wc_InitDhKey(key);
|
||||
if (ret != 0) {
|
||||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
|
||||
LogStr("wc_InitDhKey(key=%p)\n", key);
|
||||
#else
|
||||
|
@ -80,13 +92,17 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1FreeDhKey(
|
|||
JNIEnv* env, jobject this)
|
||||
{
|
||||
#ifndef NO_DH
|
||||
int ret = 0;
|
||||
DhKey* key = (DhKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
/* getNativeStruct may throw exception */
|
||||
return;
|
||||
}
|
||||
|
||||
wc_FreeDhKey(key);
|
||||
ret = wc_FreeDhKey(key);
|
||||
if (ret != 0) {
|
||||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
|
||||
LogStr("wc_FreeDhKey(key=%p)\n", key);
|
||||
#else
|
||||
|
@ -116,12 +132,16 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhSetKey(
|
|||
g = getByteArray(env, g_object);
|
||||
gSz = getByteArrayLength(env, g_object);
|
||||
|
||||
ret = (!key || !p || !g)
|
||||
? BAD_FUNC_ARG
|
||||
: wc_DhSetKey(key, p, pSz, g, gSz);
|
||||
if (key == NULL || p == NULL || g == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
else {
|
||||
ret = wc_DhSetKey(key, p, pSz, g, gSz);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
|
||||
LogStr("wc_DhSetKey(key=%p, p, pSz, g, gSz) = %d\n", key, ret);
|
||||
LogStr("p[%u]: [%p]\n", (word32)pSz, p);
|
||||
|
@ -164,26 +184,29 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
|
|||
return;
|
||||
}
|
||||
|
||||
if (!key || !rng || (size < 0))
|
||||
if (key == NULL || rng == NULL || (size < 0)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
priv = XMALLOC(privSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (priv == NULL) {
|
||||
throwOutOfMemoryException(env,
|
||||
"Failed to allocate private key buffer");
|
||||
"Failed to allocate private key buffer");
|
||||
return;
|
||||
}
|
||||
XMEMSET(priv, 0, privSz);
|
||||
|
||||
pub = XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (pub == NULL) {
|
||||
XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
throwOutOfMemoryException(env,
|
||||
"Failed to allocate public key buffer");
|
||||
"Failed to allocate public key buffer");
|
||||
return;
|
||||
}
|
||||
XMEMSET(pub, 0, pubSz);
|
||||
|
||||
ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz);
|
||||
}
|
||||
|
@ -191,11 +214,13 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
|
|||
if (ret == 0) {
|
||||
|
||||
/* keys should be positive, if leading bit is set, add zero byte */
|
||||
if (priv[0] & 0x80)
|
||||
if (priv[0] & 0x80) {
|
||||
lBitPriv = 1;
|
||||
}
|
||||
|
||||
if (pub[0] & 0x80)
|
||||
if (pub[0] & 0x80) {
|
||||
lBitPub = 1;
|
||||
}
|
||||
|
||||
jbyteArray privateKey = (*env)->NewByteArray(env, lBitPriv + privSz);
|
||||
jbyteArray publicKey = (*env)->NewByteArray(env, lBitPub + pubSz);
|
||||
|
@ -219,6 +244,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
|
|||
|
||||
} else {
|
||||
throwWolfCryptException(env, "Failed to allocate privateKey");
|
||||
exceptionThrown = 1;
|
||||
}
|
||||
|
||||
if (publicKey && (exceptionThrown == 0)) {
|
||||
|
@ -247,10 +273,14 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair(
|
|||
LogStr("public[%u]: [%p]\n", pubSz, pub);
|
||||
LogHex(pub, 0, pubSz);
|
||||
|
||||
if (priv)
|
||||
if (priv != NULL) {
|
||||
XMEMSET(priv, 0, privSz);
|
||||
XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (pub)
|
||||
}
|
||||
if (pub != NULL) {
|
||||
XMEMSET(pub, 0, pubSz);
|
||||
XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
#endif
|
||||
|
@ -275,12 +305,16 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhCheckPubKey(
|
|||
pub = getByteArray(env, pub_object);
|
||||
pubSz = getByteArrayLength(env, pub_object);
|
||||
|
||||
ret = (!key || !pub)
|
||||
? BAD_FUNC_ARG
|
||||
: wc_DhCheckPubKey(key, pub, pubSz);
|
||||
if (key == NULL || pub == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
else {
|
||||
ret = wc_DhCheckPubKey(key, pub, pubSz);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
|
||||
LogStr("wc_DhCheckPubKey(key=%p, pub, pubSz) = %d\n", key, ret);
|
||||
LogStr("p[%u]: [%p]\n", (word32)pubSz, pub);
|
||||
|
@ -327,10 +361,14 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
|
||||
return result;
|
||||
}
|
||||
XMEMSET(secret, 0, pubSz);
|
||||
|
||||
ret = (!key || !priv || !pub)
|
||||
? BAD_FUNC_ARG
|
||||
: wc_DhAgree(key, secret, &secretSz, priv, privSz, pub, pubSz);
|
||||
if (key == NULL || priv == NULL || pub == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
else {
|
||||
ret = wc_DhAgree(key, secret, &secretSz, priv, privSz, pub, pubSz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
result = (*env)->NewByteArray(env, secretSz);
|
||||
|
@ -350,7 +388,10 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
LogStr("secret[%u]: [%p]\n", secretSz, secret);
|
||||
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, pub_object, pub, JNI_ABORT);
|
||||
|
@ -360,3 +401,4 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ public class Dh extends NativeStruct {
|
|||
private byte[] publicKey = null;
|
||||
private int pSize = 0;
|
||||
|
||||
/* Lock around object state */
|
||||
protected final Object stateLock = new Object();
|
||||
|
||||
/**
|
||||
* Create new Dh object
|
||||
*/
|
||||
|
@ -50,12 +53,19 @@ public class Dh extends NativeStruct {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void releaseNativeStruct() {
|
||||
public synchronized void releaseNativeStruct() {
|
||||
free();
|
||||
|
||||
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
|
||||
*
|
||||
|
@ -63,34 +73,46 @@ public class Dh extends NativeStruct {
|
|||
*
|
||||
* @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 */
|
||||
protected void init() {
|
||||
if (state == WolfCryptState.UNINITIALIZED) {
|
||||
wc_InitDhKey();
|
||||
state = WolfCryptState.INITIALIZED;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Native resources already initialized.");
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.UNINITIALIZED) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
wc_InitDhKey();
|
||||
}
|
||||
state = WolfCryptState.INITIALIZED;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Native resources already initialized");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Free Dh object */
|
||||
protected void free() {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
wc_FreeDhKey();
|
||||
protected synchronized void free() {
|
||||
|
||||
setPrivateKey(new byte[0]);
|
||||
setPublicKey(new byte[0]);
|
||||
synchronized (stateLock) {
|
||||
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
|
||||
*/
|
||||
public void setPrivateKey(byte[] priv) {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
if (privateKey != null)
|
||||
for (int i = 0; i < privateKey.length; i++)
|
||||
privateKey[i] = 0;
|
||||
public synchronized void setPrivateKey(byte[] priv)
|
||||
throws IllegalStateException {
|
||||
|
||||
privateKey = priv.clone();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available parameters to perform opetarion.");
|
||||
synchronized (stateLock) {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
if (privateKey != null) {
|
||||
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
|
||||
*/
|
||||
public void setPublicKey(byte[] pub) {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
if (publicKey != null)
|
||||
for (int i = 0; i < publicKey.length; i++)
|
||||
publicKey[i] = 0;
|
||||
public synchronized void setPublicKey(byte[] pub) {
|
||||
|
||||
publicKey = pub.clone();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available parameters to perform opetarion.");
|
||||
synchronized (stateLock) {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
if (publicKey != null) {
|
||||
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
|
||||
*/
|
||||
public byte[] getPublicKey() {
|
||||
public synchronized byte[] getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
|
@ -148,7 +181,7 @@ public class Dh extends NativeStruct {
|
|||
*
|
||||
* @return private key as byte array
|
||||
*/
|
||||
public byte[] getPrivateKey() {
|
||||
public synchronized byte[] getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
|
@ -161,13 +194,21 @@ public class Dh extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object already initialized
|
||||
*/
|
||||
public void setParams(byte[] p, byte[] g) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_DhSetKey(p, g);
|
||||
this.pSize = p.length;
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has parameters.");
|
||||
public synchronized void setParams(byte[] p, byte[] g)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void makeKey(Rng rng) {
|
||||
public synchronized void makeKey(Rng rng)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
if (privateKey == null) {
|
||||
/* use size of P to allocate key buffer size */
|
||||
wc_DhGenerateKeyPair(rng, this.pSize);
|
||||
synchronized (pointerLock) {
|
||||
wc_DhGenerateKeyPair(rng, this.pSize);
|
||||
}
|
||||
} 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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] makeSharedSecret(Dh pubKey) {
|
||||
public synchronized byte[] makeSharedSecret(Dh pubKey)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
byte[] publicKey = pubKey.getPublicKey();
|
||||
|
||||
if (privateKey != null || publicKey != null) {
|
||||
return wc_DhAgree(privateKey, publicKey);
|
||||
synchronized (pointerLock) {
|
||||
return wc_DhAgree(privateKey, publicKey);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the opperation.");
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ public class Ecc extends NativeStruct {
|
|||
/* used with native wc_ecc_set_rng() */
|
||||
private Rng rng = null;
|
||||
|
||||
/* Lock around object state */
|
||||
protected final Object stateLock = new Object();
|
||||
|
||||
/**
|
||||
* Create new Ecc object
|
||||
*/
|
||||
|
@ -46,7 +49,7 @@ public class Ecc extends NativeStruct {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void releaseNativeStruct() {
|
||||
public synchronized void releaseNativeStruct() {
|
||||
free();
|
||||
|
||||
super.releaseNativeStruct();
|
||||
|
@ -89,19 +92,24 @@ public class Ecc extends NativeStruct {
|
|||
* Initialize Ecc object
|
||||
*/
|
||||
protected void init() {
|
||||
if (state == WolfCryptState.UNINITIALIZED) {
|
||||
wc_ecc_init();
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.UNINITIALIZED) {
|
||||
|
||||
/* used with native wc_ecc_set_rng() */
|
||||
if (rng == null) {
|
||||
rng = new Rng();
|
||||
rng.init();
|
||||
synchronized (pointerLock) {
|
||||
wc_ecc_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
|
||||
*/
|
||||
protected void free() {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
wc_ecc_free();
|
||||
synchronized (stateLock) {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
|
||||
if (this.rng != null) {
|
||||
rng.free();
|
||||
rng.releaseNativeStruct();
|
||||
synchronized (pointerLock) {
|
||||
wc_ecc_free();
|
||||
}
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void makeKey(Rng rng, int size) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_ecc_make_key(rng, size);
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void makeKey(Rng rng, int size)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void makeKeyOnCurve(Rng rng, int size, String curveName) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_ecc_make_key_ex(rng, size, curveName.toUpperCase());
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void makeKeyOnCurve(Rng rng, int size, String curveName)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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
|
||||
* @throws IllegalStateException if object does not have a key
|
||||
*/
|
||||
public void checkKey() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
wc_ecc_check_key();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized void checkKey()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void importPrivate(byte[] privKey, byte[] x963Key) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_ecc_import_private(privKey, x963Key, null);
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void importPrivate(byte[] privKey, byte[] x963Key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void importPrivateOnCurve(byte[] privKey, byte[] x963Key,
|
||||
String curveName) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_ecc_import_private(privKey, x963Key, curveName);
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void importPrivateOnCurve(byte[] privKey,
|
||||
byte[] x963Key, String curveName)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] exportPrivate() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_ecc_export_private();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] exportPrivate()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void importX963(byte[] key) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_ecc_import_x963(key);
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void importX963(byte[] key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] exportX963() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_ecc_export_x963();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] exportX963()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void privateKeyDecode(byte[] key) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_EccPrivateKeyDecode(key);
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void privateKeyDecode(byte[] key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] privateKeyEncode() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_EccKeyToDer();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] privateKeyEncode()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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 IllegalStateException if object already has a key
|
||||
*/
|
||||
public void publicKeyDecode(byte[] key) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
wc_EccPublicKeyDecode(key);
|
||||
state = WolfCryptState.READY;
|
||||
} else {
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
public synchronized void publicKeyDecode(byte[] key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.INITIALIZED) {
|
||||
|
||||
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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] publicKeyEncode() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_EccPublicKeyToDer();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] publicKeyEncode()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] makeSharedSecret(Ecc pubKey) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_ecc_shared_secret(pubKey, this.rng);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] makeSharedSecret(Ecc pubKey)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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 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];
|
||||
|
||||
if (state == WolfCryptState.READY) {
|
||||
signature = wc_ecc_sign_hash(hash, rng);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
synchronized (pointerLock) {
|
||||
signature = wc_ecc_sign_hash(hash, rng);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
}
|
||||
}
|
||||
|
||||
return signature;
|
||||
|
@ -385,14 +495,21 @@ public class Ecc extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @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;
|
||||
|
||||
if (state == WolfCryptState.READY) {
|
||||
result = wc_ecc_verify_hash(hash, signature);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
result = wc_ecc_verify_hash(hash, signature);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -408,9 +525,10 @@ public class Ecc extends NativeStruct {
|
|||
* @return size of ECC curve
|
||||
*
|
||||
* @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 */
|
||||
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 IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] privateKeyEncodePKCS8() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_ecc_private_key_to_pkcs8();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] privateKeyEncodePKCS8()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
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
|
||||
*/
|
||||
public static String getCurveName(ECParameterSpec spec)
|
||||
throws InvalidAlgorithmParameterException
|
||||
{
|
||||
throws WolfCryptException, InvalidAlgorithmParameterException {
|
||||
|
||||
int curve_id;
|
||||
|
||||
/* Ecc object doesn't need to be initialied before call */
|
||||
|
|
|
@ -32,6 +32,9 @@ public class Rsa extends NativeStruct {
|
|||
private boolean hasPrivateKey = false;
|
||||
private Rng rng;
|
||||
|
||||
/* Lock around object state */
|
||||
protected final Object stateLock = new Object();
|
||||
|
||||
/**
|
||||
* Malloc native JNI Rsa structure
|
||||
*
|
||||
|
@ -135,15 +138,18 @@ public class Rsa extends NativeStruct {
|
|||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
*/
|
||||
public void setRng(Rng rng) throws WolfCryptException {
|
||||
public synchronized void setRng(Rng rng) throws WolfCryptException {
|
||||
init();
|
||||
|
||||
if (wc_RsaSetRNG(rng))
|
||||
this.rng = rng;
|
||||
synchronized (pointerLock) {
|
||||
if (wc_RsaSetRNG(rng)) {
|
||||
this.rng = rng;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseNativeStruct() {
|
||||
public synchronized void releaseNativeStruct() {
|
||||
free();
|
||||
|
||||
super.releaseNativeStruct();
|
||||
|
@ -155,9 +161,15 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
*/
|
||||
protected void init() throws WolfCryptException {
|
||||
if (state == WolfCryptState.UNINITIALIZED) {
|
||||
wc_InitRsaKey();
|
||||
state = WolfCryptState.INITIALIZED;
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.UNINITIALIZED) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
wc_InitRsaKey();
|
||||
}
|
||||
state = WolfCryptState.INITIALIZED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,8 +184,11 @@ public class Rsa extends NativeStruct {
|
|||
|
||||
init();
|
||||
|
||||
if (state != WolfCryptState.INITIALIZED)
|
||||
throw new IllegalStateException("Object already has a key.");
|
||||
synchronized (stateLock) {
|
||||
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
|
||||
*/
|
||||
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(
|
||||
"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
|
||||
*/
|
||||
protected void free() throws WolfCryptException {
|
||||
if (state != WolfCryptState.UNINITIALIZED) {
|
||||
wc_FreeRsaKey();
|
||||
state = WolfCryptState.UNINITIALIZED;
|
||||
|
||||
synchronized (stateLock) {
|
||||
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 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 {
|
||||
|
||||
willSetKey();
|
||||
|
||||
MakeRsaKey(size, e, rng);
|
||||
synchronized (stateLock) {
|
||||
synchronized (pointerLock) {
|
||||
MakeRsaKey(size, e, rng);
|
||||
}
|
||||
|
||||
state = WolfCryptState.READY;
|
||||
hasPrivateKey = true;
|
||||
state = WolfCryptState.READY;
|
||||
hasPrivateKey = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,12 +265,17 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object is already initialized
|
||||
*/
|
||||
public void decodePublicKey(byte[] key)
|
||||
public synchronized void decodePublicKey(byte[] key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
willSetKey();
|
||||
|
||||
wc_RsaPublicKeyDecode(key);
|
||||
state = WolfCryptState.READY;
|
||||
synchronized (stateLock) {
|
||||
synchronized (pointerLock) {
|
||||
wc_RsaPublicKeyDecode(key);
|
||||
}
|
||||
state = WolfCryptState.READY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,13 +286,18 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object is already initialized
|
||||
*/
|
||||
public void decodePrivateKey(byte[] key)
|
||||
public synchronized void decodePrivateKey(byte[] key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
willSetKey();
|
||||
|
||||
wc_RsaPrivateKeyDecode(key);
|
||||
state = WolfCryptState.READY;
|
||||
hasPrivateKey = true;
|
||||
synchronized (stateLock) {
|
||||
synchronized (pointerLock) {
|
||||
wc_RsaPrivateKeyDecode(key);
|
||||
}
|
||||
state = WolfCryptState.READY;
|
||||
hasPrivateKey = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,14 +308,19 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object is already initialized
|
||||
*/
|
||||
public void decodePrivateKeyPKCS8(byte[] key)
|
||||
public synchronized void decodePrivateKeyPKCS8(byte[] key)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
willSetKey();
|
||||
|
||||
wc_RsaPrivateKeyDecodePKCS8(key);
|
||||
synchronized (stateLock) {
|
||||
synchronized (pointerLock) {
|
||||
wc_RsaPrivateKeyDecodePKCS8(key);
|
||||
}
|
||||
|
||||
state = WolfCryptState.READY;
|
||||
hasPrivateKey = true;
|
||||
state = WolfCryptState.READY;
|
||||
hasPrivateKey = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,8 +332,9 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @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 {
|
||||
|
||||
decodeRawPublicKey(n, n.length, e, e.length);
|
||||
}
|
||||
|
||||
|
@ -302,12 +349,18 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @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 {
|
||||
|
||||
willSetKey();
|
||||
|
||||
wc_RsaPublicKeyDecodeRaw(n, nSize, e, eSize);
|
||||
state = WolfCryptState.READY;
|
||||
synchronized (stateLock) {
|
||||
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 IllegalStateException if object is already initialized
|
||||
*/
|
||||
public void decodeRawPublicKey(ByteBuffer n, ByteBuffer e)
|
||||
public synchronized void decodeRawPublicKey(ByteBuffer n, ByteBuffer e)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
decodeRawPublicKey(n, n.limit(), e, e.limit());
|
||||
}
|
||||
|
||||
|
@ -335,12 +389,18 @@ public class Rsa extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object is already initialized
|
||||
*/
|
||||
public void decodeRawPublicKey(ByteBuffer n, long nSz, ByteBuffer e,
|
||||
long eSz) throws WolfCryptException, IllegalStateException {
|
||||
public synchronized void decodeRawPublicKey(ByteBuffer n, long nSz,
|
||||
ByteBuffer e, long eSz)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
willSetKey();
|
||||
|
||||
wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz);
|
||||
state = WolfCryptState.READY;
|
||||
synchronized (stateLock) {
|
||||
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
|
||||
*/
|
||||
public void exportRawPublicKey(byte[] n, long[] nSz, byte[] e, long[] eSz)
|
||||
throws WolfCryptException {
|
||||
public synchronized void exportRawPublicKey(byte[] n, long[] nSz, byte[] e,
|
||||
long[] eSz) throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public void exportRawPublicKey(ByteBuffer n, ByteBuffer e)
|
||||
public synchronized void exportRawPublicKey(ByteBuffer n, ByteBuffer e)
|
||||
throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public byte[] exportPrivateDer() throws WolfCryptException {
|
||||
public synchronized byte[] exportPrivateDer()
|
||||
throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public byte[] exportPublicDer() throws WolfCryptException {
|
||||
public synchronized byte[] exportPublicDer()
|
||||
throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public byte[] privateKeyEncodePKCS8() throws WolfCryptException {
|
||||
public synchronized byte[] privateKeyEncodePKCS8()
|
||||
throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public int getEncryptSize() throws WolfCryptException {
|
||||
public synchronized int getEncryptSize()
|
||||
throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public byte[] encrypt(byte[] plain, Rng rng) throws WolfCryptException {
|
||||
public synchronized byte[] encrypt(byte[] plain, Rng rng)
|
||||
throws WolfCryptException {
|
||||
|
||||
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
|
||||
*/
|
||||
public byte[] decrypt(byte[] ciphertext) throws WolfCryptException {
|
||||
public synchronized byte[] decrypt(byte[] ciphertext)
|
||||
throws WolfCryptException {
|
||||
|
||||
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 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);
|
||||
|
||||
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
|
||||
*/
|
||||
public byte[] verify(byte[] signature) throws WolfCryptException {
|
||||
public synchronized byte[] verify(byte[] signature)
|
||||
throws WolfCryptException {
|
||||
|
||||
willUseKey(false);
|
||||
|
||||
return wc_RsaSSL_Verify(signature);
|
||||
synchronized (pointerLock) {
|
||||
return wc_RsaSSL_Verify(signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@ import org.junit.BeforeClass;
|
|||
|
||||
import java.util.Arrays;
|
||||
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.ShortBufferException;
|
||||
|
@ -494,5 +500,136 @@ public class WolfCryptKeyAgreementTest {
|
|||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@ import org.junit.BeforeClass;
|
|||
|
||||
import java.util.Arrays;
|
||||
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.Provider;
|
||||
|
@ -349,5 +355,125 @@ public class WolfCryptSignatureTest {
|
|||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ import org.junit.Assume;
|
|||
import org.junit.BeforeClass;
|
||||
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.Rng;
|
||||
import com.wolfssl.wolfcrypt.WolfCryptError;
|
||||
|
@ -35,6 +43,7 @@ import com.wolfssl.wolfcrypt.Fips;
|
|||
|
||||
public class DhTest {
|
||||
private static Rng rng = new Rng();
|
||||
private final Object rngLock = new Rng();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpRng() {
|
||||
|
@ -74,8 +83,10 @@ public class DhTest {
|
|||
assertNull(alice.getPublicKey());
|
||||
assertNull(bob.getPublicKey());
|
||||
|
||||
alice.makeKey(rng);
|
||||
bob.makeKey(rng);
|
||||
synchronized (rngLock) {
|
||||
alice.makeKey(rng);
|
||||
bob.makeKey(rng);
|
||||
}
|
||||
|
||||
assertNotNull(alice.getPublicKey());
|
||||
assertNotNull(bob.getPublicKey());
|
||||
|
@ -87,4 +98,102 @@ public class DhTest {
|
|||
assertNotNull(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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,14 @@ import org.junit.Assume;
|
|||
import org.junit.BeforeClass;
|
||||
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.KeyPair;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
|
@ -43,10 +51,13 @@ import com.wolfssl.wolfcrypt.WolfCryptException;
|
|||
|
||||
public class EccTest {
|
||||
private static Rng rng = new Rng();
|
||||
private static final Object rngLock = new Rng();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpRng() {
|
||||
rng.init();
|
||||
synchronized (rngLock) {
|
||||
rng.init();
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
@ -71,8 +82,10 @@ public class EccTest {
|
|||
Ecc bob = new Ecc();
|
||||
Ecc aliceX963 = new Ecc();
|
||||
|
||||
alice.makeKey(rng, 66);
|
||||
bob.makeKey(rng, 66);
|
||||
synchronized (rngLock) {
|
||||
alice.makeKey(rng, 66);
|
||||
bob.makeKey(rng, 66);
|
||||
}
|
||||
aliceX963.importX963(alice.exportX963());
|
||||
|
||||
byte[] sharedSecretA = alice.makeSharedSecret(bob);
|
||||
|
@ -112,7 +125,10 @@ public class EccTest {
|
|||
|
||||
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));
|
||||
|
||||
|
@ -157,11 +173,15 @@ public class EccTest {
|
|||
@Test
|
||||
public void eccMakeKeyOnCurve() {
|
||||
Ecc alice = new Ecc();
|
||||
alice.makeKeyOnCurve(rng, 32, "secp256r1");
|
||||
synchronized (rngLock) {
|
||||
alice.makeKeyOnCurve(rng, 32, "secp256r1");
|
||||
}
|
||||
|
||||
try {
|
||||
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");
|
||||
} catch (WolfCryptException e) {
|
||||
/* should throw exception here */
|
||||
|
@ -300,5 +320,199 @@ public class EccTest {
|
|||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,14 @@ import org.junit.Assume;
|
|||
import org.junit.BeforeClass;
|
||||
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.Rng;
|
||||
import com.wolfssl.wolfcrypt.Fips;
|
||||
|
@ -367,4 +375,136 @@ public class RsaTest {
|
|||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue