Update FIPS support to bring in latest changes

* RH2104724: Avoid import/export of DH private keys
* RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode
* Build the systemconf library on all platforms
This commit is contained in:
Andrew Hughes 2022-08-15 02:09:20 +01:00
parent b540c51900
commit ddd9b60d6e
2 changed files with 276 additions and 443 deletions

View File

@ -124,10 +124,10 @@ index c2c9c4adf3a..9d105b37acf 100644
LCMS_CFLAGS:=@LCMS_CFLAGS@
LCMS_LIBS:=@LCMS_LIBS@
diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk
index 5658ff342e5..cb7a56852f7 100644
index 5658ff342e5..c8bc5bde1e1 100644
--- a/make/modules/java.base/Lib.gmk
+++ b/make/modules/java.base/Lib.gmk
@@ -167,6 +167,31 @@ ifeq ($(call isTargetOsType, unix), true)
@@ -167,6 +167,29 @@ ifeq ($(call isTargetOsType, unix), true)
endif
endif
@ -142,255 +142,23 @@ index 5658ff342e5..cb7a56852f7 100644
+ LIBSYSTEMCONF_CXXFLAGS += $(NSS_CFLAGS) -DSYSCONF_NSS
+endif
+
+ifeq ($(OPENJDK_BUILD_OS), linux)
+ $(eval $(call SetupJdkLibrary, BUILD_LIBSYSTEMCONF, \
+ NAME := systemconf, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) $(LIBSYSTEMCONF_CFLAGS), \
+ CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBSYSTEMCONF_CXXFLAGS), \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS_unix := $(LIBDL) $(NSS_LIBS), \
+ ))
+$(eval $(call SetupJdkLibrary, BUILD_LIBSYSTEMCONF, \
+ NAME := systemconf, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) $(LIBSYSTEMCONF_CFLAGS), \
+ CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBSYSTEMCONF_CXXFLAGS), \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS_unix := $(LIBDL) $(NSS_LIBS), \
+))
+
+ TARGETS += $(BUILD_LIBSYSTEMCONF)
+endif
+TARGETS += $(BUILD_LIBSYSTEMCONF)
+
################################################################################
# Create the symbols file for static builds.
diff --git a/src/java.base/linux/native/libsystemconf/systemconf.c b/src/java.base/linux/native/libsystemconf/systemconf.c
new file mode 100644
index 00000000000..8dcb7d9073f
--- /dev/null
+++ b/src/java.base/linux/native/libsystemconf/systemconf.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2021, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include <jni_util.h>
+#include "jvm_md.h"
+#include <stdio.h>
+
+#ifdef SYSCONF_NSS
+#include <nss3/pk11pub.h>
+#else
+#include <dlfcn.h>
+#endif //SYSCONF_NSS
+
+#include "java_security_SystemConfigurator.h"
+
+#define MSG_MAX_SIZE 256
+#define FIPS_ENABLED_PATH "/proc/sys/crypto/fips_enabled"
+
+typedef int (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE)(void);
+
+static SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE *getSystemFIPSEnabled;
+static jmethodID debugPrintlnMethodID = NULL;
+static jobject debugObj = NULL;
+
+static void dbgPrint(JNIEnv *env, const char* msg)
+{
+ jstring jMsg;
+ if (debugObj != NULL) {
+ jMsg = (*env)->NewStringUTF(env, msg);
+ CHECK_NULL(jMsg);
+ (*env)->CallVoidMethod(env, debugObj, debugPrintlnMethodID, jMsg);
+ }
+}
+
+static void throwIOException(JNIEnv *env, const char *msg)
+{
+ jclass cls = (*env)->FindClass(env, "java/io/IOException");
+ if (cls != 0)
+ (*env)->ThrowNew(env, cls, msg);
+}
+
+static void handle_msg(JNIEnv *env, const char* msg, int msg_bytes)
+{
+ if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) {
+ dbgPrint(env, msg);
+ } else {
+ dbgPrint(env, "systemconf: cannot render message");
+ }
+}
+
+// Only used when NSS is not linked at build time
+#ifndef SYSCONF_NSS
+
+static void *nss_handle;
+
+static jboolean loadNSS(JNIEnv *env)
+{
+ char msg[MSG_MAX_SIZE];
+ int msg_bytes;
+ const char* errmsg;
+
+ nss_handle = dlopen(JNI_LIB_NAME("nss3"), RTLD_LAZY);
+ if (nss_handle == NULL) {
+ errmsg = dlerror();
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlopen: %s\n",
+ errmsg);
+ handle_msg(env, msg, msg_bytes);
+ return JNI_FALSE;
+ }
+ dlerror(); /* Clear errors */
+ getSystemFIPSEnabled = (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE*)dlsym(nss_handle, "SECMOD_GetSystemFIPSEnabled");
+ if ((errmsg = dlerror()) != NULL) {
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlsym: %s\n",
+ errmsg);
+ handle_msg(env, msg, msg_bytes);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+static void closeNSS(JNIEnv *env)
+{
+ char msg[MSG_MAX_SIZE];
+ int msg_bytes;
+ const char* errmsg;
+
+ if (dlclose(nss_handle) != 0) {
+ errmsg = dlerror();
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "closeNSS: dlclose: %s\n",
+ errmsg);
+ handle_msg(env, msg, msg_bytes);
+ }
+}
+
+#endif
+
+/*
+ * Class: java_security_SystemConfigurator
+ * Method: JNI_OnLoad
+ */
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ JNIEnv *env;
+ jclass sysConfCls, debugCls;
+ jfieldID sdebugFld;
+
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return JNI_EVERSION; /* JNI version not supported */
+ }
+
+ sysConfCls = (*env)->FindClass(env,"java/security/SystemConfigurator");
+ if (sysConfCls == NULL) {
+ printf("libsystemconf: SystemConfigurator class not found\n");
+ return JNI_ERR;
+ }
+ sdebugFld = (*env)->GetStaticFieldID(env, sysConfCls,
+ "sdebug", "Lsun/security/util/Debug;");
+ if (sdebugFld == NULL) {
+ printf("libsystemconf: SystemConfigurator::sdebug field not found\n");
+ return JNI_ERR;
+ }
+ debugObj = (*env)->GetStaticObjectField(env, sysConfCls, sdebugFld);
+ if (debugObj != NULL) {
+ debugCls = (*env)->FindClass(env,"sun/security/util/Debug");
+ if (debugCls == NULL) {
+ printf("libsystemconf: Debug class not found\n");
+ return JNI_ERR;
+ }
+ debugPrintlnMethodID = (*env)->GetMethodID(env, debugCls,
+ "println", "(Ljava/lang/String;)V");
+ if (debugPrintlnMethodID == NULL) {
+ printf("libsystemconf: Debug::println(String) method not found\n");
+ return JNI_ERR;
+ }
+ debugObj = (*env)->NewGlobalRef(env, debugObj);
+ }
+
+#ifdef SYSCONF_NSS
+ getSystemFIPSEnabled = *SECMOD_GetSystemFIPSEnabled;
+#else
+ if (loadNSS(env) == JNI_FALSE) {
+ dbgPrint(env, "libsystemconf: Failed to load NSS library.");
+ }
+#endif
+
+ return (*env)->GetVersion(env);
+}
+
+/*
+ * Class: java_security_SystemConfigurator
+ * Method: JNI_OnUnload
+ */
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved)
+{
+ JNIEnv *env;
+
+ if (debugObj != NULL) {
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return; /* Should not happen */
+ }
+#ifndef SYSCONF_NSS
+ closeNSS(env);
+#endif
+ (*env)->DeleteGlobalRef(env, debugObj);
+ }
+}
+
+JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEnabled
+ (JNIEnv *env, jclass cls)
+{
+ int fips_enabled;
+ char msg[MSG_MAX_SIZE];
+ int msg_bytes;
+
+ if (getSystemFIPSEnabled != NULL) {
+ dbgPrint(env, "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled");
+ fips_enabled = (*getSystemFIPSEnabled)();
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
+ " SECMOD_GetSystemFIPSEnabled returned 0x%x", fips_enabled);
+ handle_msg(env, msg, msg_bytes);
+ return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE);
+ } else {
+ FILE *fe;
+
+ dbgPrint(env, "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH);
+ if ((fe = fopen(FIPS_ENABLED_PATH, "r")) == NULL) {
+ throwIOException(env, "Cannot open " FIPS_ENABLED_PATH);
+ return JNI_FALSE;
+ }
+ fips_enabled = fgetc(fe);
+ fclose(fe);
+ if (fips_enabled == EOF) {
+ throwIOException(env, "Cannot read " FIPS_ENABLED_PATH);
+ return JNI_FALSE;
+ }
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
+ " read character is '%c'", fips_enabled);
+ handle_msg(env, msg, msg_bytes);
+ return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE);
+ }
+}
diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
index a020e1c15d8..6d459fdec01 100644
index a020e1c15d8..3c064965e82 100644
--- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
+++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
@@ -31,6 +31,7 @@ import java.security.SecureRandom;
@ -1006,89 +774,10 @@ index a020e1c15d8..6d459fdec01 100644
/*
* Algorithm Parameter engines
@@ -531,197 +540,199 @@ public final class SunJCE extends Provider {
psA("AlgorithmParameters", "ChaCha20-Poly1305",
"com.sun.crypto.provider.ChaCha20Poly1305Parameters", null);
@@ -610,118 +619,120 @@ public final class SunJCE extends Provider {
ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_256",
"com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256");
- /*
- * Key factories
- */
- psA("KeyFactory", "DiffieHellman",
- "com.sun.crypto.provider.DHKeyFactory",
- null);
-
- /*
- * Secret-key factories
- */
- ps("SecretKeyFactory", "DES",
- "com.sun.crypto.provider.DESKeyFactory");
-
- psA("SecretKeyFactory", "DESede",
- "com.sun.crypto.provider.DESedeKeyFactory", null);
-
- psA("SecretKeyFactory", "PBEWithMD5AndDES",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES",
- null);
-
- /*
- * Internal in-house crypto algorithm used for
- * the JCEKS keystore type. Since this was developed
- * internally, there isn't an OID corresponding to this
- * algorithm.
- */
- ps("SecretKeyFactory", "PBEWithMD5AndTripleDES",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES");
-
- psA("SecretKeyFactory", "PBEWithSHA1AndDESede",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndDESede",
- null);
-
- psA("SecretKeyFactory", "PBEWithSHA1AndRC2_40",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_40",
- null);
-
- psA("SecretKeyFactory", "PBEWithSHA1AndRC2_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_128",
- null);
-
- psA("SecretKeyFactory", "PBEWithSHA1AndRC4_40",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_40",
- null);
-
- psA("SecretKeyFactory", "PBEWithSHA1AndRC4_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_128",
- null);
-
- ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_128",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_256",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_256",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_256",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256");
-
- ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_256",
- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256");
-
- // PBKDF2
- psA("SecretKeyFactory", "PBKDF2WithHmacSHA1",
- "com.sun.crypto.provider.PBKDF2Core$HmacSHA1",
@ -1202,85 +891,6 @@ index a020e1c15d8..6d459fdec01 100644
- "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator",
- List.of("SunTls12RsaPremasterSecret"), null);
+ if (!systemFipsEnabled) {
+ /*
+ * Key factories
+ */
+ psA("KeyFactory", "DiffieHellman",
+ "com.sun.crypto.provider.DHKeyFactory",
+ null);
+
+ /*
+ * Secret-key factories
+ */
+ ps("SecretKeyFactory", "DES",
+ "com.sun.crypto.provider.DESKeyFactory");
+
+ psA("SecretKeyFactory", "DESede",
+ "com.sun.crypto.provider.DESedeKeyFactory", null);
+
+ psA("SecretKeyFactory", "PBEWithMD5AndDES",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES",
+ null);
+
+ /*
+ * Internal in-house crypto algorithm used for
+ * the JCEKS keystore type. Since this was developed
+ * internally, there isn't an OID corresponding to this
+ * algorithm.
+ */
+ ps("SecretKeyFactory", "PBEWithMD5AndTripleDES",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES");
+
+ psA("SecretKeyFactory", "PBEWithSHA1AndDESede",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndDESede",
+ null);
+
+ psA("SecretKeyFactory", "PBEWithSHA1AndRC2_40",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_40",
+ null);
+
+ psA("SecretKeyFactory", "PBEWithSHA1AndRC2_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_128",
+ null);
+
+ psA("SecretKeyFactory", "PBEWithSHA1AndRC4_40",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_40",
+ null);
+
+ psA("SecretKeyFactory", "PBEWithSHA1AndRC4_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_128",
+ null);
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_128",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_256",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_256",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_256",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256");
+
+ ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_256",
+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256");
+
+ // PBKDF2
+ psA("SecretKeyFactory", "PBKDF2WithHmacSHA1",
+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA1",
@ -2474,12 +2084,254 @@ index b22f26947af..3ee2ce6ea88 100644
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
diff --git a/src/java.base/share/native/libsystemconf/systemconf.c b/src/java.base/share/native/libsystemconf/systemconf.c
new file mode 100644
index 00000000000..ddf9befe5bc
--- /dev/null
+++ b/src/java.base/share/native/libsystemconf/systemconf.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2021, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include <jni_util.h>
+#include "jvm_md.h"
+#include <stdio.h>
+
+#ifdef LINUX
+
+#ifdef SYSCONF_NSS
+#include <nss3/pk11pub.h>
+#else
+#include <dlfcn.h>
+#endif //SYSCONF_NSS
+
+#include "java_security_SystemConfigurator.h"
+
+#define MSG_MAX_SIZE 256
+#define FIPS_ENABLED_PATH "/proc/sys/crypto/fips_enabled"
+
+typedef int (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE)(void);
+
+static SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE *getSystemFIPSEnabled;
+static jmethodID debugPrintlnMethodID = NULL;
+static jobject debugObj = NULL;
+
+static void dbgPrint(JNIEnv *env, const char* msg)
+{
+ jstring jMsg;
+ if (debugObj != NULL) {
+ jMsg = (*env)->NewStringUTF(env, msg);
+ CHECK_NULL(jMsg);
+ (*env)->CallVoidMethod(env, debugObj, debugPrintlnMethodID, jMsg);
+ }
+}
+
+static void throwIOException(JNIEnv *env, const char *msg)
+{
+ jclass cls = (*env)->FindClass(env, "java/io/IOException");
+ if (cls != 0)
+ (*env)->ThrowNew(env, cls, msg);
+}
+
+static void handle_msg(JNIEnv *env, const char* msg, int msg_bytes)
+{
+ if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) {
+ dbgPrint(env, msg);
+ } else {
+ dbgPrint(env, "systemconf: cannot render message");
+ }
+}
+
+// Only used when NSS is not linked at build time
+#ifndef SYSCONF_NSS
+
+static void *nss_handle;
+
+static jboolean loadNSS(JNIEnv *env)
+{
+ char msg[MSG_MAX_SIZE];
+ int msg_bytes;
+ const char* errmsg;
+
+ nss_handle = dlopen(JNI_LIB_NAME("nss3"), RTLD_LAZY);
+ if (nss_handle == NULL) {
+ errmsg = dlerror();
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlopen: %s\n",
+ errmsg);
+ handle_msg(env, msg, msg_bytes);
+ return JNI_FALSE;
+ }
+ dlerror(); /* Clear errors */
+ getSystemFIPSEnabled = (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE*)dlsym(nss_handle, "SECMOD_GetSystemFIPSEnabled");
+ if ((errmsg = dlerror()) != NULL) {
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlsym: %s\n",
+ errmsg);
+ handle_msg(env, msg, msg_bytes);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+static void closeNSS(JNIEnv *env)
+{
+ char msg[MSG_MAX_SIZE];
+ int msg_bytes;
+ const char* errmsg;
+
+ if (dlclose(nss_handle) != 0) {
+ errmsg = dlerror();
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "closeNSS: dlclose: %s\n",
+ errmsg);
+ handle_msg(env, msg, msg_bytes);
+ }
+}
+
+#endif
+
+/*
+ * Class: java_security_SystemConfigurator
+ * Method: JNI_OnLoad
+ */
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ JNIEnv *env;
+ jclass sysConfCls, debugCls;
+ jfieldID sdebugFld;
+
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return JNI_EVERSION; /* JNI version not supported */
+ }
+
+ sysConfCls = (*env)->FindClass(env,"java/security/SystemConfigurator");
+ if (sysConfCls == NULL) {
+ printf("libsystemconf: SystemConfigurator class not found\n");
+ return JNI_ERR;
+ }
+ sdebugFld = (*env)->GetStaticFieldID(env, sysConfCls,
+ "sdebug", "Lsun/security/util/Debug;");
+ if (sdebugFld == NULL) {
+ printf("libsystemconf: SystemConfigurator::sdebug field not found\n");
+ return JNI_ERR;
+ }
+ debugObj = (*env)->GetStaticObjectField(env, sysConfCls, sdebugFld);
+ if (debugObj != NULL) {
+ debugCls = (*env)->FindClass(env,"sun/security/util/Debug");
+ if (debugCls == NULL) {
+ printf("libsystemconf: Debug class not found\n");
+ return JNI_ERR;
+ }
+ debugPrintlnMethodID = (*env)->GetMethodID(env, debugCls,
+ "println", "(Ljava/lang/String;)V");
+ if (debugPrintlnMethodID == NULL) {
+ printf("libsystemconf: Debug::println(String) method not found\n");
+ return JNI_ERR;
+ }
+ debugObj = (*env)->NewGlobalRef(env, debugObj);
+ }
+
+#ifdef SYSCONF_NSS
+ getSystemFIPSEnabled = *SECMOD_GetSystemFIPSEnabled;
+#else
+ if (loadNSS(env) == JNI_FALSE) {
+ dbgPrint(env, "libsystemconf: Failed to load NSS library.");
+ }
+#endif
+
+ return (*env)->GetVersion(env);
+}
+
+/*
+ * Class: java_security_SystemConfigurator
+ * Method: JNI_OnUnload
+ */
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved)
+{
+ JNIEnv *env;
+
+ if (debugObj != NULL) {
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return; /* Should not happen */
+ }
+#ifndef SYSCONF_NSS
+ closeNSS(env);
+#endif
+ (*env)->DeleteGlobalRef(env, debugObj);
+ }
+}
+
+JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEnabled
+ (JNIEnv *env, jclass cls)
+{
+ int fips_enabled;
+ char msg[MSG_MAX_SIZE];
+ int msg_bytes;
+
+ if (getSystemFIPSEnabled != NULL) {
+ dbgPrint(env, "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled");
+ fips_enabled = (*getSystemFIPSEnabled)();
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
+ " SECMOD_GetSystemFIPSEnabled returned 0x%x", fips_enabled);
+ handle_msg(env, msg, msg_bytes);
+ return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE);
+ } else {
+ FILE *fe;
+
+ dbgPrint(env, "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH);
+ if ((fe = fopen(FIPS_ENABLED_PATH, "r")) == NULL) {
+ throwIOException(env, "Cannot open " FIPS_ENABLED_PATH);
+ return JNI_FALSE;
+ }
+ fips_enabled = fgetc(fe);
+ fclose(fe);
+ if (fips_enabled == EOF) {
+ throwIOException(env, "Cannot read " FIPS_ENABLED_PATH);
+ return JNI_FALSE;
+ }
+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
+ " read character is '%c'", fips_enabled);
+ handle_msg(env, msg, msg_bytes);
+ return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE);
+ }
+}
+
+#else // !LINUX
+
+JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEnabled
+ (JNIEnv *env, jclass cls)
+{
+ return JNI_FALSE;
+}
+
+#endif
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java
new file mode 100644
index 00000000000..9bb31555f48
index 00000000000..8cfa2734d4e
--- /dev/null
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java
@@ -0,0 +1,490 @@
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 2021, Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -2520,7 +2372,6 @@ index 00000000000..9bb31555f48
+import javax.crypto.Cipher;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+import javax.crypto.spec.DHPrivateKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+
+import sun.security.jca.JCAUtil;
@ -2676,34 +2527,6 @@ index 00000000000..9bb31555f48
+ attrsMap.put(CKA_NETSCAPE_DB,
+ new CK_ATTRIBUTE(CKA_NETSCAPE_DB, BigInteger.ZERO));
+ }
+ } else if (keyType == CKK_DH) {
+ if (debug != null) {
+ debug.println("Importing a Diffie-Hellman private key...");
+ }
+ if (DHKF == null) {
+ DHKFLock.lock();
+ try {
+ if (DHKF == null) {
+ DHKF = KeyFactory.getInstance(
+ "DH", P11Util.getSunJceProvider());
+ }
+ } finally {
+ DHKFLock.unlock();
+ }
+ }
+ DHPrivateKeySpec spec = new DHPrivateKeySpec
+ (((v = attrsMap.get(CKA_VALUE).getBigInteger()) != null)
+ ? v : BigInteger.ZERO,
+ ((v = attrsMap.get(CKA_PRIME).getBigInteger()) != null)
+ ? v : BigInteger.ZERO,
+ ((v = attrsMap.get(CKA_BASE).getBigInteger()) != null)
+ ? v : BigInteger.ZERO);
+ keyBytes = DHKF.generatePrivate(spec).getEncoded();
+ if (token.config.getNssNetscapeDbWorkaround() &&
+ attrsMap.get(CKA_NETSCAPE_DB) == null) {
+ attrsMap.put(CKA_NETSCAPE_DB,
+ new CK_ATTRIBUTE(CKA_NETSCAPE_DB, BigInteger.ZERO));
+ }
+ } else {
+ if (debug != null) {
+ debug.println("Unrecognized private key type.");
@ -2971,7 +2794,7 @@ index 00000000000..9bb31555f48
+ }
+}
diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java
index 9b69072280e..b403e6d3c6d 100644
index 9b69072280e..babf19d7157 100644
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java
@@ -37,6 +37,8 @@ import javax.crypto.*;
@ -2993,17 +2816,18 @@ index 9b69072280e..b403e6d3c6d 100644
private static final long serialVersionUID = -2575874101938349339L;
private static final String PUBLIC = "public";
@@ -379,7 +384,8 @@ abstract class P11Key implements Key, Length {
@@ -379,7 +384,9 @@ abstract class P11Key implements Key, Length {
new CK_ATTRIBUTE(CKA_SENSITIVE),
new CK_ATTRIBUTE(CKA_EXTRACTABLE),
});
- if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) {
+ if (!plainKeySupportEnabled && (attributes[1].getBoolean() ||
+ boolean exportable = plainKeySupportEnabled && !algorithm.equals("DH");
+ if (!exportable && (attributes[1].getBoolean() ||
+ (attributes[2].getBoolean() == false))) {
return new P11PrivateKey
(session, keyID, algorithm, keyLength, attributes);
} else {
@@ -461,7 +467,8 @@ abstract class P11Key implements Key, Length {
@@ -461,7 +468,8 @@ abstract class P11Key implements Key, Length {
}
public String getFormat() {
token.ensureValid();

View File

@ -349,7 +349,7 @@
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the FIPS support patches
%global fipsver f8142a23d0a
%global fipsver bb46af07cb9
# Standard JPackage naming and versioning defines
%global origin openjdk
@ -357,7 +357,7 @@
%global top_level_dir_name %{origin}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
%global buildver 8
%global rpmrelease 1
%global rpmrelease 2
# Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit
%if %is_system_jdk
# Using 10 digits may overflow the int used for priority, so we combine the patch and build versions
@ -1384,6 +1384,9 @@ Patch6: rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-d
# RH2094027: SunEC runtime permission for FIPS
# RH2036462: sun.security.pkcs11.wrapper.PKCS11.getInstance breakage
# RH2090378: Revert to disabling system security properties and FIPS mode support together
# RH2104724: Avoid import/export of DH private keys
# RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode
# Build the systemconf library on all platforms
Patch1001: fips-17u-%{fipsver}.patch
#############################################
@ -2604,6 +2607,12 @@ cjc.mainProgram(args)
%endif
%changelog
* Mon Aug 15 2022 Andrew Hughes <gnu.andrew@redhat.com> - 1:17.0.4.0.8-2
- Update FIPS support to bring in latest changes
- * RH2104724: Avoid import/export of DH private keys
- * RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode
- * Build the systemconf library on all platforms
* Fri Jul 22 2022 Andrew Hughes <gnu.andrew@redhat.com> - 1:17.0.4.0.8-1
- Update to jdk-17.0.3.0+8
- Update release notes to 17.0.3.0+8