Skip to content

Commit ac28a35

Browse files
martinuygnu-andrew
authored andcommitted
RH1929465: Improve system FIPS detection
1 parent 118ce2e commit ac28a35

File tree

7 files changed

+306
-14
lines changed

7 files changed

+306
-14
lines changed

make/autoconf/libraries.m4

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
101101
LIB_SETUP_LIBFFI
102102
LIB_SETUP_BUNDLED_LIBS
103103
LIB_SETUP_MISC_LIBS
104+
LIB_SETUP_SYSCONF_LIBS
104105
LIB_SETUP_SOLARIS_STLPORT
105106
LIB_TESTS_SETUP_GRAALUNIT
106107
@@ -223,3 +224,62 @@ AC_DEFUN_ONCE([LIB_SETUP_SOLARIS_STLPORT],
223224
fi
224225
])
225226

227+
################################################################################
228+
# Setup system configuration libraries
229+
################################################################################
230+
AC_DEFUN_ONCE([LIB_SETUP_SYSCONF_LIBS],
231+
[
232+
###############################################################################
233+
#
234+
# Check for the NSS library
235+
#
236+
237+
AC_MSG_CHECKING([whether to use the system NSS library with the System Configurator (libsysconf)])
238+
239+
# default is not available
240+
DEFAULT_SYSCONF_NSS=no
241+
242+
AC_ARG_ENABLE([sysconf-nss], [AS_HELP_STRING([--enable-sysconf-nss],
243+
[build the System Configurator (libsysconf) using the system NSS library if available @<:@disabled@:>@])],
244+
[
245+
case "${enableval}" in
246+
yes)
247+
sysconf_nss=yes
248+
;;
249+
*)
250+
sysconf_nss=no
251+
;;
252+
esac
253+
],
254+
[
255+
sysconf_nss=${DEFAULT_SYSCONF_NSS}
256+
])
257+
AC_MSG_RESULT([$sysconf_nss])
258+
259+
USE_SYSCONF_NSS=false
260+
if test "x${sysconf_nss}" = "xyes"; then
261+
PKG_CHECK_MODULES(NSS, nss >= 3.53, [NSS_FOUND=yes], [NSS_FOUND=no])
262+
if test "x${NSS_FOUND}" = "xyes"; then
263+
AC_MSG_CHECKING([for system FIPS support in NSS])
264+
saved_libs="${LIBS}"
265+
saved_cflags="${CFLAGS}"
266+
CFLAGS="${CFLAGS} ${NSS_CFLAGS}"
267+
LIBS="${LIBS} ${NSS_LIBS}"
268+
AC_LANG_PUSH([C])
269+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <nss3/pk11pub.h>]],
270+
[[SECMOD_GetSystemFIPSEnabled()]])],
271+
[AC_MSG_RESULT([yes])],
272+
[AC_MSG_RESULT([no])
273+
AC_MSG_ERROR([System NSS FIPS detection unavailable])])
274+
AC_LANG_POP([C])
275+
CFLAGS="${saved_cflags}"
276+
LIBS="${saved_libs}"
277+
USE_SYSCONF_NSS=true
278+
else
279+
dnl NSS 3.53 is the one that introduces the SECMOD_GetSystemFIPSEnabled API
280+
dnl in nss3/pk11pub.h.
281+
AC_MSG_ERROR([--enable-sysconf-nss specified, but NSS 3.53 or above not found.])
282+
fi
283+
fi
284+
AC_SUBST(USE_SYSCONF_NSS)
285+
])

make/autoconf/spec.gmk.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,10 @@ INSTALL_SYSCONFDIR=@sysconfdir@
823823
# Libraries
824824
#
825825

826+
USE_SYSCONF_NSS:=@USE_SYSCONF_NSS@
827+
NSS_LIBS:=@NSS_LIBS@
828+
NSS_CFLAGS:=@NSS_CFLAGS@
829+
826830
USE_EXTERNAL_LCMS:=@USE_EXTERNAL_LCMS@
827831
LCMS_CFLAGS:=@LCMS_CFLAGS@
828832
LCMS_LIBS:=@LCMS_LIBS@

