Blame SOURCES/rh2052829-fips_runtime_nss_detection.patch

2578b9
commit e2be09f982af1cc05f5e6556d51900bca4757416
2578b9
Author: Andrew Hughes <gnu.andrew@redhat.com>
2578b9
Date:   Mon Feb 28 05:30:32 2022 +0000
2578b9
2578b9
    RH2051605: Detect NSS at Runtime for FIPS detection
2578b9
2578b9
diff --git openjdk.orig/src/java.base/linux/native/libsystemconf/systemconf.c openjdk/src/java.base/linux/native/libsystemconf/systemconf.c
2578b9
index 34d0ff0ce91..8dcb7d9073f 100644
2578b9
--- openjdk.orig/src/java.base/linux/native/libsystemconf/systemconf.c
2578b9
+++ openjdk/src/java.base/linux/native/libsystemconf/systemconf.c
2578b9
@@ -23,25 +23,99 @@
2578b9
  * questions.
2578b9
  */
2578b9
 
2578b9
-#include <dlfcn.h>
2578b9
 #include <jni.h>
2578b9
 #include <jni_util.h>
2578b9
+#include "jvm_md.h"
2578b9
 #include <stdio.h>
2578b9
 
2578b9
 #ifdef SYSCONF_NSS
2578b9
 #include <nss3/pk11pub.h>
2578b9
+#else
2578b9
+#include <dlfcn.h>
2578b9
 #endif //SYSCONF_NSS
2578b9
 
2578b9
 #include "java_security_SystemConfigurator.h"
2578b9
 
2578b9
+#define MSG_MAX_SIZE 256
2578b9
 #define FIPS_ENABLED_PATH "/proc/sys/crypto/fips_enabled"
2578b9
-#define MSG_MAX_SIZE 96
2578b9
 
2578b9
+typedef int (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE)(void);
2578b9
+
2578b9
+static SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE *getSystemFIPSEnabled;
2578b9
 static jmethodID debugPrintlnMethodID = NULL;
2578b9
 static jobject debugObj = NULL;
2578b9
 
2578b9
-static void throwIOException(JNIEnv *env, const char *msg);
2578b9
-static void dbgPrint(JNIEnv *env, const char* msg);
2578b9
+static void dbgPrint(JNIEnv *env, const char* msg)
2578b9
+{
2578b9
+    jstring jMsg;
2578b9
+    if (debugObj != NULL) {
2578b9
+        jMsg = (*env)->NewStringUTF(env, msg);
2578b9
+        CHECK_NULL(jMsg);
2578b9
+        (*env)->CallVoidMethod(env, debugObj, debugPrintlnMethodID, jMsg);
2578b9
+    }
2578b9
+}
2578b9
+
2578b9
+static void throwIOException(JNIEnv *env, const char *msg)
2578b9
+{
2578b9
+    jclass cls = (*env)->FindClass(env, "java/io/IOException");
2578b9
+    if (cls != 0)
2578b9
+        (*env)->ThrowNew(env, cls, msg);
2578b9
+}
2578b9
+
2578b9
+static void handle_msg(JNIEnv *env, const char* msg, int msg_bytes)
2578b9
+{
2578b9
+  if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) {
2578b9
+    dbgPrint(env, msg);
2578b9
+  } else {
2578b9
+    dbgPrint(env, "systemconf: cannot render message");
2578b9
+  }
2578b9
+}
2578b9
+
2578b9
+// Only used when NSS is not linked at build time
2578b9
+#ifndef SYSCONF_NSS
2578b9
+
2578b9
+static void *nss_handle;
2578b9
+
2578b9
+static jboolean loadNSS(JNIEnv *env)
2578b9
+{
2578b9
+  char msg[MSG_MAX_SIZE];
2578b9
+  int msg_bytes;
2578b9
+  const char* errmsg;
2578b9
+
2578b9
+  nss_handle = dlopen(JNI_LIB_NAME("nss3"), RTLD_LAZY);
2578b9
+  if (nss_handle == NULL) {
2578b9
+    errmsg = dlerror();
2578b9
+    msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlopen: %s\n",
2578b9
+                         errmsg);
2578b9
+    handle_msg(env, msg, msg_bytes);
2578b9
+    return JNI_FALSE;
2578b9
+  }
2578b9
+  dlerror(); /* Clear errors */
2578b9
+  getSystemFIPSEnabled = (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE*)dlsym(nss_handle, "SECMOD_GetSystemFIPSEnabled");
2578b9
+  if ((errmsg = dlerror()) != NULL) {
2578b9
+    msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlsym: %s\n",
2578b9
+                         errmsg);
2578b9
+    handle_msg(env, msg, msg_bytes);
2578b9
+    return JNI_FALSE;
2578b9
+  }
2578b9
+  return JNI_TRUE;
2578b9
+}
2578b9
+
2578b9
+static void closeNSS(JNIEnv *env)
2578b9
+{
2578b9
+  char msg[MSG_MAX_SIZE];
2578b9
+  int msg_bytes;
2578b9
+  const char* errmsg;
2578b9
+
2578b9
+  if (dlclose(nss_handle) != 0) {
2578b9
+    errmsg = dlerror();
2578b9
+    msg_bytes = snprintf(msg, MSG_MAX_SIZE, "closeNSS: dlclose: %s\n",
2578b9
+                         errmsg);
2578b9
+    handle_msg(env, msg, msg_bytes);
2578b9
+  }
2578b9
+}
2578b9
+
2578b9
+#endif
2578b9
 
