2323 * questions.
2424 */
2525
26- #include <dlfcn.h>
2726#include <jni.h>
2827#include <jni_util.h>
28+ #include "jvm_md.h"
2929#include <stdio.h>
3030
3131#ifdef SYSCONF_NSS
3232#include <nss3/pk11pub.h>
33+ #else
34+ #include <dlfcn.h>
3335#endif //SYSCONF_NSS
3436
3537#include "java_security_SystemConfigurator.h"
3638
39+ #define MSG_MAX_SIZE 256
3740#define FIPS_ENABLED_PATH "/proc/sys/crypto/fips_enabled"
38- #define MSG_MAX_SIZE 96
3941
42+ typedef int (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE )(void );
43+
44+ static SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE * getSystemFIPSEnabled ;
4045static jmethodID debugPrintlnMethodID = NULL ;
4146static jobject debugObj = NULL ;
4247
43- static void throwIOException (JNIEnv * env , const char * msg );
44- static void dbgPrint (JNIEnv * env , const char * msg );
48+ static void dbgPrint (JNIEnv * env , const char * msg )
49+ {
50+ jstring jMsg ;
51+ if (debugObj != NULL ) {
52+ jMsg = (* env )-> NewStringUTF (env , msg );
53+ CHECK_NULL (jMsg );
54+ (* env )-> CallVoidMethod (env , debugObj , debugPrintlnMethodID , jMsg );
55+ }
56+ }
57+
58+ static void throwIOException (JNIEnv * env , const char * msg )
59+ {
60+ jclass cls = (* env )-> FindClass (env , "java/io/IOException" );
61+ if (cls != 0 )
62+ (* env )-> ThrowNew (env , cls , msg );
63+ }
64+
65+ static void handle_msg (JNIEnv * env , const char * msg , int msg_bytes )
66+ {
67+ if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE ) {
68+ dbgPrint (env , msg );
69+ } else {
70+ dbgPrint (env , "systemconf: cannot render message" );
71+ }
72+ }
73+
74+ // Only used when NSS is not linked at build time
75+ #ifndef SYSCONF_NSS
76+
77+ static void * nss_handle ;
78+
79+ static jboolean loadNSS (JNIEnv * env )
80+ {
81+ char msg [MSG_MAX_SIZE ];
82+ int msg_bytes ;
83+ const char * errmsg ;
84+
85+ nss_handle = dlopen (JNI_LIB_NAME ("nss3" ), RTLD_LAZY );
86+ if (nss_handle == NULL ) {
87+ errmsg = dlerror ();
88+ msg_bytes = snprintf (msg , MSG_MAX_SIZE , "loadNSS: dlopen: %s\n" ,
89+ errmsg );
90+ handle_msg (env , msg , msg_bytes );
91+ return JNI_FALSE ;
92+ }
93+ dlerror (); /* Clear errors */
94+ getSystemFIPSEnabled = (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE * )dlsym (nss_handle , "SECMOD_GetSystemFIPSEnabled" );
95+ if ((errmsg = dlerror ()) != NULL ) {
96+ msg_bytes = snprintf (msg , MSG_MAX_SIZE , "loadNSS: dlsym: %s\n" ,
97+ errmsg );
98+ handle_msg (env , msg , msg_bytes );
99+ return JNI_FALSE ;
100+ }
101+ return JNI_TRUE ;
102+ }
103+
104+ static void closeNSS (JNIEnv * env )
105+ {
106+ char msg [MSG_MAX_SIZE ];
107+ int msg_bytes ;
108+ const char * errmsg ;
109+
110+ if (dlclose (nss_handle ) != 0 ) {
111+ errmsg = dlerror ();
112+ msg_bytes = snprintf (msg , MSG_MAX_SIZE , "closeNSS: dlclose: %s\n" ,
113+ errmsg );
114+ handle_msg (env , msg , msg_bytes );
115+ }
116+ }
117+
118+ #endif
45119
46120/*
47121 * Class: java_security_SystemConfigurator
@@ -84,6 +158,14 @@ JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
84158 debugObj = (* env )-> NewGlobalRef (env , debugObj );
85159 }
86160
161+ #ifdef SYSCONF_NSS
162+ getSystemFIPSEnabled = * SECMOD_GetSystemFIPSEnabled ;
163+ #else
164+ if (loadNSS (env ) == JNI_FALSE ) {
165+ dbgPrint (env , "libsystemconf: Failed to load NSS library." );
166+ }
167+ #endif
168+
87169 return (* env )-> GetVersion (env );
88170}
89171
@@ -99,6 +181,9 @@ JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved)
99181 if ((* vm )-> GetEnv (vm , (void * * ) & env , JNI_VERSION_1_2 ) != JNI_OK ) {
100182 return ; /* Should not happen */
101183 }
184+ #ifndef SYSCONF_NSS
185+ closeNSS (env );
186+ #endif
102187 (* env )-> DeleteGlobalRef (env , debugObj );
103188 }
104189}
@@ -110,61 +195,30 @@ JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEn
110195 char msg [MSG_MAX_SIZE ];
111196 int msg_bytes ;
112197
113- #ifdef SYSCONF_NSS
114-
115- dbgPrint (env , "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled" );
116- fips_enabled = SECMOD_GetSystemFIPSEnabled ();
117- msg_bytes = snprintf (msg , MSG_MAX_SIZE , "getSystemFIPSEnabled:" \
118- " SECMOD_GetSystemFIPSEnabled returned 0x%x" , fips_enabled );
119- if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE ) {
120- dbgPrint (env , msg );
198+ if (getSystemFIPSEnabled != NULL ) {
199+ dbgPrint (env , "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled" );
200+ fips_enabled = (* getSystemFIPSEnabled )();
201+ msg_bytes = snprintf (msg , MSG_MAX_SIZE , "getSystemFIPSEnabled:" \
202+ " SECMOD_GetSystemFIPSEnabled returned 0x%x" , fips_enabled );
203+ handle_msg (env , msg , msg_bytes );
204+ return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE );
121205 } else {
122- dbgPrint (env , "getSystemFIPSEnabled: cannot render" \
123- " SECMOD_GetSystemFIPSEnabled return value" );
124- }
125- return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE );
126-
127- #else // SYSCONF_NSS
206+ FILE * fe ;
128207
129- FILE * fe ;
130-
131- dbgPrint (env , "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH );
132- if ((fe = fopen (FIPS_ENABLED_PATH , "r" )) == NULL ) {
208+ dbgPrint (env , "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH );
209+ if ((fe = fopen (FIPS_ENABLED_PATH , "r" )) == NULL ) {
133210 throwIOException (env , "Cannot open " FIPS_ENABLED_PATH );
134211 return JNI_FALSE ;
135- }
136- fips_enabled = fgetc (fe );
137- fclose (fe );
138- if (fips_enabled == EOF ) {
212+ }
213+ fips_enabled = fgetc (fe );
214+ fclose (fe );
215+ if (fips_enabled == EOF ) {
139216 throwIOException (env , "Cannot read " FIPS_ENABLED_PATH );
140217 return JNI_FALSE ;
141- }
142- msg_bytes = snprintf (msg , MSG_MAX_SIZE , "getSystemFIPSEnabled:" \
143- " read character is '%c'" , fips_enabled );
144- if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE ) {
145- dbgPrint (env , msg );
146- } else {
147- dbgPrint (env , "getSystemFIPSEnabled: cannot render" \
148- " read character" );
149- }
150- return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE );
151-
152- #endif // SYSCONF_NSS
153- }
154-
155- static void throwIOException (JNIEnv * env , const char * msg )
156- {
157- jclass cls = (* env )-> FindClass (env , "java/io/IOException" );
158- if (cls != 0 )
159- (* env )-> ThrowNew (env , cls , msg );
160- }
161-
162- static void dbgPrint (JNIEnv * env , const char * msg )
163- {
164- jstring jMsg ;
165- if (debugObj != NULL ) {
166- jMsg = (* env )-> NewStringUTF (env , msg );
167- CHECK_NULL (jMsg );
168- (* env )-> CallVoidMethod (env , debugObj , debugPrintlnMethodID , jMsg );
218+ }
219+ msg_bytes = snprintf (msg , MSG_MAX_SIZE , "getSystemFIPSEnabled:" \
220+ " read character is '%c'" , fips_enabled );
221+ handle_msg (env , msg , msg_bytes );
222+ return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE );
169223 }
170224}
0 commit comments