SSLContextImpl.java revision 12745:f068a4ffddd2
1/*
2 * Copyright (c) 1999, 2015, 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;
39import sun.security.action.GetPropertyAction;
40
41public abstract class SSLContextImpl extends SSLContextSpi {
42
43    private static final Debug debug = Debug.getInstance("ssl");
44
45    private final EphemeralKeyManager ephemeralKeyManager;
46    private final SSLSessionContextImpl clientCache;
47    private final SSLSessionContextImpl serverCache;
48
49    private boolean isInitialized;
50
51    private X509ExtendedKeyManager keyManager;
52    private X509TrustManager trustManager;
53    private SecureRandom secureRandom;
54
55    // supported and default protocols
56    private ProtocolList defaultServerProtocolList;
57    private ProtocolList defaultClientProtocolList;
58    private ProtocolList supportedProtocolList;
59
60    // supported and default cipher suites
61    private CipherSuiteList defaultServerCipherSuiteList;
62    private CipherSuiteList defaultClientCipherSuiteList;
63    private CipherSuiteList supportedCipherSuiteList;
64
65    // DTLS cookie exchange manager
66    private HelloCookieManager helloCookieManager;
67
68    private StatusResponseManager statusResponseManager;
69
70    SSLContextImpl() {
71        ephemeralKeyManager = new EphemeralKeyManager();
72        clientCache = new SSLSessionContextImpl();
73        serverCache = new SSLSessionContextImpl();
74    }
75
76    @Override
77    protected void engineInit(KeyManager[] km, TrustManager[] tm,
78                                SecureRandom sr) throws KeyManagementException {
79        isInitialized = false;
80        keyManager = chooseKeyManager(km);
81
82        if (tm == null) {
83            try {
84                TrustManagerFactory tmf = TrustManagerFactory.getInstance(
85                        TrustManagerFactory.getDefaultAlgorithm());
86                tmf.init((KeyStore)null);
87                tm = tmf.getTrustManagers();
88            } catch (Exception e) {
89                // eat
90            }
91        }
92        trustManager = chooseTrustManager(tm);
93        statusResponseManager = new StatusResponseManager();
94
95        if (sr == null) {
96            secureRandom = JsseJce.getSecureRandom();
97        } else {
98            if (SunJSSE.isFIPS() &&
99                        (sr.getProvider() != SunJSSE.cryptoProvider)) {
100                throw new KeyManagementException
101                    ("FIPS mode: SecureRandom must be from provider "
102                    + SunJSSE.cryptoProvider.getName());
103            }
104            secureRandom = sr;
105        }
106
107        /*
108         * The initial delay of seeding the random number generator
109         * could be long enough to cause the initial handshake on our
110         * first connection to timeout and fail. Make sure it is
111         * primed and ready by getting some initial output from it.
112         */
113        if (debug != null && Debug.isOn("sslctx")) {
114            System.out.println("trigger seeding of SecureRandom");
115        }
116        secureRandom.nextInt();
117        if (debug != null && Debug.isOn("sslctx")) {
118            System.out.println("done seeding SecureRandom");
119        }
120        isInitialized = true;
121    }
122
123    private X509TrustManager chooseTrustManager(TrustManager[] tm)
124            throws KeyManagementException {
125        // We only use the first instance of X509TrustManager passed to us.
126        for (int i = 0; tm != null && i < tm.length; i++) {
127            if (tm[i] instanceof X509TrustManager) {
128                if (SunJSSE.isFIPS() &&
129                        !(tm[i] instanceof X509TrustManagerImpl)) {
130                    throw new KeyManagementException
131                        ("FIPS mode: only SunJSSE TrustManagers may be used");
132                }
133
134                if (tm[i] instanceof X509ExtendedTrustManager) {
135                    return (X509TrustManager)tm[i];
136                } else {
137                    return new AbstractTrustManagerWrapper(
138                                        (X509TrustManager)tm[i]);
139                }
140            }
141        }
142
143        // nothing found, return a dummy X509TrustManager.
144        return DummyX509TrustManager.INSTANCE;
145    }
146
147    private X509ExtendedKeyManager chooseKeyManager(KeyManager[] kms)
148            throws KeyManagementException {
149        for (int i = 0; kms != null && i < kms.length; i++) {
150            KeyManager km = kms[i];
151            if (!(km instanceof X509KeyManager)) {
152                continue;
153            }
154            if (SunJSSE.isFIPS()) {
155                // In FIPS mode, require that one of SunJSSE's own keymanagers
156                // is used. Otherwise, we cannot be sure that only keys from
157                // the FIPS token are used.
158                if ((km instanceof X509KeyManagerImpl)
159                            || (km instanceof SunX509KeyManagerImpl)) {
160                    return (X509ExtendedKeyManager)km;
161                } else {
162                    // throw exception, we don't want to silently use the
163                    // dummy keymanager without telling the user.
164                    throw new KeyManagementException
165                        ("FIPS mode: only SunJSSE KeyManagers may be used");
166                }
167            }
168            if (km instanceof X509ExtendedKeyManager) {
169                return (X509ExtendedKeyManager)km;
170            }
171            if (debug != null && Debug.isOn("sslctx")) {
172                System.out.println(
173                    "X509KeyManager passed to " +
174                    "SSLContext.init():  need an " +
175                    "X509ExtendedKeyManager for SSLEngine use");
176            }
177            return new AbstractKeyManagerWrapper((X509KeyManager)km);
178        }
179
180        // nothing found, return a dummy X509ExtendedKeyManager
181        return DummyX509KeyManager.INSTANCE;
182    }
183
184    abstract SSLEngine createSSLEngineImpl();
185    abstract SSLEngine createSSLEngineImpl(String host, int port);
186
187    @Override
188    protected SSLEngine engineCreateSSLEngine() {
189        if (!isInitialized) {
190            throw new IllegalStateException("SSLContext is not initialized");
191        }
192        return createSSLEngineImpl();
193    }
194
195    @Override
196    protected SSLEngine engineCreateSSLEngine(String host, int port) {
197        if (!isInitialized) {
198            throw new IllegalStateException("SSLContext is not initialized");
199        }
200        return createSSLEngineImpl(host, port);
201    }
202
203    @Override
204    protected SSLSocketFactory engineGetSocketFactory() {
205        if (!isInitialized) {
206            throw new IllegalStateException("SSLContext is not initialized");
207        }
208       return new SSLSocketFactoryImpl(this);
209    }
210
211    @Override
212    protected SSLServerSocketFactory engineGetServerSocketFactory() {
213        if (!isInitialized) {
214            throw new IllegalStateException("SSLContext is not initialized");
215        }
216        return new SSLServerSocketFactoryImpl(this);
217    }
218
219    @Override
220    protected SSLSessionContext engineGetClientSessionContext() {
221        return clientCache;
222    }
223
224    @Override
225    protected SSLSessionContext engineGetServerSessionContext() {
226        return serverCache;
227    }
228
229    SecureRandom getSecureRandom() {
230        return secureRandom;
231    }
232
233    X509ExtendedKeyManager getX509KeyManager() {
234        return keyManager;
235    }
236
237    X509TrustManager getX509TrustManager() {
238        return trustManager;
239    }
240
241    EphemeralKeyManager getEphemeralKeyManager() {
242        return ephemeralKeyManager;
243    }
244
245    HelloCookieManager getHelloCookieManager() {
246        if (!isInitialized) {
247            throw new IllegalStateException("SSLContext is not initialized");
248        }
249
250        if (helloCookieManager == null) {
251            helloCookieManager = getHelloCookieManager(secureRandom);
252        }
253
254        return helloCookieManager;
255    }
256
257    HelloCookieManager getHelloCookieManager(SecureRandom secureRandom) {
258        throw new UnsupportedOperationException(
259                "Cookie exchange applies to DTLS only");
260    }
261
262    StatusResponseManager getStatusResponseManager() {
263        return statusResponseManager;
264    }
265
266    abstract SSLParameters getDefaultServerSSLParams();
267    abstract SSLParameters getDefaultClientSSLParams();
268    abstract SSLParameters getSupportedSSLParams();
269
270    // Get supported ProtocolList.
271    ProtocolList getSuportedProtocolList() {
272        if (supportedProtocolList == null) {
273            supportedProtocolList =
274                new ProtocolList(getSupportedSSLParams().getProtocols());
275        }
276
277        return supportedProtocolList;
278    }
279
280    // Get default ProtocolList.
281    ProtocolList getDefaultProtocolList(boolean roleIsServer) {
282        if (roleIsServer) {
283            if (defaultServerProtocolList == null) {
284                defaultServerProtocolList = new ProtocolList(
285                        getDefaultServerSSLParams().getProtocols());
286            }
287
288            return defaultServerProtocolList;
289        } else {
290            if (defaultClientProtocolList == null) {
291                defaultClientProtocolList = new ProtocolList(
292                        getDefaultClientSSLParams().getProtocols());
293            }
294
295            return defaultClientProtocolList;
296        }
297    }
298
299    // Get supported CipherSuiteList.
300    CipherSuiteList getSupportedCipherSuiteList() {
301        // The maintenance of cipher suites needs to be synchronized.
302        synchronized (this) {
303            // Clear cache of available ciphersuites.
304            clearAvailableCache();
305
306            if (supportedCipherSuiteList == null) {
307                supportedCipherSuiteList = getApplicableCipherSuiteList(
308                        getSuportedProtocolList(), false);
309            }
310
311            return supportedCipherSuiteList;
312        }
313    }
314
315    // Get default CipherSuiteList.
316    CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
317        // The maintenance of cipher suites needs to be synchronized.
318        synchronized (this) {
319            // Clear cache of available ciphersuites.
320            clearAvailableCache();
321
322            if (roleIsServer) {
323                if (defaultServerCipherSuiteList == null) {
324                    defaultServerCipherSuiteList = getApplicableCipherSuiteList(
325                        getDefaultProtocolList(true), true);
326                }
327
328                return defaultServerCipherSuiteList;
329            } else {
330                if (defaultClientCipherSuiteList == null) {
331                    defaultClientCipherSuiteList = getApplicableCipherSuiteList(
332                        getDefaultProtocolList(false), true);
333                }
334
335                return defaultClientCipherSuiteList;
336            }
337        }
338    }
339
340    /**
341     * Return whether a protocol list is the original default enabled
342     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
343     */
344    boolean isDefaultProtocolList(ProtocolList protocols) {
345        return (protocols == defaultServerProtocolList) ||
346               (protocols == defaultClientProtocolList);
347    }
348
349    /**
350     * Return whether a protocol list is the original default enabled
351     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
352     */
353    boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
354        return (cipherSuites == defaultClientCipherSuiteList) ||
355               (cipherSuites == defaultServerCipherSuiteList);
356    }
357
358    /*
359     * Return the list of all available CipherSuites with a priority of
360     * minPriority or above.
361     */
362    private static CipherSuiteList getApplicableCipherSuiteList(
363            ProtocolList protocols, boolean onlyEnabled) {
364
365        int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
366        if (onlyEnabled) {
367            minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
368        }
369
370        Collection<CipherSuite> allowedCipherSuites =
371                                    CipherSuite.allowedCipherSuites();
372
373        TreeSet<CipherSuite> suites = new TreeSet<>();
374        if (!(protocols.collection().isEmpty()) &&
375                protocols.min.v != ProtocolVersion.NONE.v) {
376            for (CipherSuite suite : allowedCipherSuites) {
377                if (!suite.allowed || suite.priority < minPriority) {
378                    continue;
379                }
380
381                if (suite.isAvailable() &&
382                        !protocols.min.obsoletes(suite) &&
383                        protocols.max.supports(suite)) {
384                    if (SSLAlgorithmConstraints.DEFAULT.permits(
385                            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
386                            suite.name, null)) {
387                        suites.add(suite);
388                    }
389                } else if (debug != null &&
390                        Debug.isOn("sslctx") && Debug.isOn("verbose")) {
391                    if (protocols.min.obsoletes(suite)) {
392                        System.out.println(
393                            "Ignoring obsoleted cipher suite: " + suite);
394                    } else if (!protocols.max.supports(suite)) {
395                        System.out.println(
396                            "Ignoring unsupported cipher suite: " + suite);
397                    } else {
398                        System.out.println(
399                            "Ignoring unavailable cipher suite: " + suite);
400                    }
401                }
402            }
403        }
404
405        return new CipherSuiteList(suites);
406    }
407
408    /**
409     * Clear cache of available ciphersuites. If we support all ciphers
410     * internally, there is no need to clear the cache and calling this
411     * method has no effect.
412     *
413     * Note that every call to clearAvailableCache() and the maintenance of
414     * cipher suites need to be synchronized with this instance.
415     */
416    private void clearAvailableCache() {
417        if (CipherSuite.DYNAMIC_AVAILABILITY) {
418            supportedCipherSuiteList = null;
419            defaultServerCipherSuiteList = null;
420            defaultClientCipherSuiteList = null;
421            CipherSuite.BulkCipher.clearAvailableCache();
422            JsseJce.clearEcAvailable();
423        }
424    }
425
426    private static String[] getAvailableProtocols(
427            ProtocolVersion[] protocolCandidates) {
428
429        List<String> availableProtocols = Collections.<String>emptyList();
430        if (protocolCandidates !=  null && protocolCandidates.length != 0) {
431            availableProtocols = new ArrayList<>(protocolCandidates.length);
432            for (ProtocolVersion p : protocolCandidates) {
433                if (ProtocolVersion.availableProtocols.contains(p)) {
434                    availableProtocols.add(p.name);
435                }
436            }
437        }
438
439        return availableProtocols.toArray(new String[0]);
440    }
441
442
443    /*
444     * The SSLContext implementation for SSL/(D)TLS algorithm
445     *
446     * SSL/TLS protocols specify the forward compatibility and version
447     * roll-back attack protections, however, a number of SSL/TLS server
448     * vendors did not implement these aspects properly, and some current
449     * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
450     *
451     * Considering above interoperability issues, SunJSSE will not set
452     * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
453     *
454     * For SSL/TLS servers, there is no such interoperability issues as
455     * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
456     * enabled protocols for server by default.
457     *
458     * We may change the behavior when popular TLS/SSL vendors support TLS
459     * forward compatibility properly.
460     *
461     * SSLv2Hello is no longer necessary.  This interoperability option was
462     * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
463     * and there were a fair number of SSLv2-only servers deployed.  Because
464     * of the security issues in SSLv2, it is rarely (if ever) used, as
465     * deployments should now be using SSLv3 and TLSv1.
466     *
467     * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
468     * by default. Applications still can use it by enabling SSLv2Hello with
469     * the series of setEnabledProtocols APIs.
470     */
471
472    /*
473     * The base abstract SSLContext implementation for the Transport Layer
474     * Security (TLS) protocols.
475     *
476     * This abstract class encapsulates supported and the default server
477     * SSL/TLS parameters.
478     *
479     * @see SSLContext
480     */
481    private abstract static class AbstractTLSContext extends SSLContextImpl {
482        // parameters
483        private static final SSLParameters defaultServerSSLParams;
484        private static final SSLParameters supportedSSLParams;
485
486        static {
487            // supported SSL parameters
488            supportedSSLParams = new SSLParameters();
489
490            // candidates for available protocols
491            ProtocolVersion[] candidates;
492
493            if (SunJSSE.isFIPS()) {
494                supportedSSLParams.setProtocols(new String[] {
495                    ProtocolVersion.TLS10.name,
496                    ProtocolVersion.TLS11.name,
497                    ProtocolVersion.TLS12.name
498                });
499
500                candidates = new ProtocolVersion[] {
501                    ProtocolVersion.TLS10,
502                    ProtocolVersion.TLS11,
503                    ProtocolVersion.TLS12
504                };
505            } else {
506                supportedSSLParams.setProtocols(new String[] {
507                    ProtocolVersion.SSL20Hello.name,
508                    ProtocolVersion.SSL30.name,
509                    ProtocolVersion.TLS10.name,
510                    ProtocolVersion.TLS11.name,
511                    ProtocolVersion.TLS12.name
512                });
513
514                candidates = new ProtocolVersion[] {
515                    ProtocolVersion.SSL20Hello,
516                    ProtocolVersion.SSL30,
517                    ProtocolVersion.TLS10,
518                    ProtocolVersion.TLS11,
519                    ProtocolVersion.TLS12
520                };
521            }
522
523            defaultServerSSLParams = new SSLParameters();
524            defaultServerSSLParams.setProtocols(
525                    getAvailableProtocols(candidates));
526        }
527
528        @Override
529        SSLParameters getDefaultServerSSLParams() {
530            return defaultServerSSLParams;
531        }
532
533        @Override
534        SSLParameters getSupportedSSLParams() {
535            return supportedSSLParams;
536        }
537
538        @Override
539        SSLEngine createSSLEngineImpl() {
540            return new SSLEngineImpl(this, false);
541        }
542
543        @Override
544        SSLEngine createSSLEngineImpl(String host, int port) {
545            return new SSLEngineImpl(this, host, port, false);
546        }
547    }
548
549    /*
550     * The SSLContext implementation for SSLv3 and TLS10 algorithm
551     *
552     * @see SSLContext
553     */
554    public static final class TLS10Context extends AbstractTLSContext {
555        private static final SSLParameters defaultClientSSLParams;
556
557        static {
558            // candidates for available protocols
559            ProtocolVersion[] candidates;
560            if (SunJSSE.isFIPS()) {
561                candidates = new ProtocolVersion[] {
562                    ProtocolVersion.TLS10
563                };
564            } else {
565                candidates = new ProtocolVersion[] {
566                    ProtocolVersion.SSL30,
567                    ProtocolVersion.TLS10
568                };
569            }
570
571            defaultClientSSLParams = new SSLParameters();
572            defaultClientSSLParams.setProtocols(
573                    getAvailableProtocols(candidates));
574        }
575
576        @Override
577        SSLParameters getDefaultClientSSLParams() {
578            return defaultClientSSLParams;
579        }
580    }
581
582    /*
583     * The SSLContext implementation for TLS11 algorithm
584     *
585     * @see SSLContext
586     */
587    public static final class TLS11Context extends AbstractTLSContext {
588        private static final SSLParameters defaultClientSSLParams;
589
590        static {
591            // candidates for available protocols
592            ProtocolVersion[] candidates;
593            if (SunJSSE.isFIPS()) {
594                candidates = new ProtocolVersion[] {
595                    ProtocolVersion.TLS10,
596                    ProtocolVersion.TLS11
597                };
598            } else {
599                candidates = new ProtocolVersion[] {
600                    ProtocolVersion.SSL30,
601                    ProtocolVersion.TLS10,
602                    ProtocolVersion.TLS11
603                };
604            }
605
606            defaultClientSSLParams = new SSLParameters();
607            defaultClientSSLParams.setProtocols(
608                    getAvailableProtocols(candidates));
609        }
610
611        @Override
612        SSLParameters getDefaultClientSSLParams() {
613            return defaultClientSSLParams;
614        }
615    }
616
617    /*
618     * The SSLContext implementation for TLS12 algorithm
619     *
620     * @see SSLContext
621     */
622    public static final class TLS12Context extends AbstractTLSContext {
623        private static final SSLParameters defaultClientSSLParams;
624
625        static {
626            // candidates for available protocols
627            ProtocolVersion[] candidates;
628            if (SunJSSE.isFIPS()) {
629                candidates = new ProtocolVersion[] {
630                    ProtocolVersion.TLS10,
631                    ProtocolVersion.TLS11,
632                    ProtocolVersion.TLS12
633                };
634            } else {
635                candidates = new ProtocolVersion[] {
636                    ProtocolVersion.SSL30,
637                    ProtocolVersion.TLS10,
638                    ProtocolVersion.TLS11,
639                    ProtocolVersion.TLS12
640                };
641            }
642
643            defaultClientSSLParams = new SSLParameters();
644            defaultClientSSLParams.setProtocols(
645                    getAvailableProtocols(candidates));
646        }
647
648        @Override
649        SSLParameters getDefaultClientSSLParams() {
650            return defaultClientSSLParams;
651        }
652    }
653
654    /*
655     * The interface for the customized SSL/(D)TLS SSLContext.
656     *
657     * @see SSLContext
658     */
659    private static class CustomizedSSLProtocols {
660        private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
661        static IllegalArgumentException reservedException = null;
662        static ArrayList<ProtocolVersion>
663                                customizedProtocols = new ArrayList<>();
664
665        // Don't want a java.lang.LinkageError for illegal system property.
666        //
667        // Please don't throw exception in this static block.  Otherwise,
668        // java.lang.LinkageError may be thrown during the instantiation of
669        // the provider service. Instead, please handle the initialization
670        // exception in the caller's constructor.
671        static {
672            String property = AccessController.doPrivileged(
673                    new GetPropertyAction(PROPERTY_NAME));
674            if (property != null && property.length() != 0) {
675                // remove double quote marks from beginning/end of the property
676                if (property.length() > 1 && property.charAt(0) == '"' &&
677                        property.charAt(property.length() - 1) == '"') {
678                    property = property.substring(1, property.length() - 1);
679                }
680            }
681
682            if (property != null && property.length() != 0) {
683                String[] protocols = property.split(",");
684                for (int i = 0; i < protocols.length; i++) {
685                    protocols[i] = protocols[i].trim();
686                    // Is it a supported protocol name?
687                    try {
688                        ProtocolVersion pro =
689                                ProtocolVersion.valueOf(protocols[i]);
690
691                        if (SunJSSE.isFIPS() &&
692                                ((pro.v == ProtocolVersion.SSL30.v) ||
693                                 (pro.v == ProtocolVersion.SSL20Hello.v))) {
694                            reservedException = new IllegalArgumentException(
695                                    PROPERTY_NAME + ": " + pro +
696                                    " is not FIPS compliant");
697
698                            break;
699                        }
700
701                        // ignore duplicated protocols
702                        if (!customizedProtocols.contains(pro)) {
703                            customizedProtocols.add(pro);
704                        }
705                    } catch (IllegalArgumentException iae) {
706                        reservedException = new IllegalArgumentException(
707                                PROPERTY_NAME + ": " + protocols[i] +
708                                " is not a standard SSL protocol name", iae);
709                    }
710                }
711            }
712        }
713    }
714
715    /*
716     * The SSLContext implementation for customized TLS protocols
717     *
718     * @see SSLContext
719     */
720    private static class CustomizedTLSContext extends AbstractTLSContext {
721
722        private static final SSLParameters defaultClientSSLParams;
723        private static IllegalArgumentException reservedException = null;
724
725        // Don't want a java.lang.LinkageError for illegal system property.
726        //
727        // Please don't throw exception in this static block.  Otherwise,
728        // java.lang.LinkageError may be thrown during the instantiation of
729        // the provider service. Instead, let's handle the initialization
730        // exception in constructor.
731        static {
732            reservedException = CustomizedSSLProtocols.reservedException;
733            if (reservedException == null) {
734                ArrayList<ProtocolVersion>
735                        customizedTLSProtocols = new ArrayList<>();
736                for (ProtocolVersion protocol :
737                        CustomizedSSLProtocols.customizedProtocols) {
738                    if (!protocol.isDTLSProtocol()) {
739                        customizedTLSProtocols.add(protocol);
740                    }
741                }
742
743                // candidates for available protocols
744                ProtocolVersion[] candidates;
745                if (customizedTLSProtocols.isEmpty()) {
746                    // Use the default enabled client protocols if no
747                    // customized TLS protocols.
748                    if (SunJSSE.isFIPS()) {
749                        candidates = new ProtocolVersion[] {
750                            ProtocolVersion.TLS10,
751                            ProtocolVersion.TLS11,
752                            ProtocolVersion.TLS12
753                        };
754                    } else {
755                        candidates = new ProtocolVersion[] {
756                            ProtocolVersion.SSL30,
757                            ProtocolVersion.TLS10,
758                            ProtocolVersion.TLS11,
759                            ProtocolVersion.TLS12
760                        };
761                    }
762                } else {
763                    // Use the customized TLS protocols.
764                    candidates =
765                            new ProtocolVersion[customizedTLSProtocols.size()];
766                    candidates = customizedTLSProtocols.toArray(candidates);
767                }
768
769                defaultClientSSLParams = new SSLParameters();
770                defaultClientSSLParams.setProtocols(
771                        getAvailableProtocols(candidates));
772            } else {
773                defaultClientSSLParams = null;  // unlikely to be used
774            }
775        }
776
777        protected CustomizedTLSContext() {
778            if (reservedException != null) {
779                throw reservedException;
780            }
781        }
782
783        @Override
784        SSLParameters getDefaultClientSSLParams() {
785            return defaultClientSSLParams;
786        }
787    }
788
789    /*
790     * The SSLContext implementation for default "TLS" algorithm
791     *
792     * @see SSLContext
793     */
794    public static final class TLSContext extends CustomizedTLSContext {
795        // use the default constructor and methods
796    }
797
798    /*
799     * The SSLContext implementation for default "Default" algorithm
800     *
801     * @see SSLContext
802     */
803    public static final class DefaultSSLContext extends CustomizedTLSContext {
804        private static final String NONE = "NONE";
805        private static final String P11KEYSTORE = "PKCS11";
806
807        private static volatile SSLContextImpl defaultImpl;
808
809        private static TrustManager[] defaultTrustManagers;
810        private static KeyManager[] defaultKeyManagers;
811
812        public DefaultSSLContext() throws Exception {
813            try {
814                super.engineInit(getDefaultKeyManager(),
815                        getDefaultTrustManager(), null);
816            } catch (Exception e) {
817                if (debug != null && Debug.isOn("defaultctx")) {
818                    System.out.println("default context init failed: " + e);
819                }
820                throw e;
821            }
822
823            if (defaultImpl == null) {
824                defaultImpl = this;
825            }
826        }
827
828        @Override
829        protected void engineInit(KeyManager[] km, TrustManager[] tm,
830            SecureRandom sr) throws KeyManagementException {
831            throw new KeyManagementException
832                ("Default SSLContext is initialized automatically");
833        }
834
835        static synchronized SSLContextImpl getDefaultImpl() throws Exception {
836            if (defaultImpl == null) {
837                new DefaultSSLContext();
838            }
839            return defaultImpl;
840        }
841
842        private static synchronized TrustManager[] getDefaultTrustManager()
843                throws Exception {
844            if (defaultTrustManagers != null) {
845                return defaultTrustManagers;
846            }
847
848            KeyStore ks =
849                TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
850
851            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
852                TrustManagerFactory.getDefaultAlgorithm());
853            tmf.init(ks);
854            defaultTrustManagers = tmf.getTrustManagers();
855            return defaultTrustManagers;
856        }
857
858        private static synchronized KeyManager[] getDefaultKeyManager()
859                throws Exception {
860            if (defaultKeyManagers != null) {
861                return defaultKeyManagers;
862            }
863
864            final Map<String,String> props = new HashMap<>();
865            AccessController.doPrivileged(
866                        new PrivilegedExceptionAction<Object>() {
867                @Override
868                public Object run() throws Exception {
869                    props.put("keyStore",  System.getProperty(
870                                "javax.net.ssl.keyStore", ""));
871                    props.put("keyStoreType", System.getProperty(
872                                "javax.net.ssl.keyStoreType",
873                                KeyStore.getDefaultType()));
874                    props.put("keyStoreProvider", System.getProperty(
875                                "javax.net.ssl.keyStoreProvider", ""));
876                    props.put("keyStorePasswd", System.getProperty(
877                                "javax.net.ssl.keyStorePassword", ""));
878                    return null;
879                }
880            });
881
882            final String defaultKeyStore = props.get("keyStore");
883            String defaultKeyStoreType = props.get("keyStoreType");
884            String defaultKeyStoreProvider = props.get("keyStoreProvider");
885            if (debug != null && Debug.isOn("defaultctx")) {
886                System.out.println("keyStore is : " + defaultKeyStore);
887                System.out.println("keyStore type is : " +
888                                        defaultKeyStoreType);
889                System.out.println("keyStore provider is : " +
890                                        defaultKeyStoreProvider);
891            }
892
893            if (P11KEYSTORE.equals(defaultKeyStoreType) &&
894                    !NONE.equals(defaultKeyStore)) {
895                throw new IllegalArgumentException("if keyStoreType is "
896                    + P11KEYSTORE + ", then keyStore must be " + NONE);
897            }
898
899            FileInputStream fs = null;
900            KeyStore ks = null;
901            char[] passwd = null;
902            try {
903                if (defaultKeyStore.length() != 0 &&
904                        !NONE.equals(defaultKeyStore)) {
905                    fs = AccessController.doPrivileged(
906                            new PrivilegedExceptionAction<FileInputStream>() {
907                        @Override
908                        public FileInputStream run() throws Exception {
909                            return new FileInputStream(defaultKeyStore);
910                        }
911                    });
912                }
913
914                String defaultKeyStorePassword = props.get("keyStorePasswd");
915                if (defaultKeyStorePassword.length() != 0) {
916                    passwd = defaultKeyStorePassword.toCharArray();
917                }
918
919                /**
920                 * Try to initialize key store.
921                 */
922                if ((defaultKeyStoreType.length()) != 0) {
923                    if (debug != null && Debug.isOn("defaultctx")) {
924                        System.out.println("init keystore");
925                    }
926                    if (defaultKeyStoreProvider.length() == 0) {
927                        ks = KeyStore.getInstance(defaultKeyStoreType);
928                    } else {
929                        ks = KeyStore.getInstance(defaultKeyStoreType,
930                                            defaultKeyStoreProvider);
931                    }
932
933                    // if defaultKeyStore is NONE, fs will be null
934                    ks.load(fs, passwd);
935                }
936            } finally {
937                if (fs != null) {
938                    fs.close();
939                    fs = null;
940                }
941            }
942
943            /*
944             * Try to initialize key manager.
945             */
946            if (debug != null && Debug.isOn("defaultctx")) {
947                System.out.println("init keymanager of type " +
948                    KeyManagerFactory.getDefaultAlgorithm());
949            }
950            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
951                KeyManagerFactory.getDefaultAlgorithm());
952
953            if (P11KEYSTORE.equals(defaultKeyStoreType)) {
954                kmf.init(ks, null); // do not pass key passwd if using token
955            } else {
956                kmf.init(ks, passwd);
957            }
958
959            defaultKeyManagers = kmf.getKeyManagers();
960            return defaultKeyManagers;
961        }
962    }
963
964    /*
965     * The base abstract SSLContext implementation for the Datagram Transport
966     * Layer Security (DTLS) protocols.
967     *
968     * This abstract class encapsulates supported and the default server DTLS
969     * parameters.
970     *
971     * @see SSLContext
972     */
973    private abstract static class AbstractDTLSContext extends SSLContextImpl {
974        // parameters
975        private static final SSLParameters defaultServerSSLParams;
976        private static final SSLParameters supportedSSLParams;
977
978        static {
979            // supported SSL parameters
980            supportedSSLParams = new SSLParameters();
981
982            // Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
983            supportedSSLParams.setProtocols(new String[] {
984                ProtocolVersion.DTLS10.name,
985                ProtocolVersion.DTLS12.name
986            });
987
988            // candidates for available protocols
989            ProtocolVersion[] candidates = new ProtocolVersion[] {
990                ProtocolVersion.DTLS10,
991                ProtocolVersion.DTLS12
992            };
993
994            defaultServerSSLParams = new SSLParameters();
995            defaultServerSSLParams.setProtocols(
996                    getAvailableProtocols(candidates));
997        }
998
999        @Override
1000        SSLParameters getDefaultServerSSLParams() {
1001            return defaultServerSSLParams;
1002        }
1003
1004        @Override
1005        SSLParameters getSupportedSSLParams() {
1006            return supportedSSLParams;
1007        }
1008
1009        @Override
1010        SSLEngine createSSLEngineImpl() {
1011            return new SSLEngineImpl(this, true);
1012        }
1013
1014        @Override
1015        SSLEngine createSSLEngineImpl(String host, int port) {
1016            return new SSLEngineImpl(this, host, port, true);
1017        }
1018
1019        @Override
1020        HelloCookieManager getHelloCookieManager(SecureRandom secureRandom) {
1021            return new HelloCookieManager(secureRandom);
1022        }
1023    }
1024
1025    /*
1026     * The SSLContext implementation for DTLSv1.0 algorithm.
1027     *
1028     * @see SSLContext
1029     */
1030    public static final class DTLS10Context extends AbstractDTLSContext {
1031        private static final SSLParameters defaultClientSSLParams;
1032
1033        static {
1034            // candidates for available protocols
1035            ProtocolVersion[] candidates = new ProtocolVersion[] {
1036                ProtocolVersion.DTLS10
1037            };
1038
1039            defaultClientSSLParams = new SSLParameters();
1040            defaultClientSSLParams.setProtocols(
1041                    getAvailableProtocols(candidates));
1042        }
1043
1044        @Override
1045        SSLParameters getDefaultClientSSLParams() {
1046            return defaultClientSSLParams;
1047        }
1048    }
1049
1050    /*
1051     * The SSLContext implementation for DTLSv1.2 algorithm.
1052     *
1053     * @see SSLContext
1054     */
1055    public static final class DTLS12Context extends AbstractDTLSContext {
1056        private static final SSLParameters defaultClientSSLParams;
1057
1058        static {
1059            // candidates for available protocols
1060            ProtocolVersion[] candidates = new ProtocolVersion[] {
1061                ProtocolVersion.DTLS10,
1062                ProtocolVersion.DTLS12
1063            };
1064
1065            defaultClientSSLParams = new SSLParameters();
1066            defaultClientSSLParams.setProtocols(
1067                    getAvailableProtocols(candidates));
1068        }
1069
1070        @Override
1071        SSLParameters getDefaultClientSSLParams() {
1072            return defaultClientSSLParams;
1073        }
1074    }
1075
1076    /*
1077     * The SSLContext implementation for customized TLS protocols
1078     *
1079     * @see SSLContext
1080     */
1081    private static class CustomizedDTLSContext extends AbstractDTLSContext {
1082        private static final SSLParameters defaultClientSSLParams;
1083        private static IllegalArgumentException reservedException = null;
1084
1085        // Don't want a java.lang.LinkageError for illegal system property.
1086        //
1087        // Please don't throw exception in this static block.  Otherwise,
1088        // java.lang.LinkageError may be thrown during the instantiation of
1089        // the provider service. Instead, let's handle the initialization
1090        // exception in constructor.
1091        static {
1092            reservedException = CustomizedSSLProtocols.reservedException;
1093            if (reservedException == null) {
1094                ArrayList<ProtocolVersion>
1095                        customizedDTLSProtocols = new ArrayList<>();
1096                for (ProtocolVersion protocol :
1097                        CustomizedSSLProtocols.customizedProtocols) {
1098                    if (protocol.isDTLSProtocol()) {
1099                        customizedDTLSProtocols.add(protocol);
1100                    }
1101                }
1102
1103                // candidates for available protocols
1104                ProtocolVersion[] candidates;
1105                if (customizedDTLSProtocols.isEmpty()) {
1106                    // Use the default enabled client protocols if no
1107                    // customized TLS protocols.
1108                    //
1109                    // Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
1110                    candidates = new ProtocolVersion[] {
1111                        ProtocolVersion.DTLS10,
1112                        ProtocolVersion.DTLS12
1113                    };
1114
1115                } else {
1116                    // Use the customized TLS protocols.
1117                    candidates =
1118                            new ProtocolVersion[customizedDTLSProtocols.size()];
1119                    candidates = customizedDTLSProtocols.toArray(candidates);
1120                }
1121
1122                defaultClientSSLParams = new SSLParameters();
1123                defaultClientSSLParams.setProtocols(
1124                        getAvailableProtocols(candidates));
1125            } else {
1126                defaultClientSSLParams = null;   // unlikely to be used
1127            }
1128        }
1129
1130        protected CustomizedDTLSContext() {
1131            if (reservedException != null) {
1132                throw reservedException;
1133            }
1134        }
1135
1136        @Override
1137        SSLParameters getDefaultClientSSLParams() {
1138            return defaultClientSSLParams;
1139        }
1140    }
1141
1142    /*
1143     * The SSLContext implementation for default "DTLS" algorithm
1144     *
1145     * @see SSLContext
1146     */
1147    public static final class DTLSContext extends CustomizedDTLSContext {
1148        // use the default constructor and methods
1149    }
1150
1151}
1152
1153
1154final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
1155            implements X509TrustManager {
1156
1157    // the delegated trust manager
1158    private final X509TrustManager tm;
1159
1160    AbstractTrustManagerWrapper(X509TrustManager tm) {
1161        this.tm = tm;
1162    }
1163
1164    @Override
1165    public void checkClientTrusted(X509Certificate[] chain, String authType)
1166        throws CertificateException {
1167        tm.checkClientTrusted(chain, authType);
1168    }
1169
1170    @Override
1171    public void checkServerTrusted(X509Certificate[] chain, String authType)
1172        throws CertificateException {
1173        tm.checkServerTrusted(chain, authType);
1174    }
1175
1176    @Override
1177    public X509Certificate[] getAcceptedIssuers() {
1178        return tm.getAcceptedIssuers();
1179    }
1180
1181    @Override
1182    public void checkClientTrusted(X509Certificate[] chain, String authType,
1183                Socket socket) throws CertificateException {
1184        tm.checkClientTrusted(chain, authType);
1185        checkAdditionalTrust(chain, authType, socket, true);
1186    }
1187
1188    @Override
1189    public void checkServerTrusted(X509Certificate[] chain, String authType,
1190            Socket socket) throws CertificateException {
1191        tm.checkServerTrusted(chain, authType);
1192        checkAdditionalTrust(chain, authType, socket, false);
1193    }
1194
1195    @Override
1196    public void checkClientTrusted(X509Certificate[] chain, String authType,
1197            SSLEngine engine) throws CertificateException {
1198        tm.checkClientTrusted(chain, authType);
1199        checkAdditionalTrust(chain, authType, engine, true);
1200    }
1201
1202    @Override
1203    public void checkServerTrusted(X509Certificate[] chain, String authType,
1204            SSLEngine engine) throws CertificateException {
1205        tm.checkServerTrusted(chain, authType);
1206        checkAdditionalTrust(chain, authType, engine, false);
1207    }
1208
1209    private void checkAdditionalTrust(X509Certificate[] chain, String authType,
1210                Socket socket, boolean isClient) throws CertificateException {
1211        if (socket != null && socket.isConnected() &&
1212                                    socket instanceof SSLSocket) {
1213
1214            SSLSocket sslSocket = (SSLSocket)socket;
1215            SSLSession session = sslSocket.getHandshakeSession();
1216            if (session == null) {
1217                throw new CertificateException("No handshake session");
1218            }
1219
1220            // check endpoint identity
1221            String identityAlg = sslSocket.getSSLParameters().
1222                                        getEndpointIdentificationAlgorithm();
1223            if (identityAlg != null && identityAlg.length() != 0) {
1224                String hostname = session.getPeerHost();
1225                X509TrustManagerImpl.checkIdentity(
1226                                    hostname, chain[0], identityAlg);
1227            }
1228
1229            // try the best to check the algorithm constraints
1230            ProtocolVersion protocolVersion =
1231                ProtocolVersion.valueOf(session.getProtocol());
1232            AlgorithmConstraints constraints = null;
1233            if (protocolVersion.useTLS12PlusSpec()) {
1234                if (session instanceof ExtendedSSLSession) {
1235                    ExtendedSSLSession extSession =
1236                                    (ExtendedSSLSession)session;
1237                    String[] peerSupportedSignAlgs =
1238                            extSession.getLocalSupportedSignatureAlgorithms();
1239
1240                    constraints = new SSLAlgorithmConstraints(
1241                                    sslSocket, peerSupportedSignAlgs, true);
1242                } else {
1243                    constraints =
1244                            new SSLAlgorithmConstraints(sslSocket, true);
1245                }
1246            } else {
1247                constraints = new SSLAlgorithmConstraints(sslSocket, true);
1248            }
1249
1250            checkAlgorithmConstraints(chain, constraints);
1251        }
1252    }
1253
1254    private void checkAdditionalTrust(X509Certificate[] chain, String authType,
1255            SSLEngine engine, boolean isClient) throws CertificateException {
1256        if (engine != null) {
1257            SSLSession session = engine.getHandshakeSession();
1258            if (session == null) {
1259                throw new CertificateException("No handshake session");
1260            }
1261
1262            // check endpoint identity
1263            String identityAlg = engine.getSSLParameters().
1264                                        getEndpointIdentificationAlgorithm();
1265            if (identityAlg != null && identityAlg.length() != 0) {
1266                String hostname = session.getPeerHost();
1267                X509TrustManagerImpl.checkIdentity(
1268                                    hostname, chain[0], identityAlg);
1269            }
1270
1271            // try the best to check the algorithm constraints
1272            ProtocolVersion protocolVersion =
1273                ProtocolVersion.valueOf(session.getProtocol());
1274            AlgorithmConstraints constraints = null;
1275            if (protocolVersion.useTLS12PlusSpec()) {
1276                if (session instanceof ExtendedSSLSession) {
1277                    ExtendedSSLSession extSession =
1278                                    (ExtendedSSLSession)session;
1279                    String[] peerSupportedSignAlgs =
1280                            extSession.getLocalSupportedSignatureAlgorithms();
1281
1282                    constraints = new SSLAlgorithmConstraints(
1283                                    engine, peerSupportedSignAlgs, true);
1284                } else {
1285                    constraints =
1286                            new SSLAlgorithmConstraints(engine, true);
1287                }
1288            } else {
1289                constraints = new SSLAlgorithmConstraints(engine, true);
1290            }
1291
1292            checkAlgorithmConstraints(chain, constraints);
1293        }
1294    }
1295
1296    private void checkAlgorithmConstraints(X509Certificate[] chain,
1297            AlgorithmConstraints constraints) throws CertificateException {
1298
1299        try {
1300            // Does the certificate chain end with a trusted certificate?
1301            int checkedLength = chain.length - 1;
1302
1303            Collection<X509Certificate> trustedCerts = new HashSet<>();
1304            X509Certificate[] certs = tm.getAcceptedIssuers();
1305            if ((certs != null) && (certs.length > 0)){
1306                Collections.addAll(trustedCerts, certs);
1307            }
1308
1309            if (trustedCerts.contains(chain[checkedLength])) {
1310                    checkedLength--;
1311            }
1312
1313            // A forward checker, need to check from trust to target
1314            if (checkedLength >= 0) {
1315                AlgorithmChecker checker = new AlgorithmChecker(constraints);
1316                checker.init(false);
1317                for (int i = checkedLength; i >= 0; i--) {
1318                    Certificate cert = chain[i];
1319                    // We don't care about the unresolved critical extensions.
1320                    checker.check(cert, Collections.<String>emptySet());
1321                }
1322            }
1323        } catch (CertPathValidatorException cpve) {
1324            throw new CertificateException(
1325                "Certificates does not conform to algorithm constraints");
1326        }
1327    }
1328}
1329
1330// Dummy X509TrustManager implementation, rejects all peer certificates.
1331// Used if the application did not specify a proper X509TrustManager.
1332final class DummyX509TrustManager extends X509ExtendedTrustManager
1333            implements X509TrustManager {
1334
1335    static final X509TrustManager INSTANCE = new DummyX509TrustManager();
1336
1337    private DummyX509TrustManager() {
1338        // empty
1339    }
1340
1341    /*
1342     * Given the partial or complete certificate chain
1343     * provided by the peer, build a certificate path
1344     * to a trusted root and return if it can be
1345     * validated and is trusted for client SSL authentication.
1346     * If not, it throws an exception.
1347     */
1348    @Override
1349    public void checkClientTrusted(X509Certificate[] chain, String authType)
1350        throws CertificateException {
1351        throw new CertificateException(
1352            "No X509TrustManager implementation avaiable");
1353    }
1354
1355    /*
1356     * Given the partial or complete certificate chain
1357     * provided by the peer, build a certificate path
1358     * to a trusted root and return if it can be
1359     * validated and is trusted for server SSL authentication.
1360     * If not, it throws an exception.
1361     */
1362    @Override
1363    public void checkServerTrusted(X509Certificate[] chain, String authType)
1364        throws CertificateException {
1365        throw new CertificateException(
1366            "No X509TrustManager implementation available");
1367    }
1368
1369    /*
1370     * Return an array of issuer certificates which are trusted
1371     * for authenticating peers.
1372     */
1373    @Override
1374    public X509Certificate[] getAcceptedIssuers() {
1375        return new X509Certificate[0];
1376    }
1377
1378    @Override
1379    public void checkClientTrusted(X509Certificate[] chain, String authType,
1380                Socket socket) throws CertificateException {
1381        throw new CertificateException(
1382            "No X509TrustManager implementation available");
1383    }
1384
1385    @Override
1386    public void checkServerTrusted(X509Certificate[] chain, String authType,
1387            Socket socket) throws CertificateException {
1388        throw new CertificateException(
1389            "No X509TrustManager implementation available");
1390    }
1391
1392    @Override
1393    public void checkClientTrusted(X509Certificate[] chain, String authType,
1394            SSLEngine engine) throws CertificateException {
1395        throw new CertificateException(
1396            "No X509TrustManager implementation available");
1397    }
1398
1399    @Override
1400    public void checkServerTrusted(X509Certificate[] chain, String authType,
1401            SSLEngine engine) throws CertificateException {
1402        throw new CertificateException(
1403            "No X509TrustManager implementation available");
1404    }
1405}
1406
1407/*
1408 * A wrapper class to turn a X509KeyManager into an X509ExtendedKeyManager
1409 */
1410final class AbstractKeyManagerWrapper extends X509ExtendedKeyManager {
1411
1412    private final X509KeyManager km;
1413
1414    AbstractKeyManagerWrapper(X509KeyManager km) {
1415        this.km = km;
1416    }
1417
1418    @Override
1419    public String[] getClientAliases(String keyType, Principal[] issuers) {
1420        return km.getClientAliases(keyType, issuers);
1421    }
1422
1423    @Override
1424    public String chooseClientAlias(String[] keyType, Principal[] issuers,
1425            Socket socket) {
1426        return km.chooseClientAlias(keyType, issuers, socket);
1427    }
1428
1429    @Override
1430    public String[] getServerAliases(String keyType, Principal[] issuers) {
1431        return km.getServerAliases(keyType, issuers);
1432    }
1433
1434    @Override
1435    public String chooseServerAlias(String keyType, Principal[] issuers,
1436            Socket socket) {
1437        return km.chooseServerAlias(keyType, issuers, socket);
1438    }
1439
1440    @Override
1441    public X509Certificate[] getCertificateChain(String alias) {
1442        return km.getCertificateChain(alias);
1443    }
1444
1445    @Override
1446    public PrivateKey getPrivateKey(String alias) {
1447        return km.getPrivateKey(alias);
1448    }
1449
1450    // Inherit chooseEngineClientAlias() and chooseEngineServerAlias() from
1451    // X509ExtendedKeymanager. It defines them to return null;
1452}
1453
1454
1455// Dummy X509KeyManager implementation, never returns any certificates/keys.
1456// Used if the application did not specify a proper X509TrustManager.
1457final class DummyX509KeyManager extends X509ExtendedKeyManager {
1458
1459    static final X509ExtendedKeyManager INSTANCE = new DummyX509KeyManager();
1460
1461    private DummyX509KeyManager() {
1462        // empty
1463    }
1464
1465    /*
1466     * Get the matching aliases for authenticating the client side of a secure
1467     * socket given the public key type and the list of
1468     * certificate issuer authorities recognized by the peer (if any).
1469     */
1470    @Override
1471    public String[] getClientAliases(String keyType, Principal[] issuers) {
1472        return null;
1473    }
1474
1475    /*
1476     * Choose an alias to authenticate the client side of a secure
1477     * socket given the public key type and the list of
1478     * certificate issuer authorities recognized by the peer (if any).
1479     */
1480    @Override
1481    public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
1482            Socket socket) {
1483        return null;
1484    }
1485
1486    /*
1487     * Choose an alias to authenticate the client side of an
1488     * engine given the public key type and the list of
1489     * certificate issuer authorities recognized by the peer (if any).
1490     */
1491    @Override
1492    public String chooseEngineClientAlias(
1493            String[] keyTypes, Principal[] issuers, SSLEngine engine) {
1494        return null;
1495    }
1496
1497    /*
1498     * Get the matching aliases for authenticating the server side of a secure
1499     * socket given the public key type and the list of
1500     * certificate issuer authorities recognized by the peer (if any).
1501     */
1502    @Override
1503    public String[] getServerAliases(String keyType, Principal[] issuers) {
1504        return null;
1505    }
1506
1507    /*
1508     * Choose an alias to authenticate the server side of a secure
1509     * socket given the public key type and the list of
1510     * certificate issuer authorities recognized by the peer (if any).
1511     */
1512    @Override
1513    public String chooseServerAlias(String keyType, Principal[] issuers,
1514            Socket socket) {
1515        return null;
1516    }
1517
1518    /*
1519     * Choose an alias to authenticate the server side of an engine
1520     * given the public key type and the list of
1521     * certificate issuer authorities recognized by the peer (if any).
1522     */
1523    @Override
1524    public String chooseEngineServerAlias(
1525            String keyType, Principal[] issuers, SSLEngine engine) {
1526        return null;
1527    }
1528
1529    /**
1530     * Returns the certificate chain associated with the given alias.
1531     *
1532     * @param alias the alias name
1533     *
1534     * @return the certificate chain (ordered with the user's certificate first
1535     * and the root certificate authority last)
1536     */
1537    @Override
1538    public X509Certificate[] getCertificateChain(String alias) {
1539        return null;
1540    }
1541
1542    /*
1543     * Returns the key associated with the given alias, using the given
1544     * password to recover it.
1545     *
1546     * @param alias the alias name
1547     *
1548     * @return the requested key
1549     */
1550    @Override
1551    public PrivateKey getPrivateKey(String alias) {
1552        return null;
1553    }
1554}
1555