Blame SOURCES/rh1655466-global_crypto_and_fips.patch

d1af5a
diff --git a/src/java.base/share/classes/javopenjdk.orig///security/Security.java openjdk///src/java.base/share/classes/java/security/Security.java
d1af5a
--- openjdk.orig/src/java.base/share/classes/java/security/Security.java
d1af5a
+++ openjdk/src/java.base/share/classes/java/security/Security.java
d1af5a
@@ -196,26 +196,8 @@
d1af5a
         if (disableSystemProps == null &&
d1af5a
             "true".equalsIgnoreCase(props.getProperty
d1af5a
                 ("security.useSystemPropertiesFile"))) {
d1af5a
-
d1af5a
-            // now load the system file, if it exists, so its values
d1af5a
-            // will win if they conflict with the earlier values
d1af5a
-            try (BufferedInputStream bis =
d1af5a
-                 new BufferedInputStream(new FileInputStream(SYSTEM_PROPERTIES))) {
d1af5a
-                props.load(bis);
d1af5a
+            if (SystemConfigurator.configure(props)) {
d1af5a
                 loadedProps = true;
d1af5a
-
d1af5a
-                if (sdebug != null) {
d1af5a
-                    sdebug.println("reading system security properties file " +
d1af5a
-                                   SYSTEM_PROPERTIES);
d1af5a
-                    sdebug.println(props.toString());
d1af5a
-                }
d1af5a
-            } catch (IOException e) {
d1af5a
-                if (sdebug != null) {
d1af5a
-                    sdebug.println
d1af5a
-                        ("unable to load security properties from " +
d1af5a
-                         SYSTEM_PROPERTIES);
d1af5a
-                    e.printStackTrace();
d1af5a
-                }
d1af5a
             }
d1af5a
         }
d1af5a
 
d1af5a
diff --git a/src/java.base/share/classes/javopenjdk.orig///security/SystemConfigurator.java openjdk///src/java.base/share/classes/java/security/SystemConfigurator.java
d1af5a
new file mode 100644
d1af5a
--- /dev/null
d1af5a
+++ openjdk/src/java.base/share/classes/java/security/SystemConfigurator.java
d1af5a
@@ -0,0 +1,151 @@
d1af5a
+/*
d1af5a
+ * Copyright (c) 2019, Red Hat, Inc.
d1af5a
+ *
d1af5a
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
d1af5a
+ *
d1af5a
+ * This code is free software; you can redistribute it and/or modify it
d1af5a
+ * under the terms of the GNU General Public License version 2 only, as
d1af5a
+ * published by the Free Software Foundation.
d1af5a
+ *
d1af5a
+ * This code is distributed in the hope that it will be useful, but WITHOUT
d1af5a
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
d1af5a
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
d1af5a
+ * version 2 for more details (a copy is included in the LICENSE file that
d1af5a
+ * accompanied this code).
d1af5a
+ *
d1af5a
+ * You should have received a copy of the GNU General Public License version
d1af5a
+ * 2 along with this work; if not, write to the Free Software Foundation,
d1af5a
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
d1af5a
+ *
d1af5a
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
d1af5a
+ * or visit www.oracle.com if you need additional information or have any
d1af5a
+ * questions.
d1af5a
+ */
d1af5a
+
d1af5a
+package java.security;
d1af5a
+
d1af5a
+import java.io.BufferedInputStream;
d1af5a
+import java.io.FileInputStream;
d1af5a
+import java.io.IOException;
d1af5a
+
d1af5a
+import java.nio.file.Files;
d1af5a
+import java.nio.file.Path;
d1af5a
+
d1af5a
+import java.util.Iterator;
d1af5a
+import java.util.Map.Entry;
d1af5a
+import java.util.Properties;
d1af5a
+import java.util.function.Consumer;
d1af5a
+import java.util.regex.Matcher;
d1af5a
+import java.util.regex.Pattern;
d1af5a
+
d1af5a
+import sun.security.util.Debug;
d1af5a
+
d1af5a
+/**
d1af5a
+ * Internal class to align OpenJDK with global crypto-policies.
d1af5a
+ * Called from java.security.Security class initialization,
d1af5a
+ * during startup.
d1af5a
+ *
d1af5a
+ */
d1af5a
+
d1af5a
+class SystemConfigurator {
d1af5a
+
d1af5a
+    private static final Debug sdebug =
d1af5a
+            Debug.getInstance("properties");
d1af5a
+
d1af5a
+    private static final String CRYPTO_POLICIES_BASE_DIR =
d1af5a
+            "/etc/crypto-policies";
d1af5a
+
d1af5a
+    private static final String CRYPTO_POLICIES_JAVA_CONFIG =
d1af5a
+            CRYPTO_POLICIES_BASE_DIR + "/back-ends/java.config";
d1af5a
+
d1af5a
+    private static final String CRYPTO_POLICIES_CONFIG =
d1af5a
+            CRYPTO_POLICIES_BASE_DIR + "/config";
d1af5a
+
d1af5a
+    private static final class SecurityProviderInfo {
d1af5a
+        int number;
d1af5a
+        String key;
d1af5a
+        String value;
d1af5a
+        SecurityProviderInfo(int number, String key, String value) {
d1af5a
+            this.number = number;
d1af5a
+            this.key = key;
d1af5a
+            this.value = value;
d1af5a
+        }
d1af5a
+    }
d1af5a
+
d1af5a
+    /*
d1af5a
+     * Invoked when java.security.Security class is initialized, if
d1af5a
+     * java.security.disableSystemPropertiesFile property is not set and
d1af5a
+     * security.useSystemPropertiesFile is true.
d1af5a
+     */
d1af5a
+    static boolean configure(Properties props) {
d1af5a
+        boolean loadedProps = false;
d1af5a
+
d1af5a
+        try (BufferedInputStream bis =
d1af5a
+                new BufferedInputStream(
d1af5a
+                        new FileInputStream(CRYPTO_POLICIES_JAVA_CONFIG))) {
d1af5a
+            props.load(bis);
d1af5a
+            loadedProps = true;
d1af5a
+            if (sdebug != null) {
d1af5a
+                sdebug.println("reading system security properties file " +
d1af5a
+                        CRYPTO_POLICIES_JAVA_CONFIG);
d1af5a
+                sdebug.println(props.toString());
d1af5a
+            }
d1af5a
+        } catch (IOException e) {
d1af5a
+            if (sdebug != null) {
d1af5a
+                sdebug.println("unable to load security properties from " +
d1af5a
+                        CRYPTO_POLICIES_JAVA_CONFIG);
d1af5a
+                e.printStackTrace();
d1af5a
+            }
d1af5a
+        }
d1af5a
+
d1af5a
+        try {
d1af5a
+            if (enableFips()) {
d1af5a
+                if (sdebug != null) { sdebug.println("FIPS mode detected"); }
d1af5a
+                loadedProps = false;
d1af5a
+                // Remove all security providers
d1af5a
+                Iterator<Entry<Object, Object>> i = props.entrySet().iterator();
d1af5a
+                while (i.hasNext()) {
d1af5a
+                    Entry<Object, Object> e = i.next();
d1af5a
+                    if (((String) e.getKey()).startsWith("security.provider")) {
d1af5a
+                        if (sdebug != null) { sdebug.println("Removing provider: " + e); }
d1af5a
+                        i.remove();
d1af5a
+                    }
d1af5a
+                }
d1af5a
+                // Add FIPS security providers
d1af5a
+                String fipsProviderValue = null;
d1af5a
+                for (int n = 1;
d1af5a
+                     (fipsProviderValue = (String) props.get("fips.provider." + n)) != null; n++) {
d1af5a
+                    String fipsProviderKey = "security.provider." + n;
d1af5a
+                    if (sdebug != null) {
d1af5a
+                        sdebug.println("Adding provider " + n + ": " +
d1af5a
+                                fipsProviderKey + "=" + fipsProviderValue);
d1af5a
+                    }
d1af5a
+                    props.put(fipsProviderKey, fipsProviderValue);
d1af5a
+                }
d1af5a
+                loadedProps = true;
d1af5a
+            }
d1af5a
+        } catch (Exception e) {
d1af5a
+            if (sdebug != null) {
d1af5a
+                sdebug.println("unable to load FIPS configuration");
d1af5a
+                e.printStackTrace();
d1af5a
+            }
d1af5a
+        }
d1af5a
+        return loadedProps;
d1af5a
+    }
d1af5a
+
d1af5a
+    /*
d1af5a
+     * FIPS is enabled only if crypto-policies are set to "FIPS"
d1af5a
+     * and the com.redhat.fips property is true.
d1af5a
+     */
d1af5a
+    private static boolean enableFips() throws Exception {
d1af5a
+        boolean fipsEnabled = Boolean.valueOf(System.getProperty("com.redhat.fips", "true"));
d1af5a
+        if (fipsEnabled) {
d1af5a
+            String cryptoPoliciesConfig = new String(Files.readAllBytes(Path.of(CRYPTO_POLICIES_CONFIG)));
d1af5a
+            if (sdebug != null) { sdebug.println("Crypto config:\n" + cryptoPoliciesConfig); }
d1af5a
+            Pattern pattern = Pattern.compile("^FIPS$", Pattern.MULTILINE);
d1af5a
+            return pattern.matcher(cryptoPoliciesConfig).find();
d1af5a
+        } else {
d1af5a
+            return false;
d1af5a
+        }
d1af5a
+    }
d1af5a
+}
d1af5a
diff --git openjdk.orig///src/java.base/share/conf/security/java.security openjdk///src/java.base/share/conf/security/java.security
d1af5a
--- openjdk.orig/src/java.base/share/conf/security/java.security
d1af5a
+++ openjdk/src/java.base/share/conf/security/java.security
d1af5a
@@ -87,6 +87,14 @@
d1af5a
 #security.provider.tbd=SunPKCS11 ${java.home}/lib/security/nss.cfg
d1af5a
 
d1af5a
 #
d1af5a
+# Security providers used when global crypto-policies are set to FIPS.
d1af5a
+#
d1af5a
+fips.provider.1=SunPKCS11 ${java.home}/conf/security/nss.fips.cfg
d1af5a
+fips.provider.2=SUN
d1af5a
+fips.provider.3=SunEC
d1af5a
+fips.provider.4=SunJSSE
d1af5a
+
d1af5a
+#
d1af5a
 # A list of preferred providers for specific algorithms. These providers will
d1af5a
 # be searched for matching algorithms before the list of registered providers.
d1af5a
 # Entries containing errors (parsing, etc) will be ignored. Use the