1 /* |
1 /* |
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
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 |
22 * or visit www.oracle.com if you need additional information or have any |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 |
|
27 package sun.security.ssl; |
26 package sun.security.ssl; |
28 |
27 |
29 import java.net.Socket; |
28 import java.net.Socket; |
30 import javax.net.ssl.SSLSession; |
|
31 |
|
32 import java.util.*; |
|
33 import java.security.*; |
29 import java.security.*; |
34 import java.security.cert.*; |
30 import java.security.cert.*; |
|
31 import java.util.*; |
35 import javax.net.ssl.*; |
32 import javax.net.ssl.*; |
36 |
|
37 import sun.security.validator.*; |
|
38 import sun.security.util.AnchorCertificates; |
33 import sun.security.util.AnchorCertificates; |
39 import sun.security.util.HostnameChecker; |
34 import sun.security.util.HostnameChecker; |
|
35 import sun.security.validator.*; |
40 |
36 |
41 /** |
37 /** |
42 * This class implements the SunJSSE X.509 trust manager using the internal |
38 * This class implements the SunJSSE X.509 trust manager using the internal |
43 * validator API in J2SE core. The logic in this class is minimal.<p> |
39 * validator API in J2SE core. The logic in this class is minimal.<p> |
44 * <p> |
40 * <p> |
65 |
61 |
66 // note that we need separate validator for client and server due to |
62 // note that we need separate validator for client and server due to |
67 // the different extension checks. They are initialized lazily on demand. |
63 // the different extension checks. They are initialized lazily on demand. |
68 private volatile Validator clientValidator, serverValidator; |
64 private volatile Validator clientValidator, serverValidator; |
69 |
65 |
70 private static final Debug debug = Debug.getInstance("ssl"); |
|
71 |
|
72 X509TrustManagerImpl(String validatorType, |
66 X509TrustManagerImpl(String validatorType, |
73 Collection<X509Certificate> trustedCerts) { |
67 Collection<X509Certificate> trustedCerts) { |
74 |
68 |
75 this.validatorType = validatorType; |
69 this.validatorType = validatorType; |
76 this.pkixParams = null; |
70 this.pkixParams = null; |
79 trustedCerts = Collections.<X509Certificate>emptySet(); |
73 trustedCerts = Collections.<X509Certificate>emptySet(); |
80 } |
74 } |
81 |
75 |
82 this.trustedCerts = trustedCerts; |
76 this.trustedCerts = trustedCerts; |
83 |
77 |
84 if (debug != null && Debug.isOn("trustmanager")) { |
78 if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { |
85 showTrustedCerts(); |
79 SSLLogger.fine("adding as trusted certificates", |
|
80 (Object[])trustedCerts.toArray(new X509Certificate[0])); |
86 } |
81 } |
87 } |
82 } |
88 |
83 |
89 X509TrustManagerImpl(String validatorType, PKIXBuilderParameters params) { |
84 X509TrustManagerImpl(String validatorType, PKIXBuilderParameters params) { |
90 this.validatorType = validatorType; |
85 this.validatorType = validatorType; |
95 // the little extra footprint |
90 // the little extra footprint |
96 Validator v = getValidator(Validator.VAR_TLS_SERVER); |
91 Validator v = getValidator(Validator.VAR_TLS_SERVER); |
97 trustedCerts = v.getTrustedCertificates(); |
92 trustedCerts = v.getTrustedCertificates(); |
98 serverValidator = v; |
93 serverValidator = v; |
99 |
94 |
100 if (debug != null && Debug.isOn("trustmanager")) { |
95 if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { |
101 showTrustedCerts(); |
96 SSLLogger.fine("adding as trusted certificates", |
|
97 (Object[])trustedCerts.toArray(new X509Certificate[0])); |
102 } |
98 } |
103 } |
99 } |
104 |
100 |
105 @Override |
101 @Override |
106 public void checkClientTrusted(X509Certificate[] chain, String authType) |
102 public void checkClientTrusted(X509Certificate[] chain, String authType) |
200 if (session == null) { |
196 if (session == null) { |
201 throw new CertificateException("No handshake session"); |
197 throw new CertificateException("No handshake session"); |
202 } |
198 } |
203 |
199 |
204 // create the algorithm constraints |
200 // create the algorithm constraints |
205 ProtocolVersion protocolVersion = |
|
206 ProtocolVersion.valueOf(session.getProtocol()); |
|
207 boolean isExtSession = (session instanceof ExtendedSSLSession); |
201 boolean isExtSession = (session instanceof ExtendedSSLSession); |
208 AlgorithmConstraints constraints = null; |
202 AlgorithmConstraints constraints; |
209 if (protocolVersion.v >= ProtocolVersion.TLS12.v && isExtSession) { |
203 if (isExtSession && |
|
204 ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) { |
210 ExtendedSSLSession extSession = (ExtendedSSLSession)session; |
205 ExtendedSSLSession extSession = (ExtendedSSLSession)session; |
211 String[] localSupportedSignAlgs = |
206 String[] localSupportedSignAlgs = |
212 extSession.getLocalSupportedSignatureAlgorithms(); |
207 extSession.getLocalSupportedSignatureAlgorithms(); |
213 |
208 |
214 constraints = new SSLAlgorithmConstraints( |
209 constraints = new SSLAlgorithmConstraints( |
226 trustedChain = validate(v, chain, responseList, |
221 trustedChain = validate(v, chain, responseList, |
227 constraints, isClient ? null : authType); |
222 constraints, isClient ? null : authType); |
228 |
223 |
229 // check if EE certificate chains to a public root CA (as |
224 // check if EE certificate chains to a public root CA (as |
230 // pre-installed in cacerts) |
225 // pre-installed in cacerts) |
231 boolean chainsToPublicCA = |
226 boolean chainsToPublicCA = AnchorCertificates.contains( |
232 AnchorCertificates.contains(trustedChain[trustedChain.length-1]); |
227 trustedChain[trustedChain.length-1]); |
233 |
228 |
234 // check endpoint identity |
229 // check endpoint identity |
235 String identityAlg = sslSocket.getSSLParameters(). |
230 String identityAlg = sslSocket.getSSLParameters(). |
236 getEndpointIdentificationAlgorithm(); |
231 getEndpointIdentificationAlgorithm(); |
237 if (identityAlg != null && identityAlg.length() != 0) { |
232 if (identityAlg != null && identityAlg.length() != 0) { |
240 } |
235 } |
241 } else { |
236 } else { |
242 trustedChain = validate(v, chain, Collections.emptyList(), |
237 trustedChain = validate(v, chain, Collections.emptyList(), |
243 null, isClient ? null : authType); |
238 null, isClient ? null : authType); |
244 } |
239 } |
245 if (debug != null && Debug.isOn("trustmanager")) { |
240 |
246 System.out.println("Found trusted certificate:"); |
241 if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { |
247 System.out.println(trustedChain[trustedChain.length - 1]); |
242 SSLLogger.fine("Found trusted certificate", |
|
243 trustedChain[trustedChain.length - 1]); |
248 } |
244 } |
249 } |
245 } |
250 |
246 |
251 private void checkTrusted(X509Certificate[] chain, String authType, |
247 private void checkTrusted(X509Certificate[] chain, String authType, |
252 SSLEngine engine, boolean isClient) throws CertificateException { |
248 SSLEngine engine, boolean isClient) throws CertificateException { |
258 if (session == null) { |
254 if (session == null) { |
259 throw new CertificateException("No handshake session"); |
255 throw new CertificateException("No handshake session"); |
260 } |
256 } |
261 |
257 |
262 // create the algorithm constraints |
258 // create the algorithm constraints |
263 ProtocolVersion protocolVersion = |
|
264 ProtocolVersion.valueOf(session.getProtocol()); |
|
265 boolean isExtSession = (session instanceof ExtendedSSLSession); |
259 boolean isExtSession = (session instanceof ExtendedSSLSession); |
266 AlgorithmConstraints constraints = null; |
260 AlgorithmConstraints constraints; |
267 if (protocolVersion.v >= ProtocolVersion.TLS12.v && isExtSession) { |
261 if (isExtSession && |
|
262 ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) { |
268 ExtendedSSLSession extSession = (ExtendedSSLSession)session; |
263 ExtendedSSLSession extSession = (ExtendedSSLSession)session; |
269 String[] localSupportedSignAlgs = |
264 String[] localSupportedSignAlgs = |
270 extSession.getLocalSupportedSignatureAlgorithms(); |
265 extSession.getLocalSupportedSignatureAlgorithms(); |
271 |
266 |
272 constraints = new SSLAlgorithmConstraints( |
267 constraints = new SSLAlgorithmConstraints( |
284 trustedChain = validate(v, chain, responseList, |
279 trustedChain = validate(v, chain, responseList, |
285 constraints, isClient ? null : authType); |
280 constraints, isClient ? null : authType); |
286 |
281 |
287 // check if EE certificate chains to a public root CA (as |
282 // check if EE certificate chains to a public root CA (as |
288 // pre-installed in cacerts) |
283 // pre-installed in cacerts) |
289 boolean chainsToPublicCA = |
284 boolean chainsToPublicCA = AnchorCertificates.contains( |
290 AnchorCertificates.contains(trustedChain[trustedChain.length-1]); |
285 trustedChain[trustedChain.length-1]); |
291 |
286 |
292 // check endpoint identity |
287 // check endpoint identity |
293 String identityAlg = engine.getSSLParameters(). |
288 String identityAlg = engine.getSSLParameters(). |
294 getEndpointIdentificationAlgorithm(); |
289 getEndpointIdentificationAlgorithm(); |
295 if (identityAlg != null && identityAlg.length() != 0) { |
290 if (identityAlg != null && identityAlg.length() != 0) { |
298 } |
293 } |
299 } else { |
294 } else { |
300 trustedChain = validate(v, chain, Collections.emptyList(), |
295 trustedChain = validate(v, chain, Collections.emptyList(), |
301 null, isClient ? null : authType); |
296 null, isClient ? null : authType); |
302 } |
297 } |
303 if (debug != null && Debug.isOn("trustmanager")) { |
298 |
304 System.out.println("Found trusted certificate:"); |
299 if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { |
305 System.out.println(trustedChain[trustedChain.length - 1]); |
300 SSLLogger.fine("Found trusted certificate", |
306 } |
301 trustedChain[trustedChain.length - 1]); |
307 } |
|
308 |
|
309 private void showTrustedCerts() { |
|
310 for (X509Certificate cert : trustedCerts) { |
|
311 System.out.println("adding as trusted cert:"); |
|
312 System.out.println(" Subject: " |
|
313 + cert.getSubjectX500Principal()); |
|
314 System.out.println(" Issuer: " |
|
315 + cert.getIssuerX500Principal()); |
|
316 System.out.println(" Algorithm: " |
|
317 + cert.getPublicKey().getAlgorithm() |
|
318 + "; Serial number: 0x" |
|
319 + cert.getSerialNumber().toString(16)); |
|
320 System.out.println(" Valid from " |
|
321 + cert.getNotBefore() + " until " |
|
322 + cert.getNotAfter()); |
|
323 System.out.println(); |
|
324 } |
302 } |
325 } |
303 } |
326 |
304 |
327 private Validator getValidator(String variant) { |
305 private Validator getValidator(String variant) { |
328 Validator v; |
306 Validator v; |
362 } else { |
340 } else { |
363 try { |
341 try { |
364 hostname = new SNIHostName(sniName.getEncoded()); |
342 hostname = new SNIHostName(sniName.getEncoded()); |
365 } catch (IllegalArgumentException iae) { |
343 } catch (IllegalArgumentException iae) { |
366 // unlikely to happen, just in case ... |
344 // unlikely to happen, just in case ... |
367 if ((debug != null) && Debug.isOn("trustmanager")) { |
345 if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { |
368 System.out.println("Illegal server name: " + sniName); |
346 SSLLogger.fine("Illegal server name: " + sniName); |
369 } |
347 } |
370 } |
348 } |
371 } |
349 } |
372 |
350 |
373 // no more than server name of the same name type |
351 // no more than server name of the same name type |