diff --git a/jni/include/com_wolfssl_wolfcrypt_Fips.h b/jni/include/com_wolfssl_wolfcrypt_Fips.h index cfae770..2866b74 100644 --- a/jni/include/com_wolfssl_wolfcrypt_Fips.h +++ b/jni/include/com_wolfssl_wolfcrypt_Fips.h @@ -7,6 +7,14 @@ #ifdef __cplusplus extern "C" { #endif +/* + * Class: com_wolfssl_wolfcrypt_Fips + * Method: setErrorCallback + * Signature: (Lcom/wolfssl/wolfcrypt/Fips/ErrorCallback;)V + */ +JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Fips_setErrorCallback + (JNIEnv *, jclass, jobject); + /* * Class: com_wolfssl_wolfcrypt_Fips * Method: AesSetKey_fips diff --git a/jni/include/com_wolfssl_wolfcrypt_Fips_ErrorCallback.h b/jni/include/com_wolfssl_wolfcrypt_Fips_ErrorCallback.h new file mode 100644 index 0000000..f81ae8a --- /dev/null +++ b/jni/include/com_wolfssl_wolfcrypt_Fips_ErrorCallback.h @@ -0,0 +1,13 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_wolfssl_wolfcrypt_Fips_ErrorCallback */ + +#ifndef _Included_com_wolfssl_wolfcrypt_Fips_ErrorCallback +#define _Included_com_wolfssl_wolfcrypt_Fips_ErrorCallback +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/jni_asn.c b/jni/jni_asn.c index 720bb43..9f3f388 100644 --- a/jni/jni_asn.c +++ b/jni/jni_asn.c @@ -20,9 +20,9 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Asn_encodeSignature( if (!encoded || !hash) throwWolfCryptException(env, "Bad method argument provided"); - - setDirectBufferLimit(env, encoded_object, - wc_EncodeSignature(encoded, hash, hashSize, hashOID)); + else + setDirectBufferLimit(env, encoded_object, + wc_EncodeSignature(encoded, hash, hashSize, hashOID)); } JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getCTC_1HashOID( diff --git a/jni/jni_fips.c b/jni/jni_fips.c index c1e4ca9..e5266c7 100644 --- a/jni/jni_fips.c +++ b/jni/jni_fips.c @@ -1,11 +1,13 @@ #include #include #include +#include #ifndef __ANDROID__ #include #endif +#include #include #include #include @@ -22,6 +24,54 @@ /* #define WOLFCRYPT_JNI_DEBUG_ON */ #include +extern JavaVM* g_vm; +static jobject g_errCb; + +void NativeErrorCallback(const int ok, const int err, const char * const hash) +{ + JNIEnv* env; + jclass class; + jmethodID method; + jint ret; + + ret = (int) ((*g_vm)->GetEnv(g_vm, (void**) &env, JNI_VERSION_1_6)); + if (ret == JNI_EDETACHED) { +#ifdef __ANDROID__ + ret = (*g_vm)->AttachCurrentThread(g_vm, &env, NULL); +#else + ret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &env, NULL); +#endif + if (ret) { + printf("Failed to attach JNIEnv to thread\n"); + return; + } + } + else if (ret != JNI_OK) { + printf("Unable to get JNIEnv from JavaVM\n"); + return; + } + + if (JNIGlobalRefType != (*env)->GetObjectRefType(env, g_errCb)) + throwWolfCryptException(env, "Invalid errorCallback reference"); + else if (!(class = (*env)->GetObjectClass(env, g_errCb))) + throwWolfCryptException(env, "Failed to get callback class"); + else if (!(method = (*env)->GetMethodID(env, class, "errorCallback", + "(IILjava/lang/String;)V"))) + throwWolfCryptException(env, "Failed to get method ID"); + else + (*env)->CallVoidMethod(env, g_errCb, method, ok, err, + (*env)->NewStringUTF(env, hash)); +} + +JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Fips_setErrorCallback( + JNIEnv* env, jclass class, jobject callback) +{ + if ((g_errCb = (*env)->NewGlobalRef(env, callback))) + wolfCrypt_SetCb_fips(NativeErrorCallback); + else + throwWolfCryptException(env, "Failed to store global error callback"); +} + /* * ### FIPS Aprooved Security Methods ########################################## */ diff --git a/jni/jni_native_struct.c b/jni/jni_native_struct.c index 02da2ed..34c4783 100644 --- a/jni/jni_native_struct.c +++ b/jni/jni_native_struct.c @@ -12,6 +12,16 @@ #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" +JavaVM* g_vm = NULL; + +/* called when native library is loaded */ +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + /* store JavaVM */ + g_vm = vm; + return JNI_VERSION_1_6; +} + JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_NativeStruct_xfree( JNIEnv* env, jobject this, jlong ptr) { diff --git a/jni/jni_rsa.c b/jni/jni_rsa.c index b8ac6f2..780ad04 100644 --- a/jni/jni_rsa.c +++ b/jni/jni_rsa.c @@ -46,8 +46,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Rsa_decodeRawPublicKey( if (!key || !n || !e) throwWolfCryptException(env, "Bad method argument provided"); - - if (wc_RsaPublicKeyDecodeRaw(n, nSize, e, eSize, key) != 0) + else if (wc_RsaPublicKeyDecodeRaw(n, nSize, e, eSize, key) != 0) throwWolfCryptException(env, "Failed to decode raw public key"); #endif diff --git a/src/java/com/wolfssl/wolfcrypt/Fips.java b/src/java/com/wolfssl/wolfcrypt/Fips.java index 2c4d9a5..83d8a7e 100644 --- a/src/java/com/wolfssl/wolfcrypt/Fips.java +++ b/src/java/com/wolfssl/wolfcrypt/Fips.java @@ -15,6 +15,12 @@ public class Fips extends WolfObject { private Fips() { } + public interface ErrorCallback { + public void errorCallback(int ok, int err, String hash); + } + + public static native void setErrorCallback(ErrorCallback callback); + /* * ### FIPS Aprooved Security Methods ###################################### */ diff --git a/src/test/com/wolfssl/wolfcrypt/fips/ErrorCallbackFipsTest.java b/src/test/com/wolfssl/wolfcrypt/fips/ErrorCallbackFipsTest.java new file mode 100644 index 0000000..ece3d53 --- /dev/null +++ b/src/test/com/wolfssl/wolfcrypt/fips/ErrorCallbackFipsTest.java @@ -0,0 +1,40 @@ +package com.wolfssl.wolfcrypt.fips; + +import java.nio.ByteBuffer; + +import org.junit.Test; + +import com.wolfssl.wolfcrypt.Fips.ErrorCallback; +import com.wolfssl.wolfcrypt.Aes; +import com.wolfssl.wolfcrypt.Fips; + +public class ErrorCallbackFipsTest { + + public class MyCallback implements ErrorCallback { + @Override + public void errorCallback(int ok, int err, String hash) { + System.out.println("in my Fips callback, ok =" + ok + " err = " + + err); + System.out.println("hash = " + hash); + + if (err == -203) { + System.out + .println("In core integrity hash check failure, copy above hash"); + System.out + .println("into verifyCore[] in fips_test.c and rebuild"); + } + } + + } + + @Test + public void setErrorCallbackShouldNotRaise() { + MyCallback callback = new MyCallback(); + + Fips.setErrorCallback(callback); + + Fips.AesSetKey_fips(new Aes(), + ByteBuffer.allocateDirect(Aes.KEY_SIZE_256), Aes.KEY_SIZE_128, + null, Aes.ENCRYPT_MODE); + } +}