make/lib/Lib-java.base.gmk

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,31 @@ ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
178178
endif
179179
endif
180180

181+
################################################################################
182+
# Create the systemconf library
183+
184+
LIBSYSTEMCONF_CFLAGS :=
185+
LIBSYSTEMCONF_CXXFLAGS :=
186+
187+
ifeq ($(USE_SYSCONF_NSS), true)
188+
LIBSYSTEMCONF_CFLAGS += $(NSS_CFLAGS) -DSYSCONF_NSS
189+
LIBSYSTEMCONF_CXXFLAGS += $(NSS_CFLAGS) -DSYSCONF_NSS
190+
endif
191+
192+
ifeq ($(OPENJDK_BUILD_OS), linux)
193+
$(eval $(call SetupJdkLibrary, BUILD_LIBSYSTEMCONF, \
194+
NAME := systemconf, \
195+
OPTIMIZATION := LOW, \
196+
CFLAGS := $(CFLAGS_JDKLIB) $(LIBSYSTEMCONF_CFLAGS), \
197+
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBSYSTEMCONF_CXXFLAGS), \
198+
LDFLAGS := $(LDFLAGS_JDKLIB) \
199+
$(call SET_SHARED_LIBRARY_ORIGIN), \
200+
LIBS_unix := $(LIBDL) $(NSS_LIBS), \
201+
))
202+
203+
TARGETS += $(BUILD_LIBSYSTEMCONF)
204+
endif
205+
181206
################################################################################
182207
# Create the symbols file for static builds.
183208

make/nb_native/nbproject/configurations.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2950,6 +2950,9 @@
29502950
<in>LinuxWatchService.c</in>
29512951
</df>
29522952
</df>
2953+
<df name="libsystemconf">
2954+
<in>systemconf.c</in>
2955+
</df>
29532956
</df>
29542957
</df>
29552958
<df name="macosx">
@@ -29301,6 +29304,11 @@
2930129304
tool="0"
2930229305
flavor2="0">
2930329306
</item>
29307+
<item path="../../src/java.base/linux/native/libsystemconf/systemconf.c"
29308+
ex="false"
29309+
tool="0"
29310+
flavor2="0">
29311+
</item>
2930429312
<item path="../../src/java.base/macosx/native/include/jni_md.h"
2930529313
ex="false"
2930629314
tool="3"

