1 /* 2 * Copyright (c) 1999, 2012, 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 package sun.security.ssl; 27 28 import java.util.*; 29 import java.io.*; 30 import java.security.*; 31 import java.security.cert.*; 32 import javax.net.ssl.*; 33 import sun.security.action.GetPropertyAction; 34 import sun.security.action.OpenFileInputStreamAction; 35 import sun.security.validator.Validator; 36 37 abstract class TrustManagerFactoryImpl extends TrustManagerFactorySpi { 38 39 private static final Debug debug = Debug.getInstance("ssl"); 40 private X509TrustManager trustManager = null; 41 private boolean isInitialized = false; 42 43 TrustManagerFactoryImpl() { 44 // empty 45 } 46 47 @Override 48 protected void engineInit(KeyStore ks) throws KeyStoreException { 49 if (ks == null) { 50 try { 51 ks = getCacertsKeyStore("trustmanager"); 52 } catch (SecurityException se) { 53 // eat security exceptions but report other throwables 54 if (debug != null && Debug.isOn("trustmanager")) { 55 System.out.println( 56 "SunX509: skip default keystore: " + se); 57 } 58 } catch (Error err) { 59 if (debug != null && Debug.isOn("trustmanager")) { 60 System.out.println( 61 "SunX509: skip default keystore: " + err); 62 } 63 throw err; 64 } catch (RuntimeException re) { 65 if (debug != null && Debug.isOn("trustmanager")) { 66 System.out.println( 67 "SunX509: skip default keystore: " + re); 68 } 69 throw re; 70 } catch (Exception e) { 71 if (debug != null && Debug.isOn("trustmanager")) { 72 System.out.println( 73 "SunX509: skip default keystore: " + e); 74 } 75 throw new KeyStoreException( 76 "problem accessing trust store" + e); 77 } 78 } 79 trustManager = getInstance(ks); 80 isInitialized = true; 81 } 82 83 abstract X509TrustManager getInstance(KeyStore ks) throws KeyStoreException; 84 85 abstract X509TrustManager getInstance(ManagerFactoryParameters spec) 86 throws InvalidAlgorithmParameterException; 87 88 @Override 89 protected void engineInit(ManagerFactoryParameters spec) throws 90 InvalidAlgorithmParameterException { 91 trustManager = getInstance(spec); 92 isInitialized = true; 93 } 94 95 /** 96 * Returns one trust manager for each type of trust material. 97 */ 98 @Override 99 protected TrustManager[] engineGetTrustManagers() { 100 if (!isInitialized) { 101 throw new IllegalStateException( 102 "TrustManagerFactoryImpl is not initialized"); 103 } 104 return new TrustManager[] { trustManager }; 105 } 106 107 /* 108 * Try to get an InputStream based on the file we pass in. 109 */ 110 private static FileInputStream getFileInputStream(final File file) 111 throws Exception { 112 return AccessController.doPrivileged( 113 new OpenFileInputStreamAction(file, true)); 114 } 115 116 /** 117 * Returns the keystore with the configured CA certificates. 118 */ 119 static KeyStore getCacertsKeyStore(String dbgname) throws Exception { 120 FileInputStream fis = null; 121 final String sep = File.separator; 122 KeyStore ks = null; 123 124 final Properties props = GetPropertyAction.getProperties(); 125 126 /* 127 * Try: 128 * javax.net.ssl.trustStore (if this variable exists, stop) 129 * jssecacerts 130 * cacerts 131 * 132 * If none exists, we use an empty keystore. 133 */ 134 135 try { 136 File storeFile; 137 String storeFileName = props 138 .getProperty("javax.net.ssl.trustStore"); 139 if (!"NONE".equals(storeFileName)) { 140 if (storeFileName != null) { 141 storeFile = new File(storeFileName); 142 fis = getFileInputStream(storeFile); 143 } else { 144 String javaHome = props.getProperty("java.home"); 145 storeFile = new File(javaHome + sep + "lib" + sep 146 + "security" + sep + 147 "jssecacerts"); 148 if ((fis = getFileInputStream(storeFile)) == null) { 149 storeFile = new File(javaHome + sep + "lib" + sep 150 + "security" + sep + 151 "cacerts"); 152 fis = getFileInputStream(storeFile); 153 } 154 } 155 156 if (fis != null) { 157 storeFileName = storeFile.getPath(); 158 } else { 159 storeFileName = "No File Available, using empty keystore."; 160 } 161 } 162 163 String defaultTrustStoreType = props.getProperty( 164 "javax.net.ssl.trustStoreType", 165 KeyStore.getDefaultType()); 166 String defaultTrustStoreProvider = props.getProperty( 167 "javax.net.ssl.trustStoreProvider", ""); 168 if (debug != null && Debug.isOn(dbgname)) { 169 System.out.println("trustStore is: " + storeFileName); 170 System.out.println("trustStore type is : " + 171 defaultTrustStoreType); 172 System.out.println("trustStore provider is : " + 173 defaultTrustStoreProvider); 174 } 175 176 /* 177 * Try to initialize trust store. 178 */ 179 if (defaultTrustStoreType.length() != 0) { 180 if (debug != null && Debug.isOn(dbgname)) { 181 System.out.println("init truststore"); 182 } 183 if (defaultTrustStoreProvider.length() == 0) { 184 ks = KeyStore.getInstance(defaultTrustStoreType); 185 } else { 186 ks = KeyStore.getInstance(defaultTrustStoreType, 187 defaultTrustStoreProvider); 188 } 189 char[] passwd = null; 190 String defaultTrustStorePassword = props 191 .getProperty("javax.net.ssl.trustStorePassword", ""); 192 if (defaultTrustStorePassword.length() != 0) 193 passwd = defaultTrustStorePassword.toCharArray(); 194 195 // if trustStore is NONE, fis will be null 196 ks.load(fis, passwd); 197 198 // Zero out the temporary password storage 199 if (passwd != null) { 200 for (int i = 0; i < passwd.length; i++) { 201 passwd[i] = (char)0; 202 } 203 } 204 } 205 } finally { 206 if (fis != null) { 207 fis.close(); 208 } 209 } 210 211 return ks; 212 } 213 214 public static final class SimpleFactory extends TrustManagerFactoryImpl { 215 @Override 216 X509TrustManager getInstance(KeyStore ks) throws KeyStoreException { 217 return new X509TrustManagerImpl(Validator.TYPE_SIMPLE, ks); 218 } 219 @Override 220 X509TrustManager getInstance(ManagerFactoryParameters spec) 221 throws InvalidAlgorithmParameterException { 222 throw new InvalidAlgorithmParameterException 223 ("SunX509 TrustManagerFactory does not use " 224 + "ManagerFactoryParameters"); 225 } 226 } 227 228 public static final class PKIXFactory extends TrustManagerFactoryImpl { 229 @Override 230 X509TrustManager getInstance(KeyStore ks) throws KeyStoreException { 231 return new X509TrustManagerImpl(Validator.TYPE_PKIX, ks); 232 } 233 @Override 234 X509TrustManager getInstance(ManagerFactoryParameters spec) 235 throws InvalidAlgorithmParameterException { 236 if (spec instanceof CertPathTrustManagerParameters == false) { 237 throw new InvalidAlgorithmParameterException 238 ("Parameters must be CertPathTrustManagerParameters"); 239 } 240 CertPathParameters params = 241 ((CertPathTrustManagerParameters)spec).getParameters(); 242 if (params instanceof PKIXBuilderParameters == false) { 243 throw new InvalidAlgorithmParameterException 244 ("Encapsulated parameters must be PKIXBuilderParameters"); 245 } 246 PKIXBuilderParameters pkixParams = (PKIXBuilderParameters)params; 247 return new X509TrustManagerImpl(Validator.TYPE_PKIX, pkixParams); 248 } 249 } 250 }