blob: 5fed15fc1f0a3fee15e137ae8488c3714edb9360 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.security.ssl;
27
28import java.util.*;
29import java.io.*;
30import java.math.*;
31import java.security.*;
32import java.security.cert.*;
33import javax.net.ssl.*;
34import java.security.spec.AlgorithmParameterSpec;
35
36import sun.security.validator.Validator;
37
38abstract class TrustManagerFactoryImpl extends TrustManagerFactorySpi {
39
40 private static final Debug debug = Debug.getInstance("ssl");
41 private X509TrustManager trustManager = null;
42 private boolean isInitialized = false;
43
44 TrustManagerFactoryImpl() {
45 // empty
46 }
47
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 protected void engineInit(ManagerFactoryParameters spec) throws
89 InvalidAlgorithmParameterException {
90 trustManager = getInstance(spec);
91 isInitialized = true;
92 }
93
94 /**
95 * Returns one trust manager for each type of trust material.
96 */
97 protected TrustManager[] engineGetTrustManagers() {
98 if (!isInitialized) {
99 throw new IllegalStateException(
100 "TrustManagerFactoryImpl is not initialized");
101 }
102 return new TrustManager[] { trustManager };
103 }
104
105 /*
106 * Try to get an InputStream based on the file we pass in.
107 */
108 private static FileInputStream getFileInputStream(final File file)
109 throws Exception {
110 return AccessController.doPrivileged(
111 new PrivilegedExceptionAction<FileInputStream>() {
112 public FileInputStream run() throws Exception {
113 try {
114 if (file.exists()) {
115 return new FileInputStream(file);
116 } else {
117 return null;
118 }
119 } catch (FileNotFoundException e) {
120 // couldn't find it, oh well.
121 return null;
122 }
123 }
124 });
125 }
126
127 /**
128 * Returns the keystore with the configured CA certificates.
129 */
130 static KeyStore getCacertsKeyStore(String dbgname) throws Exception
131 {
132 String storeFileName = null;
133 File storeFile = null;
134 FileInputStream fis = null;
135 String defaultTrustStoreType;
136 String defaultTrustStoreProvider;
137 final HashMap<String,String> props = new HashMap<String,String>();
138 final String sep = File.separator;
139 KeyStore ks = null;
140
141 AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
142 public Void run() throws Exception {
143 props.put("trustStore", System.getProperty(
144 "javax.net.ssl.trustStore"));
145 props.put("javaHome", System.getProperty(
146 "java.home"));
147 props.put("trustStoreType", System.getProperty(
148 "javax.net.ssl.trustStoreType",
149 KeyStore.getDefaultType()));
150 props.put("trustStoreProvider", System.getProperty(
151 "javax.net.ssl.trustStoreProvider", ""));
152 props.put("trustStorePasswd", System.getProperty(
153 "javax.net.ssl.trustStorePassword", ""));
154 return null;
155 }
156 });
157
158 /*
159 * Try:
160 * javax.net.ssl.trustStore (if this variable exists, stop)
161 * jssecacerts
162 * cacerts
163 *
164 * If none exists, we use an empty keystore.
165 */
166
167 storeFileName = props.get("trustStore");
168 if (!"NONE".equals(storeFileName)) {
169 if (storeFileName != null) {
170 storeFile = new File(storeFileName);
171 fis = getFileInputStream(storeFile);
172 } else {
173 String javaHome = props.get("javaHome");
174 storeFile = new File(javaHome + sep + "lib" + sep
175 + "security" + sep +
176 "jssecacerts");
177 if ((fis = getFileInputStream(storeFile)) == null) {
178 storeFile = new File(javaHome + sep + "lib" + sep
179 + "security" + sep +
180 "cacerts");
181 fis = getFileInputStream(storeFile);
182 }
183 }
184
185 if (fis != null) {
186 storeFileName = storeFile.getPath();
187 } else {
188 storeFileName = "No File Available, using empty keystore.";
189 }
190 }
191
192 defaultTrustStoreType = props.get("trustStoreType");
193 defaultTrustStoreProvider = props.get("trustStoreProvider");
194 if (debug != null && Debug.isOn(dbgname)) {
195 System.out.println("trustStore is: " + storeFileName);
196 System.out.println("trustStore type is : " +
197 defaultTrustStoreType);
198 System.out.println("trustStore provider is : " +
199 defaultTrustStoreProvider);
200 }
201
202 /*
203 * Try to initialize trust store.
204 */
205 if (defaultTrustStoreType.length() != 0) {
206 if (debug != null && Debug.isOn(dbgname)) {
207 System.out.println("init truststore");
208 }
209 if (defaultTrustStoreProvider.length() == 0) {
210 ks = KeyStore.getInstance(defaultTrustStoreType);
211 } else {
212 ks = KeyStore.getInstance(defaultTrustStoreType,
213 defaultTrustStoreProvider);
214 }
215 char[] passwd = null;
216 String defaultTrustStorePassword = props.get("trustStorePasswd");
217 if (defaultTrustStorePassword.length() != 0)
218 passwd = defaultTrustStorePassword.toCharArray();
219
220 // if trustStore is NONE, fis will be null
221 ks.load(fis, passwd);
222
223 // Zero out the temporary password storage
224 if (passwd != null) {
225 for (int i = 0; i < passwd.length; i++) {
226 passwd[i] = (char)0;
227 }
228 }
229 }
230
231 if (fis != null) {
232 fis.close();
233 }
234
235 return ks;
236 }
237
238 public static final class SimpleFactory extends TrustManagerFactoryImpl {
239 X509TrustManager getInstance(KeyStore ks) throws KeyStoreException {
240 return new X509TrustManagerImpl(Validator.TYPE_SIMPLE, ks);
241 }
242 X509TrustManager getInstance(ManagerFactoryParameters spec)
243 throws InvalidAlgorithmParameterException {
244 throw new InvalidAlgorithmParameterException
245 ("SunX509 TrustManagerFactory does not use "
246 + "ManagerFactoryParameters");
247 }
248 }
249
250 public static final class PKIXFactory extends TrustManagerFactoryImpl {
251 X509TrustManager getInstance(KeyStore ks) throws KeyStoreException {
252 return new X509TrustManagerImpl(Validator.TYPE_PKIX, ks);
253 }
254 X509TrustManager getInstance(ManagerFactoryParameters spec)
255 throws InvalidAlgorithmParameterException {
256 if (spec instanceof CertPathTrustManagerParameters == false) {
257 throw new InvalidAlgorithmParameterException
258 ("Parameters must be CertPathTrustManagerParameters");
259 }
260 CertPathParameters params =
261 ((CertPathTrustManagerParameters)spec).getParameters();
262 if (params instanceof PKIXBuilderParameters == false) {
263 throw new InvalidAlgorithmParameterException
264 ("Encapsulated parameters must be PKIXBuilderParameters");
265 }
266 PKIXBuilderParameters pkixParams = (PKIXBuilderParameters)params;
267 return new X509TrustManagerImpl(Validator.TYPE_PKIX, pkixParams);
268 }
269 }
270}