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
26package sun.security.ssl;
27
28import java.net.Socket;
29
30import java.io.*;
31import java.util.*;
32import java.security.*;
33import java.security.cert.*;
34import java.security.cert.Certificate;
35
36import javax.net.ssl.*;
37
38import sun.security.provider.certpath.AlgorithmChecker;
39
40public abstract class SSLContextImpl extends SSLContextSpi {
41
42    private static final Debug debug = Debug.getInstance("ssl");
43
44    private final EphemeralKeyManager ephemeralKeyManager;
45    private final SSLSessionContextImpl clientCache;
46    private final SSLSessionContextImpl serverCache;
47
48    private boolean isInitialized;
49
50    private X509ExtendedKeyManager keyManager;
51    private X509TrustManager trustManager;
52    private SecureRandom secureRandom;
53
54    // The default algrithm constraints
55    private AlgorithmConstraints defaultAlgorithmConstraints =
56                                 new SSLAlgorithmConstraints(null);
57
58    // supported and default protocols
59    private ProtocolList defaultServerProtocolList;
60    private ProtocolList defaultClientProtocolList;
61    private ProtocolList supportedProtocolList;
62
63    // supported and default cipher suites
64    private CipherSuiteList defaultServerCipherSuiteList;
65    private CipherSuiteList defaultClientCipherSuiteList;
66    private CipherSuiteList supportedCipherSuiteList;
67
68    SSLContextImpl() {
69        ephemeralKeyManager = new EphemeralKeyManager();
70        clientCache = new SSLSessionContextImpl();
71        serverCache = new SSLSessionContextImpl();
72    }
73
74    protected void engineInit(KeyManager[] km, TrustManager[] tm,
75                                SecureRandom sr) throws KeyManagementException {
76        isInitialized = false;
77        keyManager = chooseKeyManager(km);
78
79        if (tm == null) {
80            try {
81                TrustManagerFactory tmf = TrustManagerFactory.getInstance(
82                        TrustManagerFactory.getDefaultAlgorithm());
83                tmf.init((KeyStore)null);
84                tm = tmf.getTrustManagers();
85            } catch (Exception e) {
86                // eat
87            }
88        }
89        trustManager = chooseTrustManager(tm);
90
91        if (sr == null) {
92            secureRandom = JsseJce.getSecureRandom();
93        } else {
94            if (SunJSSE.isFIPS() &&
95                        (sr.getProvider() != SunJSSE.cryptoProvider)) {
96                throw new KeyManagementException
97                    ("FIPS mode: SecureRandom must be from provider "
98                    + SunJSSE.cryptoProvider.getName());
99            }
100            secureRandom = sr;
101        }
102
103        /*
104         * The initial delay of seeding the random number generator
105         * could be long enough to cause the initial handshake on our
106         * first connection to timeout and fail. Make sure it is
107         * primed and ready by getting some initial output from it.
108         */
109        if (debug != null && Debug.isOn("sslctx")) {
110            System.out.println("trigger seeding of SecureRandom");
111        }
112        secureRandom.nextInt();
113        if (debug != null && Debug.isOn("sslctx")) {
114            System.out.println("done seeding SecureRandom");
115        }
116        isInitialized = true;
117    }
118
119    private X509TrustManager chooseTrustManager(TrustManager[] tm)
120            throws KeyManagementException {
121        // We only use the first instance of X509TrustManager passed to us.
122        for (int i = 0; tm != null && i < tm.length; i++) {
123            if (tm[i] instanceof X509TrustManager) {
124                if (SunJSSE.isFIPS() &&
125                        !(tm[i] instanceof X509TrustManagerImpl)) {
126                    throw new KeyManagementException
127                        ("FIPS mode: only SunJSSE TrustManagers may be used");
128                }
129
130                if (tm[i] instanceof X509ExtendedTrustManager) {
131                    return (X509TrustManager)tm[i];
132                } else {
133                    return new AbstractTrustManagerWrapper(
134                                        (X509TrustManager)tm[i]);
135                }
136            }
137        }
138
139        // nothing found, return a dummy X509TrustManager.
140        return DummyX509TrustManager.INSTANCE;
141    }
142
143    private X509ExtendedKeyManager chooseKeyManager(KeyManager[] kms)
144            throws KeyManagementException {
145        for (int i = 0; kms != null && i < kms.length; i++) {
146            KeyManager km = kms[i];
147            if (!(km instanceof X509KeyManager)) {
148                continue;
149            }
150            if (SunJSSE.isFIPS()) {
151                // In FIPS mode, require that one of SunJSSE's own keymanagers
152                // is used. Otherwise, we cannot be sure that only keys from
153                // the FIPS token are used.
154                if ((km instanceof X509KeyManagerImpl)
155                            || (km instanceof SunX509KeyManagerImpl)) {
156                    return (X509ExtendedKeyManager)km;
157                } else {
158                    // throw exception, we don't want to silently use the
159                    // dummy keymanager without telling the user.
160                    throw new KeyManagementException
161                        ("FIPS mode: only SunJSSE KeyManagers may be used");
162                }
163            }
164            if (km instanceof X509ExtendedKeyManager) {
165                return (X509ExtendedKeyManager)km;
166            }
167            if (debug != null && Debug.isOn("sslctx")) {
168                System.out.println(
169                    "X509KeyManager passed to " +
170                    "SSLContext.init():  need an " +
171                    "X509ExtendedKeyManager for SSLEngine use");
172            }
173            return new AbstractKeyManagerWrapper((X509KeyManager)km);
174        }
175
176        // nothing found, return a dummy X509ExtendedKeyManager
177        return DummyX509KeyManager.INSTANCE;
178    }
179
180    protected SSLSocketFactory engineGetSocketFactory() {
181        if (!isInitialized) {
182            throw new IllegalStateException(
183                "SSLContextImpl is not initialized");
184        }
185       return new SSLSocketFactoryImpl(this);
186    }
187
188    protected SSLServerSocketFactory engineGetServerSocketFactory() {
189        if (!isInitialized) {
190            throw new IllegalStateException("SSLContext is not initialized");
191        }
192        return new SSLServerSocketFactoryImpl(this);
193    }
194
195    protected SSLEngine engineCreateSSLEngine() {
196        if (!isInitialized) {
197            throw new IllegalStateException(
198                "SSLContextImpl is not initialized");
199        }
200        return new SSLEngineImpl(this);
201    }
202
203    protected SSLEngine engineCreateSSLEngine(String host, int port) {
204        if (!isInitialized) {
205            throw new IllegalStateException(
206                "SSLContextImpl is not initialized");
207        }
208        return new SSLEngineImpl(this, host, port);
209    }
210
211    protected SSLSessionContext engineGetClientSessionContext() {
212        return clientCache;
213    }
214
215    protected SSLSessionContext engineGetServerSessionContext() {
216        return serverCache;
217    }
218
219    SecureRandom getSecureRandom() {
220        return secureRandom;
221    }
222
223    X509ExtendedKeyManager getX509KeyManager() {
224        return keyManager;
225    }
226
227    X509TrustManager getX509TrustManager() {
228        return trustManager;
229    }
230
231    EphemeralKeyManager getEphemeralKeyManager() {
232        return ephemeralKeyManager;
233    }
234
235    abstract SSLParameters getDefaultServerSSLParams();
236    abstract SSLParameters getDefaultClientSSLParams();
237    abstract SSLParameters getSupportedSSLParams();
238
239    // Get suported ProtoclList.
240    ProtocolList getSuportedProtocolList() {
241        if (supportedProtocolList == null) {
242            supportedProtocolList =
243                new ProtocolList(getSupportedSSLParams().getProtocols());
244        }
245
246        return supportedProtocolList;
247    }
248
249    // Get default ProtoclList.
250    ProtocolList getDefaultProtocolList(boolean roleIsServer) {
251        if (roleIsServer) {
252            if (defaultServerProtocolList == null) {
253                defaultServerProtocolList = new ProtocolList(
254                        getDefaultServerSSLParams().getProtocols());
255            }
256
257            return defaultServerProtocolList;
258        } else {
259            if (defaultClientProtocolList == null) {
260                defaultClientProtocolList = new ProtocolList(
261                        getDefaultClientSSLParams().getProtocols());
262            }
263
264            return defaultClientProtocolList;
265        }
266    }
267
268    // Get suported CipherSuiteList.
269    CipherSuiteList getSupportedCipherSuiteList() {
270        // The maintenance of cipher suites needs to be synchronized.
271        synchronized (this) {
272            // Clear cache of available ciphersuites.
273            clearAvailableCache();
274
275            if (supportedCipherSuiteList == null) {
276                supportedCipherSuiteList = getApplicableCipherSuiteList(
277                        getSuportedProtocolList(), false);
278            }
279
280            return supportedCipherSuiteList;
281        }
282    }
283
284    // Get default CipherSuiteList.
285    CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
286        // The maintenance of cipher suites needs to be synchronized.
287        synchronized (this) {
288            // Clear cache of available ciphersuites.
289            clearAvailableCache();
290
291            if (roleIsServer) {
292                if (defaultServerCipherSuiteList == null) {
293                    defaultServerCipherSuiteList = getApplicableCipherSuiteList(
294                        getDefaultProtocolList(true), true);
295                }
296
297                return defaultServerCipherSuiteList;
298            } else {
299                if (defaultClientCipherSuiteList == null) {
300                    defaultClientCipherSuiteList = getApplicableCipherSuiteList(
301                        getDefaultProtocolList(false), true);
302                }
303
304                return defaultClientCipherSuiteList;
305            }
306        }
307    }
308
309    /**
310     * Return whether a protocol list is the original default enabled
311     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
312     */
313    boolean isDefaultProtocolList(ProtocolList protocols) {
314        return (protocols == defaultServerProtocolList) ||
315               (protocols == defaultClientProtocolList);
316    }
317
318
319    /*
320     * Return the list of all available CipherSuites with a priority of
321     * minPriority or above.
322     */
323    private CipherSuiteList getApplicableCipherSuiteList(
324            ProtocolList protocols, boolean onlyEnabled) {
325
326        int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
327        if (onlyEnabled) {
328            minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
329        }
330
331        Collection<CipherSuite> allowedCipherSuites =
332                                    CipherSuite.allowedCipherSuites();
333
334        TreeSet<CipherSuite> suites = new TreeSet<>();
335        if (!(protocols.collection().isEmpty()) &&
336                protocols.min.v != ProtocolVersion.NONE.v) {
337            for (CipherSuite suite : allowedCipherSuites) {
338                if (!suite.allowed || suite.priority < minPriority) {
339                    continue;
340                }
341
342                if (suite.isAvailable() &&
343                        suite.obsoleted > protocols.min.v &&
344                        suite.supported <= protocols.max.v) {
345                    if (defaultAlgorithmConstraints.permits(
346                            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
347                            suite.name, null)) {
348                        suites.add(suite);
349                    }
350                } else if (debug != null &&
351                        Debug.isOn("sslctx") && Debug.isOn("verbose")) {
352                    if (suite.obsoleted <= protocols.min.v) {
353                        System.out.println(
354                            "Ignoring obsoleted cipher suite: " + suite);
355                    } else if (suite.supported > protocols.max.v) {
356                        System.out.println(
357                            "Ignoring unsupported cipher suite: " + suite);
358                    } else {
359                        System.out.println(
360                            "Ignoring unavailable cipher suite: " + suite);
361                    }
362                }
363            }
364        }
365
366        return new CipherSuiteList(suites);
367    }
368
369    /**
370     * Clear cache of available ciphersuites. If we support all ciphers
371     * internally, there is no need to clear the cache and calling this
372     * method has no effect.
373     *
374     * Note that every call to clearAvailableCache() and the maintenance of
375     * cipher suites need to be synchronized with this instance.
376     */
377    private void clearAvailableCache() {
378        if (CipherSuite.DYNAMIC_AVAILABILITY) {
379            supportedCipherSuiteList = null;
380            defaultServerCipherSuiteList = null;
381            defaultClientCipherSuiteList = null;
382            CipherSuite.BulkCipher.clearAvailableCache();
383            JsseJce.clearEcAvailable();
384        }
385    }
386
387    /*
388     * The SSLContext implementation for TLS/SSL algorithm
389     *
390     * SSL/TLS protocols specify the forward compatibility and version
391     * roll-back attack protections, however, a number of SSL/TLS server
392     * vendors did not implement these aspects properly, and some current
393     * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
394     *
395     * Considering above interoperability issues, SunJSSE will not set
396     * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
397     *
398     * For SSL/TLS servers, there is no such interoperability issues as
399     * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
400     * enabled protocols for server by default.
401     *
402     * We may change the behavior when popular TLS/SSL vendors support TLS
403     * forward compatibility properly.
404     *
405     * SSLv2Hello is no longer necessary.  This interoperability option was
406     * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
407     * and there were a fair number of SSLv2-only servers deployed.  Because
408     * of the security issues in SSLv2, it is rarely (if ever) used, as
409     * deployments should now be using SSLv3 and TLSv1.
410     *
411     * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
412     * by default. Applications still can use it by enabling SSLv2Hello with
413     * the series of setEnabledProtocols APIs.
414     */
415
416    /*
417     * The conservative SSLContext implementation for TLS, SSL, SSLv3 and
418     * TLS10 algorithm.
419     *
420     * This is a super class of DefaultSSLContext and TLS10Context.
421     *
422     * @see SSLContext
423     */
424    private static class ConservativeSSLContext extends SSLContextImpl {
425        // parameters
426        private static SSLParameters defaultServerSSLParams;
427        private static SSLParameters defaultClientSSLParams;
428        private static SSLParameters supportedSSLParams;
429
430        static {
431            if (SunJSSE.isFIPS()) {
432                supportedSSLParams = new SSLParameters();
433                supportedSSLParams.setProtocols(new String[] {
434                    ProtocolVersion.TLS10.name,
435                    ProtocolVersion.TLS11.name,
436                    ProtocolVersion.TLS12.name
437                });
438
439                defaultServerSSLParams = supportedSSLParams;
440
441                defaultClientSSLParams = new SSLParameters();
442                defaultClientSSLParams.setProtocols(new String[] {
443                    ProtocolVersion.TLS10.name
444                });
445
446            } else {
447                supportedSSLParams = new SSLParameters();
448                supportedSSLParams.setProtocols(new String[] {
449                    ProtocolVersion.SSL20Hello.name,
450                    ProtocolVersion.SSL30.name,
451                    ProtocolVersion.TLS10.name,
452                    ProtocolVersion.TLS11.name,
453                    ProtocolVersion.TLS12.name
454                });
455
456                defaultServerSSLParams = supportedSSLParams;
457
458                defaultClientSSLParams = new SSLParameters();
459                defaultClientSSLParams.setProtocols(new String[] {
460                    ProtocolVersion.SSL30.name,
461                    ProtocolVersion.TLS10.name
462                });
463            }
464        }
465
466        SSLParameters getDefaultServerSSLParams() {
467            return defaultServerSSLParams;
468        }
469
470        SSLParameters getDefaultClientSSLParams() {
471            return defaultClientSSLParams;
472        }
473
474        SSLParameters getSupportedSSLParams() {
475            return supportedSSLParams;
476        }
477    }
478
479    /*
480     * The SSLContext implementation for default algorithm
481     *
482     * @see SSLContext
483     */
484    public static final class DefaultSSLContext extends ConservativeSSLContext {
485        private static final String NONE = "NONE";
486        private static final String P11KEYSTORE = "PKCS11";
487
488        private static volatile SSLContextImpl defaultImpl;
489
490        private static TrustManager[] defaultTrustManagers;
491        private static KeyManager[] defaultKeyManagers;
492
493        public DefaultSSLContext() throws Exception {
494            try {
495                super.engineInit(getDefaultKeyManager(),
496                        getDefaultTrustManager(), null);
497            } catch (Exception e) {
498                if (debug != null && Debug.isOn("defaultctx")) {
499                    System.out.println("default context init failed: " + e);
500                }
501                throw e;
502            }
503
504            if (defaultImpl == null) {
505                defaultImpl = this;
506            }
507        }
508
509        protected void engineInit(KeyManager[] km, TrustManager[] tm,
510            SecureRandom sr) throws KeyManagementException {
511            throw new KeyManagementException
512                ("Default SSLContext is initialized automatically");
513        }
514
515        static synchronized SSLContextImpl getDefaultImpl() throws Exception {
516            if (defaultImpl == null) {
517                new DefaultSSLContext();
518            }
519            return defaultImpl;
520        }
521
522        private static synchronized TrustManager[] getDefaultTrustManager()
523                throws Exception {
524            if (defaultTrustManagers != null) {
525                return defaultTrustManagers;
526            }
527
528            KeyStore ks =
529                TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
530
531            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
532                TrustManagerFactory.getDefaultAlgorithm());
533            tmf.init(ks);
534            defaultTrustManagers = tmf.getTrustManagers();
535            return defaultTrustManagers;
536        }
537
538        private static synchronized KeyManager[] getDefaultKeyManager()
539                throws Exception {
540            if (defaultKeyManagers != null) {
541                return defaultKeyManagers;
542            }
543
544            final Map<String,String> props = new HashMap<>();
545            AccessController.doPrivileged(
546                        new PrivilegedExceptionAction<Object>() {
547                public Object run() throws Exception {
548                    props.put("keyStore",  System.getProperty(
549                                "javax.net.ssl.keyStore", ""));
550                    props.put("keyStoreType", System.getProperty(
551                                "javax.net.ssl.keyStoreType",
552                                KeyStore.getDefaultType()));
553                    props.put("keyStoreProvider", System.getProperty(
554                                "javax.net.ssl.keyStoreProvider", ""));
555                    props.put("keyStorePasswd", System.getProperty(
556                                "javax.net.ssl.keyStorePassword", ""));
557                    return null;
558                }
559            });
560
561            final String defaultKeyStore = props.get("keyStore");
562            String defaultKeyStoreType = props.get("keyStoreType");
563            String defaultKeyStoreProvider = props.get("keyStoreProvider");
564            if (debug != null && Debug.isOn("defaultctx")) {
565                System.out.println("keyStore is : " + defaultKeyStore);
566                System.out.println("keyStore type is : " +
567                                        defaultKeyStoreType);
568                System.out.println("keyStore provider is : " +
569                                        defaultKeyStoreProvider);
570            }
571
572            if (P11KEYSTORE.equals(defaultKeyStoreType) &&
573                    !NONE.equals(defaultKeyStore)) {
574                throw new IllegalArgumentException("if keyStoreType is "
575                    + P11KEYSTORE + ", then keyStore must be " + NONE);
576            }
577
578            FileInputStream fs = null;
579            if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) {
580                fs = AccessController.doPrivileged(
581                        new PrivilegedExceptionAction<FileInputStream>() {
582                    public FileInputStream run() throws Exception {
583                        return new FileInputStream(defaultKeyStore);
584                    }
585                });
586            }
587
588            String defaultKeyStorePassword = props.get("keyStorePasswd");
589            char[] passwd = null;
590            if (defaultKeyStorePassword.length() != 0) {
591                passwd = defaultKeyStorePassword.toCharArray();
592            }
593
594            /**
595             * Try to initialize key store.
596             */
597            KeyStore ks = null;
598            if ((defaultKeyStoreType.length()) != 0) {
599                if (debug != null && Debug.isOn("defaultctx")) {
600                    System.out.println("init keystore");
601                }
602                if (defaultKeyStoreProvider.length() == 0) {
603                    ks = KeyStore.getInstance(defaultKeyStoreType);
604                } else {
605                    ks = KeyStore.getInstance(defaultKeyStoreType,
606                                        defaultKeyStoreProvider);
607                }
608
609                // if defaultKeyStore is NONE, fs will be null
610                ks.load(fs, passwd);
611            }
612            if (fs != null) {
613                fs.close();
614                fs = null;
615            }
616
617            /*
618             * Try to initialize key manager.
619             */
620            if (debug != null && Debug.isOn("defaultctx")) {
621                System.out.println("init keymanager of type " +
622                    KeyManagerFactory.getDefaultAlgorithm());
623            }
624            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
625                KeyManagerFactory.getDefaultAlgorithm());
626
627            if (P11KEYSTORE.equals(defaultKeyStoreType)) {
628                kmf.init(ks, null); // do not pass key passwd if using token
629            } else {
630                kmf.init(ks, passwd);
631            }
632
633            defaultKeyManagers = kmf.getKeyManagers();
634            return defaultKeyManagers;
635        }
636    }
637
638    /*
639     * The SSLContext implementation for TLS, SSL, SSLv3 and TLS10 algorithm
640     *
641     * @see SSLContext
642     */
643    public static final class TLS10Context extends ConservativeSSLContext {
644        // use the default constructor and methods
645    }
646
647    /*
648     * The SSLContext implementation for TLS11 algorithm
649     *
650     * @see SSLContext
651     */
652    public static final class TLS11Context extends SSLContextImpl {
653        // parameters
654        private static SSLParameters defaultServerSSLParams;
655        private static SSLParameters defaultClientSSLParams;
656        private static SSLParameters supportedSSLParams;
657
658        static {
659            if (SunJSSE.isFIPS()) {
660                supportedSSLParams = new SSLParameters();
661                supportedSSLParams.setProtocols(new String[] {
662                    ProtocolVersion.TLS10.name,
663                    ProtocolVersion.TLS11.name,
664                    ProtocolVersion.TLS12.name
665                });
666
667                defaultServerSSLParams = supportedSSLParams;
668
669                defaultClientSSLParams = new SSLParameters();
670                defaultClientSSLParams.setProtocols(new String[] {
671                    ProtocolVersion.TLS10.name,
672                    ProtocolVersion.TLS11.name
673                });
674
675            } else {
676                supportedSSLParams = new SSLParameters();
677                supportedSSLParams.setProtocols(new String[] {
678                    ProtocolVersion.SSL20Hello.name,
679                    ProtocolVersion.SSL30.name,
680                    ProtocolVersion.TLS10.name,
681                    ProtocolVersion.TLS11.name,
682                    ProtocolVersion.TLS12.name
683                });
684
685                defaultServerSSLParams = supportedSSLParams;
686
687                defaultClientSSLParams = new SSLParameters();
688                defaultClientSSLParams.setProtocols(new String[] {
689                    ProtocolVersion.SSL30.name,
690                    ProtocolVersion.TLS10.name,
691                    ProtocolVersion.TLS11.name
692                });
693            }
694        }
695
696        SSLParameters getDefaultServerSSLParams() {
697            return defaultServerSSLParams;
698        }
699
700        SSLParameters getDefaultClientSSLParams() {
701            return defaultClientSSLParams;
702        }
703
704        SSLParameters getSupportedSSLParams() {
705            return supportedSSLParams;
706        }
707    }
708
709    /*
710     * The SSLContext implementation for TLS12 algorithm
711     *
712     * @see SSLContext
713     */
714    public static final class TLS12Context extends SSLContextImpl {
715        // parameters
716        private static SSLParameters defaultServerSSLParams;
717        private static SSLParameters defaultClientSSLParams;
718        private static SSLParameters supportedSSLParams;
719
720        static {
721            if (SunJSSE.isFIPS()) {
722                supportedSSLParams = new SSLParameters();
723                supportedSSLParams.setProtocols(new String[] {
724                    ProtocolVersion.TLS10.name,
725                    ProtocolVersion.TLS11.name,
726                    ProtocolVersion.TLS12.name
727                });
728
729                defaultServerSSLParams = supportedSSLParams;
730
731                defaultClientSSLParams = new SSLParameters();
732                defaultClientSSLParams.setProtocols(new String[] {
733                    ProtocolVersion.TLS10.name,
734                    ProtocolVersion.TLS11.name,
735                    ProtocolVersion.TLS12.name
736                });
737
738            } else {
739                supportedSSLParams = new SSLParameters();
740                supportedSSLParams.setProtocols(new String[] {
741                    ProtocolVersion.SSL20Hello.name,
742                    ProtocolVersion.SSL30.name,
743                    ProtocolVersion.TLS10.name,
744                    ProtocolVersion.TLS11.name,
745                    ProtocolVersion.TLS12.name
746                });
747
748                defaultServerSSLParams = supportedSSLParams;
749
750                defaultClientSSLParams = new SSLParameters();
751                defaultClientSSLParams.setProtocols(new String[] {
752                    ProtocolVersion.SSL30.name,
753                    ProtocolVersion.TLS10.name,
754                    ProtocolVersion.TLS11.name,
755                    ProtocolVersion.TLS12.name
756                });
757            }
758        }
759
760        SSLParameters getDefaultServerSSLParams() {
761            return defaultServerSSLParams;
762        }
763
764        SSLParameters getDefaultClientSSLParams() {
765            return defaultClientSSLParams;
766        }
767
768        SSLParameters getSupportedSSLParams() {
769            return supportedSSLParams;
770        }
771    }
772
773}
774
775
776final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
777            implements X509TrustManager {
778
779    // the delegated trust manager
780    private final X509TrustManager tm;
781
782    AbstractTrustManagerWrapper(X509TrustManager tm) {
783        this.tm = tm;
784    }
785
786    @Override
787    public void checkClientTrusted(X509Certificate[] chain, String authType)
788        throws CertificateException {
789        tm.checkClientTrusted(chain, authType);
790    }
791
792    @Override
793    public void checkServerTrusted(X509Certificate[] chain, String authType)
794        throws CertificateException {
795        tm.checkServerTrusted(chain, authType);
796    }
797
798    @Override
799    public X509Certificate[] getAcceptedIssuers() {
800        return tm.getAcceptedIssuers();
801    }
802
803    @Override
804    public void checkClientTrusted(X509Certificate[] chain, String authType,
805                Socket socket) throws CertificateException {
806        tm.checkClientTrusted(chain, authType);
807        checkAdditionalTrust(chain, authType, socket, true);
808    }
809
810    @Override
811    public void checkServerTrusted(X509Certificate[] chain, String authType,
812            Socket socket) throws CertificateException {
813        tm.checkServerTrusted(chain, authType);
814        checkAdditionalTrust(chain, authType, socket, false);
815    }
816
817    @Override
818    public void checkClientTrusted(X509Certificate[] chain, String authType,
819            SSLEngine engine) throws CertificateException {
820        tm.checkClientTrusted(chain, authType);
821        checkAdditionalTrust(chain, authType, engine, true);
822    }
823
824    @Override
825    public void checkServerTrusted(X509Certificate[] chain, String authType,
826            SSLEngine engine) throws CertificateException {
827        tm.checkServerTrusted(chain, authType);
828        checkAdditionalTrust(chain, authType, engine, false);
829    }
830
831    private void checkAdditionalTrust(X509Certificate[] chain, String authType,
832                Socket socket, boolean isClient) throws CertificateException {
833        if (socket != null && socket.isConnected() &&
834                                    socket instanceof SSLSocket) {
835
836            SSLSocket sslSocket = (SSLSocket)socket;
837            SSLSession session = sslSocket.getHandshakeSession();
838            if (session == null) {
839                throw new CertificateException("No handshake session");
840            }
841
842            // check endpoint identity
843            String identityAlg = sslSocket.getSSLParameters().
844                                        getEndpointIdentificationAlgorithm();
845            if (identityAlg != null && identityAlg.length() != 0) {
846                String hostname = session.getPeerHost();
847                X509TrustManagerImpl.checkIdentity(
848                                    hostname, chain[0], identityAlg);
849            }
850
851            // try the best to check the algorithm constraints
852            ProtocolVersion protocolVersion =
853                ProtocolVersion.valueOf(session.getProtocol());
854            AlgorithmConstraints constraints = null;
855            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
856                if (session instanceof ExtendedSSLSession) {
857                    ExtendedSSLSession extSession =
858                                    (ExtendedSSLSession)session;
859                    String[] peerSupportedSignAlgs =
860                            extSession.getLocalSupportedSignatureAlgorithms();
861
862                    constraints = new SSLAlgorithmConstraints(
863                                    sslSocket, peerSupportedSignAlgs, true);
864                } else {
865                    constraints =
866                            new SSLAlgorithmConstraints(sslSocket, true);
867                }
868            } else {
869                constraints = new SSLAlgorithmConstraints(sslSocket, true);
870            }
871
872            checkAlgorithmConstraints(chain, constraints);
873        }
874    }
875
876    private void checkAdditionalTrust(X509Certificate[] chain, String authType,
877            SSLEngine engine, boolean isClient) throws CertificateException {
878        if (engine != null) {
879            SSLSession session = engine.getHandshakeSession();
880            if (session == null) {
881                throw new CertificateException("No handshake session");
882            }
883
884            // check endpoint identity
885            String identityAlg = engine.getSSLParameters().
886                                        getEndpointIdentificationAlgorithm();
887            if (identityAlg != null && identityAlg.length() != 0) {
888                String hostname = session.getPeerHost();
889                X509TrustManagerImpl.checkIdentity(
890                                    hostname, chain[0], identityAlg);
891            }
892
893            // try the best to check the algorithm constraints
894            ProtocolVersion protocolVersion =
895                ProtocolVersion.valueOf(session.getProtocol());
896            AlgorithmConstraints constraints = null;
897            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
898                if (session instanceof ExtendedSSLSession) {
899                    ExtendedSSLSession extSession =
900                                    (ExtendedSSLSession)session;
901                    String[] peerSupportedSignAlgs =
902                            extSession.getLocalSupportedSignatureAlgorithms();
903
904                    constraints = new SSLAlgorithmConstraints(
905                                    engine, peerSupportedSignAlgs, true);
906                } else {
907                    constraints =
908                            new SSLAlgorithmConstraints(engine, true);
909                }
910            } else {
911                constraints = new SSLAlgorithmConstraints(engine, true);
912            }
913
914            checkAlgorithmConstraints(chain, constraints);
915        }
916    }
917
918    private void checkAlgorithmConstraints(X509Certificate[] chain,
919            AlgorithmConstraints constraints) throws CertificateException {
920
921        try {
922            // Does the certificate chain end with a trusted certificate?
923            int checkedLength = chain.length - 1;
924
925            Collection<X509Certificate> trustedCerts = new HashSet<>();
926            X509Certificate[] certs = tm.getAcceptedIssuers();
927            if ((certs != null) && (certs.length > 0)){
928                Collections.addAll(trustedCerts, certs);
929            }
930
931            if (trustedCerts.contains(chain[checkedLength])) {
932                    checkedLength--;
933            }
934
935            // A forward checker, need to check from trust to target
936            if (checkedLength >= 0) {
937                AlgorithmChecker checker = new AlgorithmChecker(constraints);
938                checker.init(false);
939                for (int i = checkedLength; i >= 0; i--) {
940                    Certificate cert = chain[i];
941                    // We don't care about the unresolved critical extensions.
942                    checker.check(cert, Collections.<String>emptySet());
943                }
944            }
945        } catch (CertPathValidatorException cpve) {
946            throw new CertificateException(
947                "Certificates does not conform to algorithm constraints");
948        }
949    }
950}
951
952// Dummy X509TrustManager implementation, rejects all peer certificates.
953// Used if the application did not specify a proper X509TrustManager.
954final class DummyX509TrustManager extends X509ExtendedTrustManager
955            implements X509TrustManager {
956
957    static final X509TrustManager INSTANCE = new DummyX509TrustManager();
958
959    private DummyX509TrustManager() {
960        // empty
961    }
962
963    /*
964     * Given the partial or complete certificate chain
965     * provided by the peer, build a certificate path
966     * to a trusted root and return if it can be
967     * validated and is trusted for client SSL authentication.
968     * If not, it throws an exception.
969     */
970    @Override
971    public void checkClientTrusted(X509Certificate[] chain, String authType)
972        throws CertificateException {
973        throw new CertificateException(
974            "No X509TrustManager implementation avaiable");
975    }
976
977    /*
978     * Given the partial or complete certificate chain
979     * provided by the peer, build a certificate path
980     * to a trusted root and return if it can be
981     * validated and is trusted for server SSL authentication.
982     * If not, it throws an exception.
983     */
984    @Override
985    public void checkServerTrusted(X509Certificate[] chain, String authType)
986        throws CertificateException {
987        throw new CertificateException(
988            "No X509TrustManager implementation available");
989    }
990
991    /*
992     * Return an array of issuer certificates which are trusted
993     * for authenticating peers.
994     */
995    @Override
996    public X509Certificate[] getAcceptedIssuers() {
997        return new X509Certificate[0];
998    }
999
1000    @Override
1001    public void checkClientTrusted(X509Certificate[] chain, String authType,
1002                Socket socket) throws CertificateException {
1003        throw new CertificateException(
1004            "No X509TrustManager implementation available");
1005    }
1006
1007    @Override
1008    public void checkServerTrusted(X509Certificate[] chain, String authType,
1009            Socket socket) throws CertificateException {
1010        throw new CertificateException(
1011            "No X509TrustManager implementation available");
1012    }
1013
1014    @Override
1015    public void checkClientTrusted(X509Certificate[] chain, String authType,
1016            SSLEngine engine) throws CertificateException {
1017        throw new CertificateException(
1018            "No X509TrustManager implementation available");
1019    }
1020
1021    @Override
1022    public void checkServerTrusted(X509Certificate[] chain, String authType,
1023            SSLEngine engine) throws CertificateException {
1024        throw new CertificateException(
1025            "No X509TrustManager implementation available");
1026    }
1027}
1028
1029/*
1030 * A wrapper class to turn a X509KeyManager into an X509ExtendedKeyManager
1031 */
1032final class AbstractKeyManagerWrapper extends X509ExtendedKeyManager {
1033
1034    private final X509KeyManager km;
1035
1036    AbstractKeyManagerWrapper(X509KeyManager km) {
1037        this.km = km;
1038    }
1039
1040    public String[] getClientAliases(String keyType, Principal[] issuers) {
1041        return km.getClientAliases(keyType, issuers);
1042    }
1043
1044    public String chooseClientAlias(String[] keyType, Principal[] issuers,
1045            Socket socket) {
1046        return km.chooseClientAlias(keyType, issuers, socket);
1047    }
1048
1049    public String[] getServerAliases(String keyType, Principal[] issuers) {
1050        return km.getServerAliases(keyType, issuers);
1051    }
1052
1053    public String chooseServerAlias(String keyType, Principal[] issuers,
1054            Socket socket) {
1055        return km.chooseServerAlias(keyType, issuers, socket);
1056    }
1057
1058    public X509Certificate[] getCertificateChain(String alias) {
1059        return km.getCertificateChain(alias);
1060    }
1061
1062    public PrivateKey getPrivateKey(String alias) {
1063        return km.getPrivateKey(alias);
1064    }
1065
1066    // Inherit chooseEngineClientAlias() and chooseEngineServerAlias() from
1067    // X509ExtendedKeymanager. It defines them to return null;
1068}
1069
1070
1071// Dummy X509KeyManager implementation, never returns any certificates/keys.
1072// Used if the application did not specify a proper X509TrustManager.
1073final class DummyX509KeyManager extends X509ExtendedKeyManager {
1074
1075    static final X509ExtendedKeyManager INSTANCE = new DummyX509KeyManager();
1076
1077    private DummyX509KeyManager() {
1078        // empty
1079    }
1080
1081    /*
1082     * Get the matching aliases for authenticating the client side of a secure
1083     * socket given the public key type and the list of
1084     * certificate issuer authorities recognized by the peer (if any).
1085     */
1086    public String[] getClientAliases(String keyType, Principal[] issuers) {
1087        return null;
1088    }
1089
1090    /*
1091     * Choose an alias to authenticate the client side of a secure
1092     * socket given the public key type and the list of
1093     * certificate issuer authorities recognized by the peer (if any).
1094     */
1095    public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
1096            Socket socket) {
1097        return null;
1098    }
1099
1100    /*
1101     * Choose an alias to authenticate the client side of an
1102     * engine given the public key type and the list of
1103     * certificate issuer authorities recognized by the peer (if any).
1104     */
1105    public String chooseEngineClientAlias(
1106            String[] keyTypes, Principal[] issuers, SSLEngine engine) {
1107        return null;
1108    }
1109
1110    /*
1111     * Get the matching aliases for authenticating the server side of a secure
1112     * socket given the public key type and the list of
1113     * certificate issuer authorities recognized by the peer (if any).
1114     */
1115    public String[] getServerAliases(String keyType, Principal[] issuers) {
1116        return null;
1117    }
1118
1119    /*
1120     * Choose an alias to authenticate the server side of a secure
1121     * socket given the public key type and the list of
1122     * certificate issuer authorities recognized by the peer (if any).
1123     */
1124    public String chooseServerAlias(String keyType, Principal[] issuers,
1125            Socket socket) {
1126        return null;
1127    }
1128
1129    /*
1130     * Choose an alias to authenticate the server side of an engine
1131     * given the public key type and the list of
1132     * certificate issuer authorities recognized by the peer (if any).
1133     */
1134    public String chooseEngineServerAlias(
1135            String keyType, Principal[] issuers, SSLEngine engine) {
1136        return null;
1137    }
1138
1139    /**
1140     * Returns the certificate chain associated with the given alias.
1141     *
1142     * @param alias the alias name
1143     *
1144     * @return the certificate chain (ordered with the user's certificate first
1145     * and the root certificate authority last)
1146     */
1147    public X509Certificate[] getCertificateChain(String alias) {
1148        return null;
1149    }
1150
1151    /*
1152     * Returns the key associated with the given alias, using the given
1153     * password to recover it.
1154     *
1155     * @param alias the alias name
1156     *
1157     * @return the requested key
1158     */
1159    public PrivateKey getPrivateKey(String alias) {
1160        return null;
1161    }
1162}
1163