TestSSLContext.java revision 4e1404f2017dc7db05b69ecad241f78c5bb1a4ee
1bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom/* 2bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project 3bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 4bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * you may not use this file except in compliance with the License. 6bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * You may obtain a copy of the License at 7bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 8bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 10bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 11bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * See the License for the specific language governing permissions and 14bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * limitations under the License. 15bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 16bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.javax.net.ssl; 18bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 193258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport java.io.IOException; 20bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.net.InetAddress; 213258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport java.net.Socket; 223258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport java.net.UnknownHostException; 23bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.KeyStore; 24204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstromimport java.security.Principal; 25bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.SecureRandom; 26e688a4123f165ed2905878e312b074b8c825d119Brian Carlstromimport java.security.cert.Certificate; 27059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstromimport java.security.cert.CertificateException; 28bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstromimport java.security.cert.X509Certificate; 29204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstromimport java.util.Collections; 304557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.KeyManager; 314557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLContext; 324557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLServerSocket; 333258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport javax.net.ssl.SSLSocket; 343258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport javax.net.ssl.SSLSocketFactory; 354557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.TrustManager; 364557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.X509TrustManager; 370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport junit.framework.Assert; 383258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport libcore.java.security.StandardNames; 393258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstromimport libcore.java.security.TestKeyStore; 40bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 41bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom/** 42bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * TestSSLContext is a convenience class for other tests that 43bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * want a canned SSLContext and related state for testing so they 44bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * don't have to duplicate the logic. 45bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrompublic final class TestSSLContext extends Assert { 47bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 48f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes /* 490af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom * The RI and Android have very different default SSLSession cache behaviors. 500af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom * The RI keeps an unlimited number of SSLSesions around for 1 day. 51f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * Android keeps 10 SSLSessions forever. 520af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom */ 539a106a63508697a6f5f02c20b7cc6b7c6152695fBrian Carlstrom private static final boolean IS_RI = StandardNames.IS_RI; 540af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom public static final int EXPECTED_DEFAULT_CLIENT_SSL_SESSION_CACHE_SIZE = (IS_RI) ? 0 : 10; 550af0a7959d838c48e6b4e8dc9ac188ff6bbb6a87Brian Carlstrom public static final int EXPECTED_DEFAULT_SERVER_SSL_SESSION_CACHE_SIZE = (IS_RI) ? 0 : 100; 564e1404f2017dc7db05b69ecad241f78c5bb1a4eeAlex Klyubin public static final int EXPECTED_DEFAULT_SSL_SESSION_CACHE_TIMEOUT = 574e1404f2017dc7db05b69ecad241f78c5bb1a4eeAlex Klyubin (IS_RI) ? 24 * 3600 : 8 * 3600; 58bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 59bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 60bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * The Android SSLSocket and SSLServerSocket implementations are 61bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * based on a version of OpenSSL which includes support for RFC 62bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * 4507 session tickets. When using session tickets, the server 63bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * does not need to keep a cache mapping session IDs to SSL 64bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * sessions for reuse. Instead, the client presents the server 65bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * with a session ticket it received from the server earlier, 66bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * which is an SSL session encrypted by the server's secret 67bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * key. Since in this case the server does not need to keep a 68bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * cache, some tests may find different results depending on 69bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * whether or not the session tickets are in use. These tests can 70bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * use this function to determine if loopback SSL connections are 71bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * expected to use session tickets and conditionalize their 72bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * results appropriately. 73bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 74bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public static boolean sslServerSocketSupportsSessionTickets () { 750c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom // Disabled session tickets for better compatability b/2682876 760c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom // return !IS_RI; 770c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom return false; 78bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 79bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 80059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public final KeyStore clientKeyStore; 81e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom public final char[] clientStorePassword; 82059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public final KeyStore serverKeyStore; 83e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom public final char[] serverStorePassword; 84edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin public final KeyManager[] clientKeyManagers; 85edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin public final KeyManager[] serverKeyManagers; 8636214feb86a0963b23f34c8c63584252bd757e19Brian Carlstrom public final X509TrustManager clientTrustManager; 8736214feb86a0963b23f34c8c63584252bd757e19Brian Carlstrom public final X509TrustManager serverTrustManager; 88059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public final SSLContext clientContext; 89059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public final SSLContext serverContext; 90bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public final SSLServerSocket serverSocket; 91bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public final InetAddress host; 92bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public final int port; 93bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 94059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom private TestSSLContext(KeyStore clientKeyStore, 95e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom char[] clientStorePassword, 96059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom KeyStore serverKeyStore, 97e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom char[] serverStorePassword, 98edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin KeyManager[] clientKeyManagers, 99edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin KeyManager[] serverKeyManagers, 10036214feb86a0963b23f34c8c63584252bd757e19Brian Carlstrom X509TrustManager clientTrustManager, 10136214feb86a0963b23f34c8c63584252bd757e19Brian Carlstrom X509TrustManager serverTrustManager, 102059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLContext clientContext, 103059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLContext serverContext, 104bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom SSLServerSocket serverSocket, 105bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom InetAddress host, 106bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom int port) { 107059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this.clientKeyStore = clientKeyStore; 108e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom this.clientStorePassword = clientStorePassword; 109059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this.serverKeyStore = serverKeyStore; 110e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom this.serverStorePassword = serverStorePassword; 111edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin this.clientKeyManagers = clientKeyManagers; 112edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin this.serverKeyManagers = serverKeyManagers; 113059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this.clientTrustManager = clientTrustManager; 114059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this.serverTrustManager = serverTrustManager; 115059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this.clientContext = clientContext; 116059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom this.serverContext = serverContext; 117bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.serverSocket = serverSocket; 118bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.host = host; 119bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom this.port = port; 120bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 121bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 122f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom public void close() { 123f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom try { 124f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom serverSocket.close(); 125f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } catch (Exception e) { 126f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom throw new RuntimeException(e); 127f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 128f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom } 129f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 130e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom /** 131e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * Usual TestSSLContext creation method, creates underlying 132e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * SSLContext with certificate and key as well as SSLServerSocket 133e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom * listening provided host and port. 134e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom */ 135bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom public static TestSSLContext create() { 136059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom return create(TestKeyStore.getClient(), 137059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestKeyStore.getServer()); 138bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 139bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 140e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom /** 141059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom * TestSSLContext creation method that allows separate creation of server key store 142e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom */ 143059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public static TestSSLContext create(TestKeyStore client, TestKeyStore server) { 144c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin return createWithAdditionalKeyManagers(client, server, null, null); 145c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin } 146c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin 147c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin /** 148c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin * TestSSLContext creation method that allows separate creation of server key store and 149c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin * the use of additional {@code KeyManager} instances 150c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin */ 151c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin public static TestSSLContext createWithAdditionalKeyManagers( 152c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin TestKeyStore client, TestKeyStore server, 153c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin KeyManager[] additionalClientKeyManagers, KeyManager[] additionalServerKeyManagers) { 1543ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root String protocol = "TLSv1.2"; 155c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin KeyManager[] clientKeyManagers = concat(client.keyManagers, additionalClientKeyManagers); 156c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin KeyManager[] serverKeyManagers = concat(server.keyManagers, additionalServerKeyManagers); 1572cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin SSLContext clientContext = 158c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin createSSLContext(protocol, clientKeyManagers, client.trustManagers); 1592cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin SSLContext serverContext = 160c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin createSSLContext(protocol, serverKeyManagers, server.trustManagers); 161e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom return create(client.keyStore, client.storePassword, 1626882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom server.keyStore, server.storePassword, 163c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin clientKeyManagers, 164c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin serverKeyManagers, 1656882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom client.trustManagers[0], 1666882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom server.trustManagers[0], 1676882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom clientContext, 1686882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom serverContext); 169bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 170bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 171bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 172059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom * TestSSLContext creation method that allows separate creation of client and server key store 173e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom */ 174e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom public static TestSSLContext create(KeyStore clientKeyStore, char[] clientStorePassword, 1756882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom KeyStore serverKeyStore, char[] serverStorePassword, 176edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin KeyManager[] clientKeyManagers, 177edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin KeyManager[] serverKeyManagers, 1786882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom TrustManager clientTrustManagers, 1796882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom TrustManager serverTrustManagers, 1806882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom SSLContext clientContext, 1816882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom SSLContext serverContext) { 182e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom try { 183059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLServerSocket serverSocket = (SSLServerSocket) 184059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom serverContext.getServerSocketFactory().createServerSocket(0); 185547450702efd233213f953ba2213bb38803c34c3Jesse Wilson InetAddress host = InetAddress.getLocalHost(); 186547450702efd233213f953ba2213bb38803c34c3Jesse Wilson int port = serverSocket.getLocalPort(); 187e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom 188e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom return new TestSSLContext(clientKeyStore, clientStorePassword, 189e3a187163504f00c98bd75cbd8bcbdde123ae2cdBrian Carlstrom serverKeyStore, serverStorePassword, 190edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin clientKeyManagers, 191edeec21a9c9e97cad91dffd47d4f2f7185dffe07Alex Klyubin serverKeyManagers, 19236214feb86a0963b23f34c8c63584252bd757e19Brian Carlstrom (X509TrustManager) clientTrustManagers, 19336214feb86a0963b23f34c8c63584252bd757e19Brian Carlstrom (X509TrustManager) serverTrustManagers, 194059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom clientContext, serverContext, 195059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom serverSocket, host, port); 196e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } catch (RuntimeException e) { 197e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom throw e; 198e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } catch (Exception e) { 199e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom throw new RuntimeException(e); 200e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 201e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 202e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom 203e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom /** 204bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Create a SSLContext with a KeyManager using the private key and 205bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * certificate chain from the given KeyStore and a TrustManager 206bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * using the certificates authorities from the same KeyStore. 207bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 2086882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom public static final SSLContext createSSLContext(final String protocol, 2096882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom final KeyManager[] keyManagers, 210059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom final TrustManager[] trustManagers) 2116882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom { 2126882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom try { 2132cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin SSLContext context = SSLContext.getInstance(protocol); 2146882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom context.init(keyManagers, trustManagers, new SecureRandom()); 2156882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom return context; 2166882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom } catch (Exception e) { 2176882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom throw new RuntimeException(e); 2186882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom } 219bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 220204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom 221204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom public static void assertCertificateInKeyStore(Principal principal, 222204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom KeyStore keyStore) throws Exception { 223204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom String subjectName = principal.getName(); 224204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom boolean found = false; 225204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom for (String alias: Collections.list(keyStore.aliases())) { 226204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom if (!keyStore.isCertificateEntry(alias)) { 227204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom continue; 228204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 229204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom X509Certificate keyStoreCertificate = (X509Certificate) keyStore.getCertificate(alias); 230204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom if (subjectName.equals(keyStoreCertificate.getSubjectDN().getName())) { 231204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom found = true; 232204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom break; 233204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 234204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 2350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(found); 236204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 237204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom 238204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom public static void assertCertificateInKeyStore(Certificate certificate, 239204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom KeyStore keyStore) throws Exception { 240204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom boolean found = false; 241204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom for (String alias: Collections.list(keyStore.aliases())) { 242204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom if (!keyStore.isCertificateEntry(alias)) { 243204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom continue; 244204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 245204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom Certificate keyStoreCertificate = keyStore.getCertificate(alias); 246204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom if (certificate.equals(keyStoreCertificate)) { 247204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom found = true; 248204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom break; 249204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 250204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 2510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(found); 252204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 253059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 254059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public static void assertServerCertificateChain(X509TrustManager trustManager, 255059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom Certificate[] serverChain) 256059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom throws CertificateException { 257059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom X509Certificate[] chain = (X509Certificate[]) serverChain; 258059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom trustManager.checkServerTrusted(chain, chain[0].getPublicKey().getAlgorithm()); 259059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 260059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom 261059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom public static void assertClientCertificateChain(X509TrustManager trustManager, 262059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom Certificate[] clientChain) 263059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom throws CertificateException { 264059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom X509Certificate[] chain = (X509Certificate[]) clientChain; 265059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom trustManager.checkClientTrusted(chain, chain[0].getPublicKey().getAlgorithm()); 266059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom } 2673258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom 2683258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom /** 2693258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom * Returns an SSLSocketFactory that calls setWantClientAuth and 2703258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom * setNeedClientAuth as specified on all returned sockets. 2713258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom */ 2723258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public static SSLSocketFactory clientAuth(final SSLSocketFactory sf, 2733258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom final boolean want, 2743258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom final boolean need) { 2753258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return new SSLSocketFactory() { 2763258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom private SSLSocket set(Socket socket) { 2773258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom SSLSocket s = (SSLSocket) socket; 2783258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom s.setWantClientAuth(want); 2793258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom s.setNeedClientAuth(need); 2803258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return s; 2813258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 2823258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public Socket createSocket(String host, int port) 2833258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom throws IOException, UnknownHostException { 2843258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return set(sf.createSocket(host, port)); 2853258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 2863258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public Socket createSocket(String host, int port, InetAddress localHost, int localPort) 2873258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom throws IOException, UnknownHostException { 2883258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return set(sf.createSocket(host, port, localHost, localPort)); 2893258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 2903258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public Socket createSocket(InetAddress host, int port) throws IOException { 2913258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return set(sf.createSocket(host, port)); 2923258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 2933258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public Socket createSocket(InetAddress address, int port, 2943258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom InetAddress localAddress, int localPort) throws IOException { 2953258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return set(sf.createSocket(address, port)); 2963258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 2973258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom 2983258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public String[] getDefaultCipherSuites() { 2993258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return sf.getDefaultCipherSuites(); 3003258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 3013258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public String[] getSupportedCipherSuites() { 3023258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return sf.getSupportedCipherSuites(); 3033258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 3043258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom 3053258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom public Socket createSocket(Socket s, String host, int port, boolean autoClose) 3063258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom throws IOException { 3073258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom return set(sf.createSocket(s, host, port, autoClose)); 3083258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 3093258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom }; 3103258b52429c7768ea91bda93c5a15257cdd390e5Brian Carlstrom } 311c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin 312c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin private static KeyManager[] concat(KeyManager[] a, KeyManager[] b) { 313c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin if ((a == null) || (a.length == 0)) { 314c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin return b; 315c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin } 316c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin if ((b == null) || (b.length == 0)) { 317c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin return a; 318c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin } 319c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin KeyManager[] result = new KeyManager[a.length + b.length]; 320c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin System.arraycopy(a, 0, result, 0, a.length); 321c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin System.arraycopy(b, 0, result, a.length, b.length); 322c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin return result; 323c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin } 324bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom} 325