2578b9
 /*
2578b9
  * Class:     java_security_SystemConfigurator
2578b9
@@ -84,6 +158,14 @@ JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
2578b9
         debugObj = (*env)->NewGlobalRef(env, debugObj);
2578b9
     }
2578b9
 
2578b9
+#ifdef SYSCONF_NSS
2578b9
+    getSystemFIPSEnabled = *SECMOD_GetSystemFIPSEnabled;
2578b9
+#else
2578b9
+    if (loadNSS(env) == JNI_FALSE) {
2578b9
+      dbgPrint(env, "libsystemconf: Failed to load NSS library.");
2578b9
+    }
2578b9
+#endif
2578b9
+
2578b9
     return (*env)->GetVersion(env);
2578b9
 }
2578b9
 
2578b9
@@ -99,6 +181,9 @@ JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved)
2578b9
         if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
2578b9
             return; /* Should not happen */
2578b9
         }
2578b9
+#ifndef SYSCONF_NSS
2578b9
+        closeNSS(env);
2578b9
+#endif
2578b9
         (*env)->DeleteGlobalRef(env, debugObj);
2578b9
     }
2578b9
 }
2578b9
@@ -110,61 +195,30 @@ JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEn
2578b9
     char msg[MSG_MAX_SIZE];
2578b9
     int msg_bytes;
2578b9
 
2578b9
-#ifdef SYSCONF_NSS
2578b9
-
2578b9
-    dbgPrint(env, "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled");
2578b9
-    fips_enabled = SECMOD_GetSystemFIPSEnabled();
2578b9
-    msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
2578b9
-            " SECMOD_GetSystemFIPSEnabled returned 0x%x", fips_enabled);
2578b9
-    if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) {
2578b9
-        dbgPrint(env, msg);
2578b9
+    if (getSystemFIPSEnabled != NULL) {
2578b9
+      dbgPrint(env, "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled");
2578b9
+      fips_enabled = (*getSystemFIPSEnabled)();
2578b9
+      msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:"   \
2578b9
+                           " SECMOD_GetSystemFIPSEnabled returned 0x%x", fips_enabled);
2578b9
+      handle_msg(env, msg, msg_bytes);
2578b9
+      return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE);
2578b9
     } else {
2578b9
-        dbgPrint(env, "getSystemFIPSEnabled: cannot render" \
2578b9
-                " SECMOD_GetSystemFIPSEnabled return value");
2578b9
-    }
2578b9
-    return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE);
2578b9
-
2578b9
-#else // SYSCONF_NSS
2578b9
+      FILE *fe;
2578b9
 
2578b9
-    FILE *fe;
2578b9
-
2578b9
-    dbgPrint(env, "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH);
2578b9
-    if ((fe = fopen(FIPS_ENABLED_PATH, "r")) == NULL) {
2578b9
+      dbgPrint(env, "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH);
2578b9
+      if ((fe = fopen(FIPS_ENABLED_PATH, "r")) == NULL) {
2578b9
         throwIOException(env, "Cannot open " FIPS_ENABLED_PATH);
2578b9
         return JNI_FALSE;
2578b9
-    }
2578b9
-    fips_enabled = fgetc(fe);
2578b9
-    fclose(fe);
2578b9
-    if (fips_enabled == EOF) {
2578b9
+      }
2578b9
+      fips_enabled = fgetc(fe);
2578b9
+      fclose(fe);
2578b9
+      if (fips_enabled == EOF) {
2578b9
         throwIOException(env, "Cannot read " FIPS_ENABLED_PATH);
2578b9
         return JNI_FALSE;
2578b9
-    }
2578b9
-    msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \
2578b9
-            " read character is '%c'", fips_enabled);
2578b9
-    if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) {
2578b9
-        dbgPrint(env, msg);
2578b9
-    } else {
2578b9
-        dbgPrint(env, "getSystemFIPSEnabled: cannot render" \
2578b9
-                " read character");
2578b9
-    }
2578b9
-    return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE);
2578b9
-
2578b9
-#endif // SYSCONF_NSS
2578b9
-}
2578b9
-
2578b9
-static void throwIOException(JNIEnv *env, const char *msg)
2578b9
-{
2578b9
-    jclass cls = (*env)->FindClass(env, "java/io/IOException");
2578b9
-    if (cls != 0)
2578b9
-        (*env)->ThrowNew(env, cls, msg);
2578b9
-}
2578b9
-
2578b9
-static void dbgPrint(JNIEnv *env, const char* msg)
2578b9
-{
2578b9
-    jstring jMsg;
2578b9
-    if (debugObj != NULL) {
2578b9
-        jMsg = (*env)->NewStringUTF(env, msg);
2578b9
-        CHECK_NULL(jMsg);
2578b9
-        (*env)->CallVoidMethod(env, debugObj, debugPrintlnMethodID, jMsg);
2578b9
+      }
2578b9
+      msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:"   \
2578b9
+                           " read character is '%c'", fips_enabled);
2578b9
+      handle_msg(env, msg, msg_bytes);
2578b9
+      return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE);
2578b9
     }
2578b9
 }