1/* 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27package sun.security.ssl; 28 29import java.security.*; 30 31/** 32 * The JSSE provider. 33 * 34 * The RSA implementation has been removed from JSSE, but we still need to 35 * register the same algorithms for compatibility. We just point to the RSA 36 * implementation in the SunRsaSign provider. This works because all classes 37 * are in the bootclasspath and therefore loaded by the same classloader. 38 * 39 * SunJSSE now supports an experimental FIPS compliant mode when used with an 40 * appropriate FIPS certified crypto provider. In FIPS mode, we: 41 * . allow only TLS 1.0 or later 42 * . allow only FIPS approved ciphersuites 43 * . perform all crypto in the FIPS crypto provider 44 * 45 * It is currently not possible to use both FIPS compliant SunJSSE and 46 * standard JSSE at the same time because of the various static data structures 47 * we use. 48 * 49 * However, we do want to allow FIPS mode to be enabled at runtime and without 50 * editing the java.security file. That means we need to allow 51 * Security.removeProvider("SunJSSE") to work, which creates an instance of 52 * this class in non-FIPS mode. That is why we delay the selection of the mode 53 * as long as possible. This is until we open an SSL/TLS connection and the 54 * data structures need to be initialized or until SunJSSE is initialized in 55 * FIPS mode. 56 * 57 */ 58public abstract class SunJSSE extends java.security.Provider { 59 60 private static final long serialVersionUID = 3231825739635378733L; 61 62 private static String info = "Sun JSSE provider" + 63 "(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)"; 64 65 private static String fipsInfo = 66 "Sun JSSE provider (FIPS mode, crypto provider "; 67 68 // tri-valued flag: 69 // null := no final decision made 70 // false := data structures initialized in non-FIPS mode 71 // true := data structures initialized in FIPS mode 72 private static Boolean fips; 73 74 // the FIPS certificate crypto provider that we use to perform all crypto 75 // operations. null in non-FIPS mode 76 static java.security.Provider cryptoProvider; 77 78 protected static synchronized boolean isFIPS() { 79 if (fips == null) { 80 fips = false; 81 } 82 return fips; 83 } 84 85 // ensure we can use FIPS mode using the specified crypto provider. 86 // enable FIPS mode if not already enabled. 87 private static synchronized void ensureFIPS(java.security.Provider p) { 88 if (fips == null) { 89 fips = true; 90 cryptoProvider = p; 91 } else { 92 if (fips == false) { 93 throw new ProviderException 94 ("SunJSSE already initialized in non-FIPS mode"); 95 } 96 if (cryptoProvider != p) { 97 throw new ProviderException 98 ("SunJSSE already initialized with FIPS crypto provider " 99 + cryptoProvider); 100 } 101 } 102 } 103 104 // standard constructor 105 protected SunJSSE() { 106 super("SunJSSE", 1.7d, info); 107 subclassCheck(); 108 if (Boolean.TRUE.equals(fips)) { 109 throw new ProviderException 110 ("SunJSSE is already initialized in FIPS mode"); 111 } 112 registerAlgorithms(false); 113 } 114 115 // prefered constructor to enable FIPS mode at runtime 116 protected SunJSSE(java.security.Provider cryptoProvider){ 117 this(checkNull(cryptoProvider), cryptoProvider.getName()); 118 } 119 120 // constructor to enable FIPS mode from java.security file 121 protected SunJSSE(String cryptoProvider){ 122 this(null, checkNull(cryptoProvider)); 123 } 124 125 private static <T> T checkNull(T t) { 126 if (t == null) { 127 throw new ProviderException("cryptoProvider must not be null"); 128 } 129 return t; 130 } 131 132 private SunJSSE(java.security.Provider cryptoProvider, 133 String providerName) { 134 super("SunJSSE", 1.6d, fipsInfo + providerName + ")"); 135 subclassCheck(); 136 if (cryptoProvider == null) { 137 // Calling Security.getProvider() will cause other providers to be 138 // loaded. That is not good but unavoidable here. 139 cryptoProvider = Security.getProvider(providerName); 140 if (cryptoProvider == null) { 141 throw new ProviderException 142 ("Crypto provider not installed: " + providerName); 143 } 144 } 145 ensureFIPS(cryptoProvider); 146 registerAlgorithms(true); 147 } 148 149 private void registerAlgorithms(final boolean isfips) { 150 AccessController.doPrivileged(new PrivilegedAction<Object>() { 151 public Object run() { 152 doRegister(isfips); 153 return null; 154 } 155 }); 156 } 157 158 private void doRegister(boolean isfips) { 159 if (isfips == false) { 160 put("KeyFactory.RSA", 161 "sun.security.rsa.RSAKeyFactory"); 162 put("Alg.Alias.KeyFactory.1.2.840.113549.1.1", "RSA"); 163 put("Alg.Alias.KeyFactory.OID.1.2.840.113549.1.1", "RSA"); 164 165 put("KeyPairGenerator.RSA", 166 "sun.security.rsa.RSAKeyPairGenerator"); 167 put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA"); 168 put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA"); 169 170 put("Signature.MD2withRSA", 171 "sun.security.rsa.RSASignature$MD2withRSA"); 172 put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA"); 173 put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", 174 "MD2withRSA"); 175 176 put("Signature.MD5withRSA", 177 "sun.security.rsa.RSASignature$MD5withRSA"); 178 put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); 179 put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", 180 "MD5withRSA"); 181 182 put("Signature.SHA1withRSA", 183 "sun.security.rsa.RSASignature$SHA1withRSA"); 184 put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); 185 put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", 186 "SHA1withRSA"); 187 put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA"); 188 put("Alg.Alias.Signature.OID.1.3.14.3.2.29", "SHA1withRSA"); 189 190 } 191 put("Signature.MD5andSHA1withRSA", 192 "sun.security.ssl.RSASignature"); 193 194 put("KeyManagerFactory.SunX509", 195 "sun.security.ssl.KeyManagerFactoryImpl$SunX509"); 196 put("KeyManagerFactory.NewSunX509", 197 "sun.security.ssl.KeyManagerFactoryImpl$X509"); 198 put("Alg.Alias.KeyManagerFactory.PKIX", "NewSunX509"); 199 200 put("TrustManagerFactory.SunX509", 201 "sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory"); 202 put("TrustManagerFactory.PKIX", 203 "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory"); 204 put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX"); 205 put("Alg.Alias.TrustManagerFactory.X509", "PKIX"); 206 put("Alg.Alias.TrustManagerFactory.X.509", "PKIX"); 207 208 put("SSLContext.TLSv1", 209 "sun.security.ssl.SSLContextImpl$TLS10Context"); 210 put("Alg.Alias.SSLContext.TLS", "TLSv1"); 211 if (isfips == false) { 212 put("Alg.Alias.SSLContext.SSL", "TLSv1"); 213 put("Alg.Alias.SSLContext.SSLv3", "TLSv1"); 214 } 215 216 put("SSLContext.TLSv1.1", 217 "sun.security.ssl.SSLContextImpl$TLS11Context"); 218 put("SSLContext.TLSv1.2", 219 "sun.security.ssl.SSLContextImpl$TLS12Context"); 220 put("SSLContext.Default", 221 "sun.security.ssl.SSLContextImpl$DefaultSSLContext"); 222 223 /* 224 * KeyStore 225 */ 226 put("KeyStore.PKCS12", 227 "sun.security.pkcs12.PKCS12KeyStore"); 228 } 229 230 private void subclassCheck() { 231 if (getClass() != com.sun.net.ssl.internal.ssl.Provider.class) { 232 throw new AssertionError("Illegal subclass: " + getClass()); 233 } 234 } 235 236 @Override 237 protected final void finalize() throws Throwable { 238 // empty 239 super.finalize(); 240 } 241 242} 243