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