diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index de2845fb550d8..b1e416b90f417 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java @@ -1203,6 +1203,39 @@ public Set getServices() { return serviceSet; } + /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ + private static final class RedHatFIPSFilter { + static final boolean IS_ON = Boolean.parseBoolean( + Security.getProperty("__redhat_fips_filter__")); + private static final Set ANY_SERVICE_TYPE = Set.of(); + private static final Map> ALLOW_LIST = Map.of( + "SunPKCS11-FIPS", ANY_SERVICE_TYPE, + "SUN", Set.of( + "AlgorithmParameterGenerator", + "AlgorithmParameters", "CertificateFactory", + "CertPathBuilder", "CertPathValidator", "CertStore", + "Configuration", "KeyStore"), + "SunEC", Set.of( + "AlgorithmParameters", "KeyFactory"), + "SunJSSE", ANY_SERVICE_TYPE, + "SunJCE", Set.of( + "AlgorithmParameters", + "AlgorithmParameterGenerator", "KeyFactory", + "SecretKeyFactory"), + "SunRsaSign", Set.of( + "KeyFactory", "AlgorithmParameters"), + "XMLDSig", ANY_SERVICE_TYPE + ); + + static boolean isAllowed(String provName, String serviceType) { + Set allowedServiceTypes = ALLOW_LIST.get(provName); + return allowedServiceTypes != null && + (allowedServiceTypes == ANY_SERVICE_TYPE || + allowedServiceTypes.contains(serviceType)); + } + } + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + /** * Add a service. If a service of the same type with the same algorithm * name exists, and it was added using {@link #putService putService()}, @@ -1231,6 +1264,15 @@ protected void putService(Service s) { ("service.getProvider() must match this Provider object"); } String type = s.getType(); + /* vvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvv */ + if (RedHatFIPSFilter.IS_ON && !RedHatFIPSFilter.isAllowed(name, type)) { + if (debug != null) { + debug.println("The previous " + name + ".putService() call " + + "was skipped by " + RedHatFIPSFilter.class.getName()); + } + return; + } + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ String algorithm = s.getAlgorithm(); ServiceKey key = new ServiceKey(type, algorithm, true); implRemoveService(serviceMap.get(key)); diff --git a/src/java.base/share/classes/java/security/Security.java b/src/java.base/share/classes/java/security/Security.java index 6969fe8a8e142..4501d5971c46c 100644 --- a/src/java.base/share/classes/java/security/Security.java +++ b/src/java.base/share/classes/java/security/Security.java @@ -323,7 +323,27 @@ public Properties getInitialProperties() { } private static void initialize() { + /* vvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvv */ + /* This 'include'-directives-only magic property is an internal */ + /* implementation detail that could (and probably will!) change. */ + /* Red Hat customers should NOT rely on this for their own use. */ + String fipsKernelFlag = "/proc/sys/crypto/fips_enabled"; + boolean fipsModeOn; + try (InputStream is = new java.io.FileInputStream(fipsKernelFlag)) { + fipsModeOn = is.read() == '1'; + } catch (IOException ioe) { + fipsModeOn = false; + if (sdebug != null) { + sdebug.println("Failed to read FIPS kernel file: " + ioe); + } + } + String fipsMagicPropName = "__redhat_fips__"; + System.setProperty(fipsMagicPropName, "" + fipsModeOn); + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ SecPropLoader.loadAll(); + /* vvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvv */ + System.clearProperty(fipsMagicPropName); + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ initialSecurityProperties = (Properties) props.clone(); if (sdebug != null) { for (String key : props.stringPropertyNames()) {