Merge pull request #263 from cconlon/fenrirAug20
Zeroize native private key copies before JNI byte array releasepull/252/merge
commit
67072b3a46
|
|
@ -36,6 +36,8 @@ word32 getDirectBufferLimit(JNIEnv* env, jobject buffer);
|
|||
void setDirectBufferLimit(JNIEnv* env, jobject buffer, jint limit);
|
||||
|
||||
byte* getByteArray(JNIEnv* env, jbyteArray array);
|
||||
byte* getByteArrayIsCopy(JNIEnv* env, jbyteArray array, jboolean* isCopy);
|
||||
void zeroizeByteArrayCopy(byte* buf, word32 sz, jboolean isCopy);
|
||||
void releaseByteArray(JNIEnv* env, jbyteArray array, byte* elements, jint abort);
|
||||
word32 getByteArrayLength(JNIEnv* env, jbyteArray array);
|
||||
void initializeNativeStruct(JNIEnv* env, jobject obj);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCcm_wc_1AesCcmSetKey
|
|||
Aes* aes = NULL;
|
||||
const byte* key = NULL;
|
||||
word32 keyLen = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
aes = (Aes*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -125,7 +126,8 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCcm_wc_1AesCcmSetKey
|
|||
}
|
||||
|
||||
if (keyArr != NULL) {
|
||||
key = (const byte*)(*env)->GetByteArrayElements(env, keyArr, NULL);
|
||||
key = (const byte*)(*env)->GetByteArrayElements(env, keyArr,
|
||||
&keyIsCopy);
|
||||
keyLen = (*env)->GetArrayLength(env, keyArr);
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +140,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCcm_wc_1AesCcmSetKey
|
|||
}
|
||||
|
||||
if (keyArr != NULL) {
|
||||
zeroizeByteArrayCopy((byte*)key, keyLen, keyIsCopy);
|
||||
(*env)->ReleaseByteArrayElements(env, keyArr, (jbyte*)key, JNI_ABORT);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1CmacSetKey(
|
|||
Cmac* cmac = NULL;
|
||||
byte* key = NULL;
|
||||
word32 keySz = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
cmac = (Cmac*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -119,7 +120,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1CmacSetKey(
|
|||
return;
|
||||
}
|
||||
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (!cmac || !key) {
|
||||
|
|
@ -134,6 +135,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1CmacSetKey(
|
|||
|
||||
LogStr("wc_InitCmac(cmac=%p, key, %d) = %d\n", cmac, keySz, ret);
|
||||
|
||||
zeroizeByteArrayCopy(key, keySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
@ -300,9 +302,11 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1AesCmacGenerate(
|
|||
byte* key = NULL;
|
||||
byte* mac = NULL;
|
||||
word32 actualDataSz, actualKeySz, actualMacArraySz;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
data = getByteArray(env, data_object);
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
actualKeySz = getByteArrayLength(env, key_object);
|
||||
mac = getByteArray(env, mac_object);
|
||||
|
||||
if (data == NULL || key == NULL || mac == NULL) {
|
||||
|
|
@ -312,7 +316,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1AesCmacGenerate(
|
|||
if (ret == 0) {
|
||||
/* Validate size parameters against actual array sizes */
|
||||
actualDataSz = getByteArrayLength(env, data_object);
|
||||
actualKeySz = getByteArrayLength(env, key_object);
|
||||
actualMacArraySz = getByteArrayLength(env, mac_object);
|
||||
|
||||
if (dataSz < 0 || keySz < 0 || macSz < 0 ||
|
||||
|
|
@ -352,6 +355,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1AesCmacGenerate(
|
|||
data, dataSz, key, keySz, ret);
|
||||
|
||||
releaseByteArray(env, data_object, data, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(key, actualKeySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
releaseByteArray(env, mac_object, mac, JNI_ABORT);
|
||||
|
||||
|
|
@ -372,10 +376,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1AesCmacVerify(
|
|||
byte* data = NULL;
|
||||
byte* key = NULL;
|
||||
word32 actualMacSz, actualDataSz, actualKeySz;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
mac = getByteArray(env, mac_object);
|
||||
data = getByteArray(env, data_object);
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
actualKeySz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (mac == NULL || data == NULL || key == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
|
|
@ -385,7 +391,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1AesCmacVerify(
|
|||
/* Validate size parameters against actual array sizes */
|
||||
actualMacSz = getByteArrayLength(env, mac_object);
|
||||
actualDataSz = getByteArrayLength(env, data_object);
|
||||
actualKeySz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (macSz < 0 || dataSz < 0 || keySz < 0 ||
|
||||
(word32)macSz > actualMacSz ||
|
||||
|
|
@ -405,6 +410,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1AesCmacVerify(
|
|||
|
||||
releaseByteArray(env, mac_object, mac, JNI_ABORT);
|
||||
releaseByteArray(env, data_object, data, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(key, actualKeySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesGcm_wc_1AesGcmSetKey
|
|||
Aes* aes = NULL;
|
||||
const byte* key = NULL;
|
||||
word32 keyLen = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
aes = (Aes*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -125,7 +126,8 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesGcm_wc_1AesGcmSetKey
|
|||
}
|
||||
|
||||
if (keyArr != NULL) {
|
||||
key = (const byte*)(*env)->GetByteArrayElements(env, keyArr, NULL);
|
||||
key = (const byte*)(*env)->GetByteArrayElements(env, keyArr,
|
||||
&keyIsCopy);
|
||||
keyLen = (*env)->GetArrayLength(env, keyArr);
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +140,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesGcm_wc_1AesGcmSetKey
|
|||
}
|
||||
|
||||
if (keyArr != NULL) {
|
||||
zeroizeByteArrayCopy((byte*)key, keyLen, keyIsCopy);
|
||||
(*env)->ReleaseByteArrayElements(env, keyArr, (jbyte*)key, JNI_ABORT);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1GmacSetKey(
|
|||
Gmac* gmac = NULL;
|
||||
byte* key = NULL;
|
||||
word32 keySz = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
gmac = (Gmac*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -118,7 +119,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1GmacSetKey(
|
|||
return;
|
||||
}
|
||||
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (!gmac || !key) {
|
||||
|
|
@ -133,6 +134,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1GmacSetKey(
|
|||
|
||||
LogStr("wc_GmacSetKey(gmac=%p, key, %d) = %d\n", gmac, keySz, ret);
|
||||
|
||||
zeroizeByteArrayCopy(key, keySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
@ -220,8 +222,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1Gmac(
|
|||
byte* authIn = NULL;
|
||||
byte* authTag = NULL;
|
||||
word32 keySz = 0, ivSz = 0, authInSz = 0, authTagSz = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
iv = getByteArray(env, iv_object);
|
||||
authIn = getByteArray(env, authIn_object);
|
||||
authTag = getByteArray(env, authTag_object);
|
||||
|
|
@ -234,7 +238,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1Gmac(
|
|||
}
|
||||
|
||||
if (ret == 0) {
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
ivSz = getByteArrayLength(env, iv_object);
|
||||
authInSz = getByteArrayLength(env, authIn_object);
|
||||
authTagSz = getByteArrayLength(env, authTag_object);
|
||||
|
|
@ -269,6 +272,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1Gmac(
|
|||
"authInSz=%d, authTag=%p, authTagSz=%d, ret=%d\n",
|
||||
key, keySz, iv, ivSz, authIn, authInSz, authTag, authTagSz, ret);
|
||||
|
||||
zeroizeByteArrayCopy(key, keySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
releaseByteArray(env, iv_object, iv, JNI_ABORT);
|
||||
releaseByteArray(env, authIn_object, authIn, JNI_ABORT);
|
||||
|
|
@ -295,8 +299,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1GmacVerify(
|
|||
byte* authIn = NULL;
|
||||
byte* authTag = NULL;
|
||||
word32 keySz = 0, ivSz = 0, authInSz = 0, authTagSz = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
iv = getByteArray(env, iv_object);
|
||||
authIn = getByteArray(env, authIn_object);
|
||||
authTag = getByteArray(env, authTag_object);
|
||||
|
|
@ -309,7 +315,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1GmacVerify(
|
|||
}
|
||||
|
||||
if (ret == 0) {
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
ivSz = getByteArrayLength(env, iv_object);
|
||||
authInSz = getByteArrayLength(env, authIn_object);
|
||||
authTagSz = getByteArrayLength(env, authTag_object);
|
||||
|
|
@ -344,6 +349,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_AesGmac_wc_1GmacVerify(
|
|||
"authInSz=%d, authTag=%p, authTagSz=%d, ret=%d\n",
|
||||
key, keySz, iv, ivSz, authIn, authInSz, authTag, authTagSz, ret);
|
||||
|
||||
zeroizeByteArrayCopy(key, keySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
releaseByteArray(env, iv_object, iv, JNI_ABORT);
|
||||
releaseByteArray(env, authIn_object, authIn, JNI_ABORT);
|
||||
|
|
|
|||
|
|
@ -159,13 +159,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Curve25519_wc_1curve25519_1imp
|
|||
byte* priv = NULL;
|
||||
byte* pub = NULL;
|
||||
word32 privSz = 0, pubSz = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
curve25519 = (curve25519_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
/* getNativeStruct may throw exception, prevent throwing another */
|
||||
return;
|
||||
}
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
pub = getByteArray(env, pub_object);
|
||||
pubSz = getByteArrayLength(env, pub_object);
|
||||
|
|
@ -184,6 +185,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Curve25519_wc_1curve25519_1imp
|
|||
|
||||
LogStr("wc_curve25519_import_private_key(curve25519=%p) = %d\n", curve25519, ret);
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
releaseByteArray(env, pub_object, pub, JNI_ABORT);
|
||||
#else
|
||||
|
|
@ -199,13 +201,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Curve25519_wc_1curve25519_1imp
|
|||
curve25519_key* curve25519 = NULL;
|
||||
byte* priv = NULL;
|
||||
word32 privSz = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
curve25519 = (curve25519_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
/* getNativeStruct may throw exception, prevent throwing another */
|
||||
return;
|
||||
}
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
|
||||
/* pub may be null if only importing private key */
|
||||
|
|
@ -221,6 +224,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Curve25519_wc_1curve25519_1imp
|
|||
|
||||
LogStr("wc_curve25519_import_private_key(curve25519=%p) = %d\n", curve25519, ret);
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ Java_com_wolfssl_wolfcrypt_Des3_native_1set_1key_1internal(
|
|||
Des3* des = NULL;
|
||||
byte* key = NULL;
|
||||
byte* iv = NULL;
|
||||
word32 keySz = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
des = (Des3*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -76,7 +78,8 @@ Java_com_wolfssl_wolfcrypt_Des3_native_1set_1key_1internal(
|
|||
return;
|
||||
}
|
||||
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
iv = getByteArray(env, iv_object);
|
||||
|
||||
ret = (!des || !key) /* iv is optional */
|
||||
|
|
@ -88,6 +91,7 @@ Java_com_wolfssl_wolfcrypt_Des3_native_1set_1key_1internal(
|
|||
|
||||
LogStr("wc_Des3SetKey(Des3=%p, key, iv, opmode) = %d\n", des, ret);
|
||||
|
||||
zeroizeByteArrayCopy(key, keySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
releaseByteArray(env, iv_object, iv, JNI_ABORT);
|
||||
#else
|
||||
|
|
|
|||
14
jni/jni_dh.c
14
jni/jni_dh.c
|
|
@ -29,6 +29,7 @@
|
|||
#include <wolfssl/version.h>
|
||||
#include <wolfssl/wolfcrypt/dh.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
#include <wolfssl/wolfcrypt/memory.h>
|
||||
|
||||
#include <com_wolfssl_wolfcrypt_Dh.h>
|
||||
#include <wolfcrypt_jni_NativeStruct.h>
|
||||
|
|
@ -399,6 +400,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
byte* pub = NULL;
|
||||
byte* secret = NULL;
|
||||
word32 privSz = 0, pubSz = 0, secretSz = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
key = (DhKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -406,7 +408,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
pub = getByteArray(env, pub_object);
|
||||
pubSz = getByteArrayLength(env, pub_object);
|
||||
|
|
@ -420,6 +422,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
throwOutOfMemoryException(
|
||||
env, "Failed to allocate shared secret buffer");
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
releaseByteArray(env, pub_object, pub, JNI_ABORT);
|
||||
|
||||
|
|
@ -464,6 +467,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree(
|
|||
XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
releaseByteArray(env, pub_object, pub, JNI_ABORT);
|
||||
#else
|
||||
|
|
@ -783,6 +787,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhImportKeyPair(
|
|||
byte* p = NULL;
|
||||
byte* g = NULL;
|
||||
word32 privSz = 0, pubSz = 0, pSz = 0, gSz = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
key = (DhKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -814,7 +819,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhImportKeyPair(
|
|||
if (ret == 0) {
|
||||
/* Get private key if provided */
|
||||
if (priv_object != NULL) {
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
}
|
||||
|
||||
|
|
@ -835,6 +840,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhImportKeyPair(
|
|||
releaseByteArray(env, p_object, p, JNI_ABORT);
|
||||
releaseByteArray(env, g_object, g, JNI_ABORT);
|
||||
if (priv_object != NULL) {
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
}
|
||||
if (pub_object != NULL) {
|
||||
|
|
@ -1126,6 +1132,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhPrivateKeyDecode(
|
|||
byte* pkcs8 = NULL;
|
||||
word32 pkcs8Sz = 0;
|
||||
word32 idx = 0;
|
||||
jboolean pkcs8IsCopy = JNI_FALSE;
|
||||
|
||||
key = (DhKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -1138,7 +1145,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhPrivateKeyDecode(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pkcs8 = getByteArray(env, pkcs8_object);
|
||||
pkcs8 = getByteArrayIsCopy(env, pkcs8_object, &pkcs8IsCopy);
|
||||
pkcs8Sz = getByteArrayLength(env, pkcs8_object);
|
||||
|
||||
if (pkcs8 == NULL) {
|
||||
|
|
@ -1166,6 +1173,7 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhPrivateKeyDecode(
|
|||
|
||||
LogStr("wc_DhKeyDecode(pkcs8=%p, key=%p) = %d\n", pkcs8, key, ret);
|
||||
|
||||
zeroizeByteArrayCopy(pkcs8, pkcs8Sz, pkcs8IsCopy);
|
||||
releaseByteArray(env, pkcs8_object, pkcs8, JNI_ABORT);
|
||||
|
||||
if (ret != 0) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <wolfssl/version.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#include <wolfssl/wolfcrypt/memory.h>
|
||||
|
||||
#include <com_wolfssl_wolfcrypt_Ecc.h>
|
||||
#include <wolfcrypt_jni_NativeStruct.h>
|
||||
|
|
@ -304,6 +305,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1import_1private
|
|||
byte* pub = NULL;
|
||||
word32 privSz = 0, pubSz = 0;
|
||||
const char* name = NULL;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
ecc = (ecc_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -311,7 +313,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1import_1private
|
|||
return;
|
||||
}
|
||||
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
pub = getByteArray(env, pub_object);
|
||||
pubSz = getByteArrayLength(env, pub_object);
|
||||
|
|
@ -360,6 +362,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1import_1private
|
|||
|
||||
LogStr("wc_ecc_import_private_key(ecc=%p) = %d\n", ecc, ret);
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
releaseByteArray(env, pub_object, pub, JNI_ABORT);
|
||||
#else
|
||||
|
|
@ -569,6 +572,7 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1EccPrivateKeyDecode(
|
|||
ecc_key* ecc = NULL;
|
||||
byte* key = NULL;
|
||||
word32 keySz = 0;
|
||||
jboolean keyIsCopy = JNI_FALSE;
|
||||
|
||||
ecc = (ecc_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -576,7 +580,7 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1EccPrivateKeyDecode(
|
|||
return;
|
||||
}
|
||||
|
||||
key = getByteArray(env, key_object);
|
||||
key = getByteArrayIsCopy(env, key_object, &keyIsCopy);
|
||||
keySz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (ecc == NULL || key == NULL) {
|
||||
|
|
@ -593,6 +597,7 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1EccPrivateKeyDecode(
|
|||
LogStr("wc_EccPrivateKeyDecode(key=%p, keySz=%d, ecc=%p) = %d\n",
|
||||
key, (int)keySz, ecc, ret);
|
||||
|
||||
zeroizeByteArrayCopy(key, keySz, keyIsCopy);
|
||||
releaseByteArray(env, key_object, key, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
@ -1439,6 +1444,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1import_1private_1
|
|||
word32 privKeySz = 0;
|
||||
const char* name = NULL;
|
||||
int curveId = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
ecc = (ecc_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -1446,7 +1452,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1import_1private_1
|
|||
return;
|
||||
}
|
||||
|
||||
privKey = getByteArray(env, priv_object);
|
||||
privKey = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privKeySz = getByteArrayLength(env, priv_object);
|
||||
|
||||
if (ecc == NULL || privKey == NULL || curveName == NULL) {
|
||||
|
|
@ -1481,6 +1487,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1import_1private_1
|
|||
LogStr("wc_ecc_import_unsigned(ecc=%p, privKey=%p) = %d\n",
|
||||
ecc, privKey, ret);
|
||||
|
||||
zeroizeByteArrayCopy(privKey, privKeySz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, privKey, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
|
|||
|
|
@ -186,13 +186,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ed25519_wc_1ed25519_1import_1p
|
|||
byte* priv = NULL;
|
||||
byte* pub = NULL;
|
||||
word32 privSz = 0, pubSz = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
ed25519 = (ed25519_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
/* getNativeStruct may throw exception, prevent throwing another */
|
||||
return;
|
||||
}
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
pub = getByteArray(env, pub_object);
|
||||
pubSz = getByteArrayLength(env, pub_object);
|
||||
|
|
@ -214,6 +215,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ed25519_wc_1ed25519_1import_1p
|
|||
|
||||
LogStr("wc_ed25519_import_private_key(ed25519=%p) = %d\n", ed25519, ret);
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
releaseByteArray(env, pub_object, pub, JNI_ABORT);
|
||||
#else
|
||||
|
|
@ -263,13 +265,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ed25519_wc_1ed25519_1import_1p
|
|||
ed25519_key* ed25519 = NULL;
|
||||
byte* priv = NULL;
|
||||
word32 privSz = 0;
|
||||
jboolean privIsCopy = JNI_FALSE;
|
||||
|
||||
ed25519 = (ed25519_key*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
/* getNativeStruct may throw exception, prevent throwing another */
|
||||
return;
|
||||
}
|
||||
priv = getByteArray(env, priv_object);
|
||||
priv = getByteArrayIsCopy(env, priv_object, &privIsCopy);
|
||||
privSz = getByteArrayLength(env, priv_object);
|
||||
|
||||
if (!ed25519 || !priv) {
|
||||
|
|
@ -284,6 +287,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Ed25519_wc_1ed25519_1import_1p
|
|||
|
||||
LogStr("wc_ed25519_import_private_key(ed25519=%p) = %d\n", ed25519, ret);
|
||||
|
||||
zeroizeByteArrayCopy(priv, privSz, privIsCopy);
|
||||
releaseByteArray(env, priv_object, priv, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
#elif !defined(__ANDROID__)
|
||||
#include <wolfssl/options.h>
|
||||
#endif
|
||||
#include <wolfssl/version.h>
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
#include <wolfssl/wolfcrypt/memory.h>
|
||||
|
||||
#include <com_wolfssl_wolfcrypt_NativeStruct.h>
|
||||
#include <wolfcrypt_jni_NativeStruct.h>
|
||||
|
|
@ -207,6 +209,31 @@ byte* getByteArray(JNIEnv* env, jbyteArray array)
|
|||
return array ? (byte*)(*env)->GetByteArrayElements(env, array, NULL) : NULL;
|
||||
}
|
||||
|
||||
/* Same as getByteArray() but also returns the JNI isCopy flag. Flag is
|
||||
* set to JNI_FALSE first so it is defined even when array is NULL */
|
||||
byte* getByteArrayIsCopy(JNIEnv* env, jbyteArray array, jboolean* isCopy)
|
||||
{
|
||||
if (isCopy != NULL) {
|
||||
*isCopy = JNI_FALSE;
|
||||
}
|
||||
return array ?
|
||||
(byte*)(*env)->GetByteArrayElements(env, array, isCopy) : NULL;
|
||||
}
|
||||
|
||||
/* Zeroize native copy of a sensitive array before JNI_ABORT release.
|
||||
* Skip pinned arrays, they alias the caller's live Java array */
|
||||
void zeroizeByteArrayCopy(byte* buf, word32 sz, jboolean isCopy)
|
||||
{
|
||||
if (buf != NULL && isCopy == JNI_TRUE) {
|
||||
#if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \
|
||||
!defined(WOLFSSL_NO_FORCE_ZERO)
|
||||
wc_ForceZero(buf, sz);
|
||||
#else
|
||||
XMEMSET(buf, 0, sz);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void releaseByteArray(JNIEnv* env, jbyteArray array, byte* elements, jint abort)
|
||||
{
|
||||
if ((env != NULL) && (array != NULL) && (elements != NULL)) {
|
||||
|
|
|
|||
|
|
@ -760,6 +760,7 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecode(
|
|||
RsaKey* key = NULL;
|
||||
byte* k = NULL;
|
||||
word32 kSz = 0, index = 0;
|
||||
jboolean kIsCopy = JNI_FALSE;
|
||||
|
||||
key = (RsaKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -767,7 +768,7 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecode(
|
|||
return;
|
||||
}
|
||||
|
||||
k = getByteArray(env, key_object);
|
||||
k = getByteArrayIsCopy(env, key_object, &kIsCopy);
|
||||
kSz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (key == NULL || k == NULL) {
|
||||
|
|
@ -785,6 +786,7 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecode(
|
|||
LogStr("key[%u]: [%p]\n", (word32)kSz, k);
|
||||
LogHex((byte*) k, 0, kSz);
|
||||
|
||||
zeroizeByteArrayCopy(k, kSz, kIsCopy);
|
||||
releaseByteArray(env, key_object, k, JNI_ABORT);
|
||||
|
||||
#else
|
||||
|
|
@ -801,6 +803,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecodePKC
|
|||
RsaKey* key = NULL;
|
||||
byte* k = NULL;
|
||||
word32 kSz = 0, offset = 0;
|
||||
jboolean kIsCopy = JNI_FALSE;
|
||||
|
||||
key = (RsaKey*) getNativeStruct(env, this);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
|
|
@ -808,7 +811,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecodePKC
|
|||
return;
|
||||
}
|
||||
|
||||
k = getByteArray(env, key_object);
|
||||
k = getByteArrayIsCopy(env, key_object, &kIsCopy);
|
||||
kSz = getByteArrayLength(env, key_object);
|
||||
|
||||
if (key == NULL || k == NULL) {
|
||||
|
|
@ -834,6 +837,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyDecodePKC
|
|||
LogStr("key[%u]: [%p]\n", (word32)kSz, k);
|
||||
LogHex((byte*) k, 0, kSz);
|
||||
|
||||
zeroizeByteArrayCopy(k, kSz, kIsCopy);
|
||||
releaseByteArray(env, key_object, k, JNI_ABORT);
|
||||
#else
|
||||
throwNotCompiledInException(env);
|
||||
|
|
@ -2160,6 +2164,12 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaImportCrtKey(
|
|||
byte* u = NULL;
|
||||
word32 nSz = 0, eSz = 0, dSz = 0, pSz = 0;
|
||||
word32 qSz = 0, dPSz = 0, dQSz = 0, uSz = 0;
|
||||
jboolean dIsCopy = JNI_FALSE;
|
||||
jboolean pIsCopy = JNI_FALSE;
|
||||
jboolean qIsCopy = JNI_FALSE;
|
||||
jboolean dPIsCopy = JNI_FALSE;
|
||||
jboolean dQIsCopy = JNI_FALSE;
|
||||
jboolean uIsCopy = JNI_FALSE;
|
||||
|
||||
#ifndef WOLFSSL_PUBLIC_MP
|
||||
ret = NOT_COMPILED_IN;
|
||||
|
|
@ -2179,22 +2189,22 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaImportCrtKey(
|
|||
e = getByteArray(env, e_object);
|
||||
eSz = getByteArrayLength(env, e_object);
|
||||
|
||||
d = getByteArray(env, d_object);
|
||||
d = getByteArrayIsCopy(env, d_object, &dIsCopy);
|
||||
dSz = getByteArrayLength(env, d_object);
|
||||
|
||||
p = getByteArray(env, p_object);
|
||||
p = getByteArrayIsCopy(env, p_object, &pIsCopy);
|
||||
pSz = getByteArrayLength(env, p_object);
|
||||
|
||||
q = getByteArray(env, q_object);
|
||||
q = getByteArrayIsCopy(env, q_object, &qIsCopy);
|
||||
qSz = getByteArrayLength(env, q_object);
|
||||
|
||||
dP = getByteArray(env, dP_object);
|
||||
dP = getByteArrayIsCopy(env, dP_object, &dPIsCopy);
|
||||
dPSz = getByteArrayLength(env, dP_object);
|
||||
|
||||
dQ = getByteArray(env, dQ_object);
|
||||
dQ = getByteArrayIsCopy(env, dQ_object, &dQIsCopy);
|
||||
dQSz = getByteArrayLength(env, dQ_object);
|
||||
|
||||
u = getByteArray(env, u_object);
|
||||
u = getByteArrayIsCopy(env, u_object, &uIsCopy);
|
||||
uSz = getByteArrayLength(env, u_object);
|
||||
|
||||
/* Validate inputs */
|
||||
|
|
@ -2252,15 +2262,21 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaImportCrtKey(
|
|||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
|
||||
/* Release all byte arrays */
|
||||
releaseByteArray(env, n_object, n, ret);
|
||||
releaseByteArray(env, e_object, e, ret);
|
||||
releaseByteArray(env, d_object, d, ret);
|
||||
releaseByteArray(env, p_object, p, ret);
|
||||
releaseByteArray(env, q_object, q, ret);
|
||||
releaseByteArray(env, dP_object, dP, ret);
|
||||
releaseByteArray(env, dQ_object, dQ, ret);
|
||||
releaseByteArray(env, u_object, u, ret);
|
||||
/* Release all byte arrays, zeroize private components */
|
||||
releaseByteArray(env, n_object, n, JNI_ABORT);
|
||||
releaseByteArray(env, e_object, e, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(d, dSz, dIsCopy);
|
||||
releaseByteArray(env, d_object, d, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(p, pSz, pIsCopy);
|
||||
releaseByteArray(env, p_object, p, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(q, qSz, qIsCopy);
|
||||
releaseByteArray(env, q_object, q, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(dP, dPSz, dPIsCopy);
|
||||
releaseByteArray(env, dP_object, dP, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(dQ, dQSz, dQIsCopy);
|
||||
releaseByteArray(env, dQ_object, dQ, JNI_ABORT);
|
||||
zeroizeByteArrayCopy(u, uSz, uIsCopy);
|
||||
releaseByteArray(env, u_object, u, JNI_ABORT);
|
||||
#else
|
||||
(void)env;
|
||||
(void)this;
|
||||
|
|
|
|||
|
|
@ -735,6 +735,92 @@ public class RsaTest {
|
|||
key.releaseNativeStruct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Native wc_RsaImportCrtKey zeroizes its component copies and must
|
||||
* release with JNI_ABORT.
|
||||
*/
|
||||
@Test
|
||||
public void importRawPrivateKeyShouldNotModifyCallerArrays() {
|
||||
|
||||
Rsa genKey = makeKeyWithRetry(2048, 65537, rng);
|
||||
|
||||
int bufSz = 512;
|
||||
byte[] n = new byte[bufSz];
|
||||
byte[] e = new byte[bufSz];
|
||||
byte[] d = new byte[bufSz];
|
||||
byte[] p = new byte[bufSz];
|
||||
byte[] q = new byte[bufSz];
|
||||
byte[] dP = new byte[bufSz];
|
||||
byte[] dQ = new byte[bufSz];
|
||||
byte[] u = new byte[bufSz];
|
||||
long[] nSz = { bufSz };
|
||||
long[] eSz = { bufSz };
|
||||
long[] dSz = { bufSz };
|
||||
long[] pSz = { bufSz };
|
||||
long[] qSz = { bufSz };
|
||||
long[] dPSz = { bufSz };
|
||||
long[] dQSz = { bufSz };
|
||||
long[] uSz = { bufSz };
|
||||
|
||||
try {
|
||||
genKey.exportRawPrivateKey(n, nSz, e, eSz, d, dSz, p, pSz, q,
|
||||
qSz, dP, dPSz, dQ, dQSz, u, uSz);
|
||||
} catch (WolfCryptException ex) {
|
||||
genKey.releaseNativeStruct();
|
||||
Assume.assumeTrue("raw export not compiled in native wolfSSL",
|
||||
ex.getError() != WolfCryptError.NOT_COMPILED_IN);
|
||||
throw ex;
|
||||
}
|
||||
genKey.releaseNativeStruct();
|
||||
|
||||
/* importRawPrivateKey must not modify any caller component array */
|
||||
byte[] nIn = Arrays.copyOf(n, (int)nSz[0]);
|
||||
byte[] eIn = Arrays.copyOf(e, (int)eSz[0]);
|
||||
byte[] dIn = Arrays.copyOf(d, (int)dSz[0]);
|
||||
byte[] pIn = Arrays.copyOf(p, (int)pSz[0]);
|
||||
byte[] qIn = Arrays.copyOf(q, (int)qSz[0]);
|
||||
byte[] dPIn = Arrays.copyOf(dP, (int)dPSz[0]);
|
||||
byte[] dQIn = Arrays.copyOf(dQ, (int)dQSz[0]);
|
||||
byte[] uIn = Arrays.copyOf(u, (int)uSz[0]);
|
||||
byte[] nCopy = nIn.clone();
|
||||
byte[] eCopy = eIn.clone();
|
||||
byte[] dCopy = dIn.clone();
|
||||
byte[] pCopy = pIn.clone();
|
||||
byte[] qCopy = qIn.clone();
|
||||
byte[] dPCopy = dPIn.clone();
|
||||
byte[] dQCopy = dQIn.clone();
|
||||
byte[] uCopy = uIn.clone();
|
||||
|
||||
Rsa rawKey = new Rsa();
|
||||
try {
|
||||
rawKey.importRawPrivateKey(nIn, eIn, dIn, pIn, qIn, dPIn,
|
||||
dQIn, uIn);
|
||||
|
||||
assertArrayEquals("importRawPrivateKey must not modify n",
|
||||
nCopy, nIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify e",
|
||||
eCopy, eIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify d",
|
||||
dCopy, dIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify p",
|
||||
pCopy, pIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify q",
|
||||
qCopy, qIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify dP",
|
||||
dPCopy, dPIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify dQ",
|
||||
dQCopy, dQIn);
|
||||
assertArrayEquals("importRawPrivateKey must not modify u",
|
||||
uCopy, uIn);
|
||||
} catch (WolfCryptException ex) {
|
||||
Assume.assumeTrue("raw import not compiled in native wolfSSL",
|
||||
ex.getError() != WolfCryptError.NOT_COMPILED_IN);
|
||||
throw ex;
|
||||
} finally {
|
||||
rawKey.releaseNativeStruct();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rsaOperations() {
|
||||
Rsa priv = new Rsa();
|
||||
|
|
|
|||
Loading…
Reference in New Issue