diff -r 4ebc2e2fb97c -r 71c04702a3d5 src/java.base/share/classes/sun/security/ssl/SunJSSE.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java Tue Sep 12 19:03:39 2017 +0200 @@ -0,0 +1,256 @@ +/* + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * 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. + */ + + +package sun.security.ssl; + +import java.security.*; +import static sun.security.util.SecurityConstants.PROVIDER_VER; + +/** + * The JSSE provider. + * + * The RSA implementation has been removed from JSSE, but we still need to + * register the same algorithms for compatibility. We just point to the RSA + * implementation in the SunRsaSign provider. This works because all classes + * are in the bootclasspath and therefore loaded by the same classloader. + * + * SunJSSE now supports an experimental FIPS compliant mode when used with an + * appropriate FIPS certified crypto provider. In FIPS mode, we: + * . allow only TLS 1.0 or later + * . allow only FIPS approved ciphersuites + * . perform all crypto in the FIPS crypto provider + * + * It is currently not possible to use both FIPS compliant SunJSSE and + * standard JSSE at the same time because of the various static data structures + * we use. + * + * However, we do want to allow FIPS mode to be enabled at runtime and without + * editing the java.security file. That means we need to allow + * Security.removeProvider("SunJSSE") to work, which creates an instance of + * this class in non-FIPS mode. That is why we delay the selection of the mode + * as long as possible. This is until we open an SSL/TLS connection and the + * data structures need to be initialized or until SunJSSE is initialized in + * FIPS mode. + * + */ +public abstract class SunJSSE extends java.security.Provider { + + private static final long serialVersionUID = 3231825739635378733L; + + private static String info = "Sun JSSE provider" + + "(PKCS12, SunX509/PKIX key/trust factories, " + + "SSLv3/TLSv1/TLSv1.1/TLSv1.2/DTLSv1.0/DTLSv1.2)"; + + private static String fipsInfo = + "Sun JSSE provider (FIPS mode, crypto provider "; + + // tri-valued flag: + // null := no final decision made + // false := data structures initialized in non-FIPS mode + // true := data structures initialized in FIPS mode + private static Boolean fips; + + // the FIPS certificate crypto provider that we use to perform all crypto + // operations. null in non-FIPS mode + static java.security.Provider cryptoProvider; + + protected static synchronized boolean isFIPS() { + if (fips == null) { + fips = false; + } + return fips; + } + + // ensure we can use FIPS mode using the specified crypto provider. + // enable FIPS mode if not already enabled. + private static synchronized void ensureFIPS(java.security.Provider p) { + if (fips == null) { + fips = true; + cryptoProvider = p; + } else { + if (fips == false) { + throw new ProviderException + ("SunJSSE already initialized in non-FIPS mode"); + } + if (cryptoProvider != p) { + throw new ProviderException + ("SunJSSE already initialized with FIPS crypto provider " + + cryptoProvider); + } + } + } + + // standard constructor + protected SunJSSE() { + super("SunJSSE", PROVIDER_VER, info); + subclassCheck(); + if (Boolean.TRUE.equals(fips)) { + throw new ProviderException + ("SunJSSE is already initialized in FIPS mode"); + } + registerAlgorithms(false); + } + + // preferred constructor to enable FIPS mode at runtime + protected SunJSSE(java.security.Provider cryptoProvider){ + this(checkNull(cryptoProvider), cryptoProvider.getName()); + } + + // constructor to enable FIPS mode from java.security file + protected SunJSSE(String cryptoProvider){ + this(null, checkNull(cryptoProvider)); + } + + private static T checkNull(T t) { + if (t == null) { + throw new ProviderException("cryptoProvider must not be null"); + } + return t; + } + + private SunJSSE(java.security.Provider cryptoProvider, + String providerName) { + super("SunJSSE", PROVIDER_VER, fipsInfo + providerName + ")"); + subclassCheck(); + if (cryptoProvider == null) { + // Calling Security.getProvider() will cause other providers to be + // loaded. That is not good but unavoidable here. + cryptoProvider = Security.getProvider(providerName); + if (cryptoProvider == null) { + throw new ProviderException + ("Crypto provider not installed: " + providerName); + } + } + ensureFIPS(cryptoProvider); + registerAlgorithms(true); + } + + private void registerAlgorithms(final boolean isfips) { + AccessController.doPrivileged(new PrivilegedAction<>() { + @Override + public Object run() { + doRegister(isfips); + return null; + } + }); + } + + private void doRegister(boolean isfips) { + if (isfips == false) { + put("KeyFactory.RSA", + "sun.security.rsa.RSAKeyFactory"); + put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA"); + put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA"); + + put("KeyPairGenerator.RSA", + "sun.security.rsa.RSAKeyPairGenerator"); + put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA"); + put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA"); + + put("Signature.MD2withRSA", + "sun.security.rsa.RSASignature$MD2withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", + "MD2withRSA"); + + put("Signature.MD5withRSA", + "sun.security.rsa.RSASignature$MD5withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", + "MD5withRSA"); + + put("Signature.SHA1withRSA", + "sun.security.rsa.RSASignature$SHA1withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", + "SHA1withRSA"); + put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA"); + put("Alg.Alias.Signature.OID.1.3.14.3.2.29", "SHA1withRSA"); + + } + put("Signature.MD5andSHA1withRSA", + "sun.security.ssl.RSASignature"); + + put("KeyManagerFactory.SunX509", + "sun.security.ssl.KeyManagerFactoryImpl$SunX509"); + put("KeyManagerFactory.NewSunX509", + "sun.security.ssl.KeyManagerFactoryImpl$X509"); + put("Alg.Alias.KeyManagerFactory.PKIX", "NewSunX509"); + + put("TrustManagerFactory.SunX509", + "sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory"); + put("TrustManagerFactory.PKIX", + "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory"); + put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX"); + put("Alg.Alias.TrustManagerFactory.X509", "PKIX"); + put("Alg.Alias.TrustManagerFactory.X.509", "PKIX"); + + put("SSLContext.TLSv1", + "sun.security.ssl.SSLContextImpl$TLS10Context"); + put("SSLContext.TLSv1.1", + "sun.security.ssl.SSLContextImpl$TLS11Context"); + put("SSLContext.TLSv1.2", + "sun.security.ssl.SSLContextImpl$TLS12Context"); + put("SSLContext.TLS", + "sun.security.ssl.SSLContextImpl$TLSContext"); + if (isfips == false) { + put("Alg.Alias.SSLContext.SSL", "TLS"); + put("Alg.Alias.SSLContext.SSLv3", "TLSv1"); + } + + put("SSLContext.DTLSv1.0", + "sun.security.ssl.SSLContextImpl$DTLS10Context"); + put("SSLContext.DTLSv1.2", + "sun.security.ssl.SSLContextImpl$DTLS12Context"); + put("SSLContext.DTLS", + "sun.security.ssl.SSLContextImpl$DTLSContext"); + + put("SSLContext.Default", + "sun.security.ssl.SSLContextImpl$DefaultSSLContext"); + + /* + * KeyStore + */ + put("KeyStore.PKCS12", + "sun.security.pkcs12.PKCS12KeyStore"); + } + + // com.sun.net.ssl.internal.ssl.Provider has been deprecated since JDK 9 + @SuppressWarnings("deprecation") + private void subclassCheck() { + if (getClass() != com.sun.net.ssl.internal.ssl.Provider.class) { + throw new AssertionError("Illegal subclass: " + getClass()); + } + } + + @Override + @SuppressWarnings("deprecation") + protected final void finalize() throws Throwable { + // empty + super.finalize(); + } + +}