2626#include <wolfssl/wolfcrypt/logging.h>
2727#include <wolfssl/wolfcrypt/hmac.h>
2828#include <wolfssl/wolfcrypt/asn_public.h>
29+ #ifdef HAVE_FIPS
30+ #include <wolfssl/wolfcrypt/fips_test.h>
31+ #endif
2932
3033#include "com_wolfssl_globals.h"
3134#include "com_wolfssl_WolfSSL.h"
@@ -36,6 +39,11 @@ JavaVM* g_vm;
3639/* global object refs for logging callbacks */
3740static jobject g_loggingCbIfaceObj ;
3841
42+ #ifdef HAVE_FIPS
43+ /* global object ref for FIPS error callback */
44+ static jobject g_fipsCbIfaceObj ;
45+ #endif
46+
3947/* custom native fn prototypes */
4048void NativeLoggingCallback (const int logLevel , const char * const logMessage );
4149
@@ -678,6 +686,141 @@ void NativeLoggingCallback(const int logLevel, const char *const logMessage)
678686 }
679687}
680688
689+ void NativeFIPSErrorCallback (const int ok , const int err ,
690+ const char * const hash )
691+ {
692+ #ifdef HAVE_FIPS
693+ JNIEnv * jenv ;
694+ jint vmret = 0 ;
695+ jclass excClass ;
696+ jmethodID errorMethod ;
697+ jobjectRefType refcheck ;
698+
699+ /* get JNIEnv from JavaVM */
700+ vmret = (int )((* g_vm )-> GetEnv (g_vm , (void * * ) & jenv , JNI_VERSION_1_6 ));
701+ if (vmret == JNI_EDETACHED ) {
702+ #ifdef __ANDROID__
703+ vmret = (* g_vm )-> AttachCurrentThread (g_vm , & jenv , NULL );
704+ #else
705+ vmret = (* g_vm )-> AttachCurrentThread (g_vm , (void * * ) & jenv , NULL );
706+ #endif
707+ if (vmret ) {
708+ printf ("Failed to attach JNIEnv to thread\n" );
709+ }
710+ } else if (vmret != JNI_OK ) {
711+ printf ("Unable to get JNIEnv from JavaVM\n" );
712+ }
713+
714+ /* find exception class */
715+ excClass = (* jenv )-> FindClass (jenv , "java/lang/Exception" );
716+ if ((* jenv )-> ExceptionOccurred (jenv )) {
717+ (* jenv )-> ExceptionDescribe (jenv );
718+ (* jenv )-> ExceptionClear (jenv );
719+ return ;
720+ }
721+
722+ /* check if our stored object reference is valid */
723+ refcheck = (* jenv )-> GetObjectRefType (jenv , g_fipsCbIfaceObj );
724+ if (refcheck == JNIGlobalRefType ) {
725+
726+ /* lookup WolfSSLLoggingCallback class from global object ref */
727+ jclass fipsCbClass = (* jenv )-> GetObjectClass (jenv , g_fipsCbIfaceObj );
728+ if (!fipsCbClass ) {
729+ if ((* jenv )-> ExceptionOccurred (jenv )) {
730+ (* jenv )-> ExceptionDescribe (jenv );
731+ (* jenv )-> ExceptionClear (jenv );
732+ }
733+
734+ (* jenv )-> ThrowNew (jenv , excClass ,
735+ "Can't get native WolfSSLFIPSErrorCallback class reference" );
736+ return ;
737+ }
738+
739+ errorMethod = (* jenv )-> GetMethodID (jenv , fipsCbClass ,
740+ "errorCallback" ,
741+ "(IILjava/lang/String;)V" );
742+ if (errorMethod == 0 ) {
743+ if ((* jenv )-> ExceptionOccurred (jenv )) {
744+ (* jenv )-> ExceptionDescribe (jenv );
745+ (* jenv )-> ExceptionClear (jenv );
746+ }
747+ (* jenv )-> ThrowNew (jenv , excClass ,
748+ "Error getting errorCallback method from JNI" );
749+ return ;
750+ }
751+
752+ /* create jstring from char* */
753+ jstring hashString = (* jenv )-> NewStringUTF (jenv , hash );
754+
755+ (* jenv )-> CallVoidMethod (jenv , g_fipsCbIfaceObj , errorMethod ,
756+ ok , err , hashString );
757+
758+ /* release local reference to jstring, since returning to native */
759+ (* jenv )-> DeleteLocalRef (jenv , hashString );
760+
761+ if ((* jenv )-> ExceptionOccurred (jenv )) {
762+ (* jenv )-> ExceptionDescribe (jenv );
763+ (* jenv )-> ExceptionClear (jenv );
764+
765+ (* jenv )-> ThrowNew (jenv , excClass ,
766+ "Error calling FIPS error callback from JNI" );
767+ return ;
768+ }
769+
770+ } else {
771+ if ((* jenv )-> ExceptionOccurred (jenv )) {
772+ (* jenv )-> ExceptionDescribe (jenv );
773+ (* jenv )-> ExceptionClear (jenv );
774+ }
775+
776+ (* jenv )-> ThrowNew (jenv , excClass ,
777+ "Object reference invalid in NativeFIPSErrorCallback" );
778+ }
779+ #endif
780+ }
781+
782+ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_setFIPSCb
783+ (JNIEnv * jenv , jclass jcl , jobject callback )
784+ {
785+ int ret = NOT_COMPILED_IN ;
786+ (void )jcl ;
787+
788+ #ifdef HAVE_FIPS
789+ if (jenv == NULL || callback == NULL ) {
790+ return BAD_FUNC_ARG ;
791+ }
792+
793+ /* store Java FIPS callback Interface object */
794+ g_fipsCbIfaceObj = (* jenv )-> NewGlobalRef (jenv , callback );
795+ if (!g_fipsCbIfaceObj ) {
796+ printf ("error storing global wolfCrypt FIPS callback interface\n" );
797+ return SSL_FAILURE ;
798+ }
799+
800+ /* register NativeFIPSErrorCallback, wraps Java callback */
801+ ret = wolfCrypt_SetCb_fips (NativeFIPSErrorCallback );
802+ if (ret == 0 ) {
803+ ret = SSL_SUCCESS ;
804+ }
805+ #else
806+ (void )jenv ;
807+ (void )callback ;
808+ printf ("Unable to set FIPS callback without wolfCrypt FIPS code\n" );
809+ #endif
810+
811+ return ret ;
812+ }
813+
814+ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSL_getWolfCryptFIPSCoreHash
815+ (JNIEnv * jenv , jclass jcl )
816+ {
817+ #ifdef HAVE_FIPS
818+ return (* jenv )-> NewStringUTF (jenv , wolfCrypt_GetCoreHash_fips ());
819+ #else
820+ return NULL ;
821+ #endif
822+ }
823+
681824JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_memsaveSessionCache
682825 (JNIEnv * jenv , jclass jcl , jbyteArray mem , jint sz )
683826{
0 commit comments