Skip to content

Commit 33d4d26

Browse files
committed
RH2051605: Detect NSS at Runtime for FIPS detection
1 parent c229747 commit 33d4d26

File tree

1 file changed

+108
-54
lines changed

1 file changed

+108
-54
lines changed

src/java.base/linux/native/libsystemconf/systemconf.c

Lines changed: 108 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,99 @@
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;
4045
static jmethodID debugPrintlnMethodID = NULL;
4146
static 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

Comments
 (0)