make/scripts/compare_exceptions.sh.incl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ];
179179
./lib/libsplashscreen.so
180180
./lib/libsunec.so
181181
./lib/libsunwjdga.so
182+
./lib/libsystemconf.so
182183
./lib/libunpack.so
183184
./lib/libverify.so
184185
./lib/libzip.so
@@ -289,6 +290,7 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
289290
./lib/libsplashscreen.so
290291
./lib/libsunec.so
291292
./lib/libsunwjdga.so
293+
./lib/libsystemconf.so
292294
./lib/libunpack.so
293295
./lib/libverify.so
294296
./lib/libzip.so
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (c) 2021, Red Hat, Inc.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
#include <dlfcn.h>
27+
#include <jni.h>
28+
#include <jni_util.h>
29+
#include <stdio.h>
30+
31+
#ifdef SYSCONF_NSS
32+
#include <nss3/pk11pub.h>
33+
#endif //SYSCONF_NSS
34+
35+
#include "java_security_SystemConfigurator.h"
36+
37+
#define FIPS_ENABLED_PATH "/proc/sys/crypto/fips_enabled"
38+
#define MSG_MAX_SIZE 96
39+
40+
static jmethodID debugPrintlnMethodID = NULL;
41+
static jobject debugObj = NULL;
42+
43+
static void throwIOException(JNIEnv *env, const char *msg);
44+
static void dbgPrint(JNIEnv *env, const char* msg);
45+
46+
/*
47+
* Class: java_security_SystemConfigurator
48+
* Method: JNI_OnLoad
49+
*/
50+
JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
51+
{
52+
JNIEnv *env;
53+
jclass sysConfCls, debugCls;
54+
jfieldID sdebugFld;
55+
56+
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
57+
return JNI_EVERSION; /* JNI version not supported */
58+
}
59+
60+
sysConfCls = (*env)->FindClass(env,"java/security/SystemConfigurator");
61+
if (sysConfCls == NULL) {
62+
printf("libsystemconf: SystemConfigurator class not found\n");
63+
return JNI_ERR;
64+
}
65+
sdebugFld = (*env)->GetStaticFieldID(env, sysConfCls,
66+
"sdebug", "Lsun/security/util/Debug;");
67+
if (sdebugFld == NULL) {
68+
printf("libsystemconf: SystemConfigurator::sdebug field not found\n");
69+
return JNI_ERR;
70+
}
71+
debugObj = (*env)->GetStaticObjectField(env, sysConfCls, sdebugFld);
72+
if (debugObj != NULL) {
73+
debugCls = (*env)->FindClass(env,"sun/security/util/Debug");
74+
if (debugCls == NULL) {
75+
printf("libsystemconf: Debug class not found\n");
76+
return JNI_ERR;
77+
}
78+
debugPrintlnMethodID = (*env)->GetMethodID(env, debugCls,
79+
"println", "(Ljava/lang/String;)V");
80+
if (debugPrintlnMethodID == NULL) {
81+
printf("libsystemconf: Debug::println(String) method not found\n");
82+
return JNI_ERR;
83+
}
84+
debugObj = (*env)->NewGlobalRef(env, debugObj);
85+
}
86+
87+
return (*env)->GetVersion(env);
88+
}
89+
90+
/*
91+
* Class: java_security_SystemConfigurator
92+
* Method: JNI_OnUnload
93+
*/
94+
JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved)
95+
{
96+
JNIEnv *env;
97+
98+
if (debugObj != NULL) {
99+
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
100+
return; /* Should not happen */
101+
}
102+
(*env)->DeleteGlobalRef(env, debugObj);
103+
}
104+
}
105+
106+
JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEnabled
107+
(JNIEnv *env, jclass cls)
108+
{
109+
int fips_enabled;
110+
char msg[MSG_MAX_SIZE];
111+
int msg_bytes;
112+
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);
121+
} 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
128+
129+
FILE *fe;
130+
131+
dbgPrint(env, "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH);
132+
if ((fe = fopen(FIPS_ENABLED_PATH, "r")) == NULL) {
133+
throwIOException(env, "Cannot open " FIPS_ENABLED_PATH);
134+
}
135+
fips_enabled = fgetc(fe);
136+
fclose(fe);
137+
if (fips_enabled == EOF) {
138+
throwIOException(env, "Cannot read " FIPS_ENABLED_PATH);
139+
}
140+
msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
141+
" read character is '%c'", fips_enabled);
142+
if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) {
143+
dbgPrint(env, msg);
144+
} else {
145+
dbgPrint(env, "getSystemFIPSEnabled: cannot render" \
146+
" read character");
147+
}
148+
return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE);
149+
150+
#endif // SYSCONF_NSS
151+
}
152+
153+
static void throwIOException(JNIEnv *env, const char *msg)
154+
{
155+
jclass cls = (*env)->FindClass(env, "java/io/IOException");
156+
if (cls != 0)
157+
(*env)->ThrowNew(env, cls, msg);
158+
}
159+
160+
static void dbgPrint(JNIEnv *env, const char* msg)
161+
{
162+
jstring jMsg;
163+
if (debugObj != NULL) {
164+
jMsg = (*env)->NewStringUTF(env, msg);
165+
CHECK_NULL(jMsg);
166+
(*env)->CallVoidMethod(env, debugObj, debugPrintlnMethodID, jMsg);
167+
}
168+
}

0 commit comments

Comments
 (0)