1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.xnet.provider.jsse;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
203258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport org.apache.harmony.xnet.provider.jsse.TrustManagerImpl;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.KeyManagementException;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.KeyStore;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.KeyStoreException;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchAlgorithmException;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.SecureRandom;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.UnrecoverableKeyException;
27ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstromimport java.util.Arrays;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.KeyManager;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.KeyManagerFactory;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.TrustManager;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.TrustManagerFactory;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.X509KeyManager;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.X509TrustManager;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
36fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes * The instances of this class encapsulate all the info
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * about enabled cipher suites and protocols,
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as well as the information about client/server mode of
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ssl socket, whether it require/want client authentication or not,
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and controls whether new SSL sessions may be established by this
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket or not.
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
436812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrompublic class SSLParametersImpl implements Cloneable {
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // default source of authentication keys
46d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    private static volatile X509KeyManager defaultKeyManager;
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // default source of authentication trust decisions
48d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    private static volatile X509TrustManager defaultTrustManager;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // default source of random numbers
50d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    private static volatile SecureRandom defaultSecureRandom;
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // default SSL parameters
52d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    private static volatile SSLParametersImpl defaultParameters;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // client session context contains the set of reusable
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // client-side SSL sessions
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final ClientSessionContext clientSessionContext;
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // server session context contains the set of reusable
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // server-side SSL sessions
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final ServerSessionContext serverSessionContext;
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // source of authentication keys
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private X509KeyManager keyManager;
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // source of authentication trust decisions
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private X509TrustManager trustManager;
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // source of random numbers
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private SecureRandom secureRandom;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // cipher suites available for SSL connection
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private CipherSuite[] enabledCipherSuites;
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // string representations of available cipher suites
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String[] enabledCipherSuiteNames = null;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // protocols available for SSL connection
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String[] enabledProtocols = ProtocolVersion.supportedProtocols;
74f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // if the peer with this parameters tuned to work in client mode
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean client_mode = true;
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // if the peer with this parameters tuned to require client authentication
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean need_client_auth = false;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // if the peer with this parameters tuned to request client authentication
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean want_client_auth = false;
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // if the peer with this parameters allowed to cteate new SSL session
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean enable_session_creation = true;
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected CipherSuite[] getEnabledCipherSuitesMember() {
85aacf6f9741dea0f12fbff5e7696e53f251177280Brian Carlstrom        if (enabledCipherSuites == null) {
86aacf6f9741dea0f12fbff5e7696e53f251177280Brian Carlstrom            this.enabledCipherSuites = CipherSuite.DEFAULT_CIPHER_SUITES;
87aacf6f9741dea0f12fbff5e7696e53f251177280Brian Carlstrom        }
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return enabledCipherSuites;
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes the parameters. Naturally this constructor is used
93d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom     * in SSLContextImpl.engineInit method which directly passes its
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parameters. In other words this constructor holds all
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the functionality provided by SSLContext.init method.
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * SecureRandom)} for more information
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
996812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom    protected SSLParametersImpl(KeyManager[] kms, TrustManager[] tms,
100f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom            SecureRandom sr, ClientSessionContext clientSessionContext,
101f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom            ServerSessionContext serverSessionContext)
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws KeyManagementException {
103f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom        this.serverSessionContext = serverSessionContext;
104f365a1c9cec94071b7a3161d7bdcb3f61d28f912Brian Carlstrom        this.clientSessionContext = clientSessionContext;
105f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
106ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        // It's not described by the spec of SSLContext what should happen
107ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        // if the arrays of length 0 are specified. This implementation
108ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        // behave as for null arrays (i.e. use installed security providers)
109ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom
110ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        // initialize keyManager
111ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        if ((kms == null) || (kms.length == 0)) {
112ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            keyManager = getDefaultKeyManager();
113ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } else {
114ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            keyManager = findX509KeyManager(kms);
115ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        }
116ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom
117ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        // initialize trustManager
118ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        if ((tms == null) || (tms.length == 0)) {
119ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            trustManager = getDefaultTrustManager();
120ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } else {
121ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            trustManager = findX509TrustManager(tms);
122ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        }
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // initialize secure random
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-removed
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // if (sr == null) {
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //     if (defaultSecureRandom == null) {
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //         defaultSecureRandom = new SecureRandom();
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //     }
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //     secureRandom = defaultSecureRandom;
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // } else {
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //     secureRandom = sr;
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // }
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-removed
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-added
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // We simply use the SecureRandom passed in by the caller. If it's
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // null, we don't replace it by a new instance. The native code below
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // then directly accesses /dev/urandom. Not the most elegant solution,
138f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // but faster than going through the SecureRandom object.
139fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes        secureRandom = sr;
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-added
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1436812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom    protected static SSLParametersImpl getDefault() throws KeyManagementException {
144d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        SSLParametersImpl result = defaultParameters;
145d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        if (result == null) {
146d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            // single-check idiom
147d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            defaultParameters = result = new SSLParametersImpl(null,
148d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom                                                               null,
149d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom                                                               null,
150d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom                                                               new ClientSessionContext(),
151d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom                                                               new ServerSessionContext());
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
153d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        return (SSLParametersImpl) result.clone();
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
155f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return server session context
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected ServerSessionContext getServerSessionContext() {
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return serverSessionContext;
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return client session context
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected ClientSessionContext getClientSessionContext() {
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return clientSessionContext;
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return key manager
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected X509KeyManager getKeyManager() {
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return keyManager;
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return trust manager
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected X509TrustManager getTrustManager() {
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return trustManager;
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return secure random
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected SecureRandom getSecureRandom() {
188d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        if (secureRandom != null) {
189d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            return secureRandom;
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
191d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        SecureRandom result = defaultSecureRandom;
192d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        if (result == null) {
193d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            // single-check idiom
194d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            defaultSecureRandom = result = new SecureRandom();
195d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        }
196d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        secureRandom = result;
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return secureRandom;
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the secure random member reference, even it is null
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected SecureRandom getSecureRandomMember() {
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return secureRandom;
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the names of enabled cipher suites
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected String[] getEnabledCipherSuites() {
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (enabledCipherSuiteNames == null) {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            CipherSuite[] enabledCipherSuites = getEnabledCipherSuitesMember();
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enabledCipherSuiteNames = new String[enabledCipherSuites.length];
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i< enabledCipherSuites.length; i++) {
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                enabledCipherSuiteNames[i] = enabledCipherSuites[i].getName();
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
218f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson        return enabledCipherSuiteNames.clone();
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the set of available cipher suites for use in SSL connection.
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   suites: String[]
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setEnabledCipherSuites(String[] suites) {
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (suites == null) {
2280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throw new IllegalArgumentException("suites == null");
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        CipherSuite[] cipherSuites = new CipherSuite[suites.length];
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<suites.length; i++) {
2320c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            String suite = suites[i];
2330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            if (suite == null) {
2340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                throw new IllegalArgumentException("suites[" + i + "] == null");
2350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            }
2360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            cipherSuites[i] = CipherSuite.getByName(suite);
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (cipherSuites[i] == null || !cipherSuites[i].supported) {
2380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                throw new IllegalArgumentException(suite + " is not supported.");
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enabledCipherSuites = cipherSuites;
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enabledCipherSuiteNames = suites;
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the set of enabled protocols
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected String[] getEnabledProtocols() {
249f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson        return enabledProtocols.clone();
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the set of available protocols for use in SSL connection.
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param protocols String[]
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setEnabledProtocols(String[] protocols) {
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (protocols == null) {
2580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            throw new IllegalArgumentException("protocols == null");
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<protocols.length; i++) {
2610c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            String protocol = protocols[i];
2620c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            if (protocol == null) {
2630c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                throw new IllegalArgumentException("protocols[" + i + "] == null");
2640c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            }
2650c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom            if (!ProtocolVersion.isSupported(protocol)) {
2660c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom                throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enabledProtocols = protocols;
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tunes the peer holding this parameters to work in client mode.
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   mode if the peer is configured to work in client mode
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setUseClientMode(boolean mode) {
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        client_mode = mode;
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value indicating if the parameters configured to work
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in client mode.
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected boolean getUseClientMode() {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return client_mode;
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tunes the peer holding this parameters to require client authentication
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setNeedClientAuth(boolean need) {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        need_client_auth = need;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // reset the want_client_auth setting
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        want_client_auth = false;
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value indicating if the peer with this parameters tuned
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to require client authentication
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected boolean getNeedClientAuth() {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return need_client_auth;
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tunes the peer holding this parameters to request client authentication
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setWantClientAuth(boolean want) {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        want_client_auth = want;
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // reset the need_client_auth setting
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        need_client_auth = false;
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value indicating if the peer with this parameters
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * tuned to request client authentication
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected boolean getWantClientAuth() {
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return want_client_auth;
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Allows/disallows the peer holding this parameters to
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * create new SSL session
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setEnableSessionCreation(boolean flag) {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        enable_session_creation = flag;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value indicating if the peer with this parameters
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * allowed to cteate new SSL session
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected boolean getEnableSessionCreation() {
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return enable_session_creation;
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the clone of this object.
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the clone.
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
343f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson    @Override
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Object clone() {
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return super.clone();
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new AssertionError(e);
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
352ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom    private static X509KeyManager getDefaultKeyManager() throws KeyManagementException {
353d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        X509KeyManager result = defaultKeyManager;
354d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        if (result == null) {
355d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            // single-check idiom
356d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            defaultKeyManager = result = createDefaultKeyManager();
357d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        }
358d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        return result;
359d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    }
360ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom    private static X509KeyManager createDefaultKeyManager() throws KeyManagementException {
361ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        try {
362ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            String algorithm = KeyManagerFactory.getDefaultAlgorithm();
363ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
364ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            kmf.init(null, null);
365ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            KeyManager[] kms = kmf.getKeyManagers();
366ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            return findX509KeyManager(kms);
367ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } catch (NoSuchAlgorithmException e) {
368ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom            throw new KeyManagementException(e);
369ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } catch (KeyStoreException e) {
370ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom            throw new KeyManagementException(e);
371ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } catch (UnrecoverableKeyException e) {
372ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom            throw new KeyManagementException(e);
373ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        }
374d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    }
375ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom    private static X509KeyManager findX509KeyManager(KeyManager[] kms) throws KeyManagementException {
376d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        for (KeyManager km : kms) {
377d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            if (km instanceof X509KeyManager) {
378d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom                return (X509KeyManager)km;
379d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            }
380d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        }
381ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom        throw new KeyManagementException("Failed to find an X509KeyManager in " + Arrays.toString(kms));
382d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    }
383d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom
3848da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee    /**
3858da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee     * Gets the default trust manager.
3868da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee     *
3878da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee     * TODO: Move this to a published API under dalvik.system.
3888da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee     */
389ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom    public static X509TrustManager getDefaultTrustManager() throws KeyManagementException {
390d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        X509TrustManager result = defaultTrustManager;
391d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        if (result == null) {
392d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            // single-check idiom
393d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            defaultTrustManager = result = createDefaultTrustManager();
394d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        }
395d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        return result;
3968da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee    }
397ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom    private static X509TrustManager createDefaultTrustManager() throws KeyManagementException {
398ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        try {
399ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
400ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
401ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            tmf.init((KeyStore) null);
402ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            TrustManager[] tms = tmf.getTrustManagers();
403ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            X509TrustManager trustManager = findX509TrustManager(tms);
404ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom            return trustManager;
405ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } catch (NoSuchAlgorithmException e) {
406ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom            throw new KeyManagementException(e);
407ed72e08ad6ee16694681c8c2317f97de6d9f4323Brian Carlstrom        } catch (KeyStoreException e) {
408ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom            throw new KeyManagementException(e);
409d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        }
410d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    }
411ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom    private static X509TrustManager findX509TrustManager(TrustManager[] tms) throws KeyManagementException {
412d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        for (TrustManager tm : tms) {
413d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            if (tm instanceof X509TrustManager) {
414d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom                return (X509TrustManager)tm;
415d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom            }
416d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom        }
417ffec9b8990adcdaab295e112ca3c3ebf83488199Brian Carlstrom        throw new KeyManagementException("Failed to find an X509TrustManager in " +  Arrays.toString(tms));
418d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom    }
4198da7f0d2e2724e8e0f1b9ae1fedb92f3b0f075f6Bob Lee}
420