1ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom/* 2ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * Copyright (C) 2010 The Android Open Source Project 3ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * 4ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * you may not use this file except in compliance with the License. 6ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * You may obtain a copy of the License at 7ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * 8ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * 10ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 11ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * See the License for the specific language governing permissions and 14ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom * limitations under the License. 15ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom */ 16ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.javax.net.ssl; 18ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 192216155c3066236eb450f307983019f69a10303dKenny Rootimport static java.nio.charset.StandardCharsets.UTF_8; 202216155c3066236eb450f307983019f69a10303dKenny Root 21fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.io.ByteArrayInputStream; 2227088efe0caca697e257e08d41387af8130364e0Kenny Rootimport java.io.Closeable; 23fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.io.DataInputStream; 240007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubinimport java.io.EOFException; 25783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.io.IOException; 265f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport java.io.InputStream; 275f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport java.io.OutputStream; 28283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstromimport java.lang.Thread.UncaughtExceptionHandler; 29615225a35dbd838210270b282d1196deff643b51Brian Carlstromimport java.lang.reflect.Method; 30a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.math.BigInteger; 319f7c676c1937bdafce079cf02a67ac121296a335Kenny Rootimport java.net.InetAddress; 3251cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstromimport java.net.InetSocketAddress; 33a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstromimport java.net.ServerSocket; 34ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.net.Socket; 355f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport java.net.SocketException; 36ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.net.SocketTimeoutException; 37a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.AlgorithmParameters; 38a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.InvalidAlgorithmParameterException; 39a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.InvalidKeyException; 40a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.InvalidParameterException; 41a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.Key; 42b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport java.security.KeyManagementException; 43b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport java.security.NoSuchAlgorithmException; 44ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.security.Principal; 45aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport java.security.PrivateKey; 46a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.Provider; 47a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.PublicKey; 48a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.SecureRandom; 49a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.Security; 50a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.Signature; 51a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.SignatureException; 52a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.SignatureSpi; 53ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.security.cert.Certificate; 542915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstromimport java.security.cert.CertificateException; 55aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport java.security.cert.X509Certificate; 5672ac463cd5718d2e5aa439e569c26cc0576f4962Kenny Rootimport java.security.interfaces.ECKey; 57a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.interfaces.ECPrivateKey; 5872ac463cd5718d2e5aa439e569c26cc0576f4962Kenny Rootimport java.security.interfaces.RSAKey; 59a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.interfaces.RSAPrivateKey; 60a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.spec.AlgorithmParameterSpec; 61a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport java.security.spec.ECParameterSpec; 62b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport java.util.ArrayList; 63ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport java.util.Arrays; 64b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Rootimport java.util.Collections; 65b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport java.util.List; 66783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.Callable; 67783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.ExecutorService; 68783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.Executors; 69783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstromimport java.util.concurrent.Future; 706ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Rootimport java.util.concurrent.ThreadFactory; 710007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubinimport java.util.concurrent.TimeUnit; 72a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport javax.crypto.BadPaddingException; 73a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport javax.crypto.Cipher; 74a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport javax.crypto.CipherSpi; 75a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport javax.crypto.IllegalBlockSizeException; 76a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport javax.crypto.NoSuchPaddingException; 77c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubinimport javax.crypto.SecretKey; 78a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Rootimport javax.crypto.ShortBufferException; 79c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubinimport javax.crypto.spec.SecretKeySpec; 800007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubinimport javax.net.ServerSocketFactory; 8158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Rootimport javax.net.SocketFactory; 82b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Rootimport javax.net.ssl.ExtendedSSLSession; 834557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.HandshakeCompletedEvent; 844557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.HandshakeCompletedListener; 85aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport javax.net.ssl.KeyManager; 86b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Rootimport javax.net.ssl.SNIHostName; 87b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Rootimport javax.net.ssl.SNIMatcher; 88b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Rootimport javax.net.ssl.SNIServerName; 894557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLContext; 904557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLException; 912915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstromimport javax.net.ssl.SSLHandshakeException; 924557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLParameters; 934557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLPeerUnverifiedException; 944557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLProtocolException; 959f7c676c1937bdafce079cf02a67ac121296a335Kenny Rootimport javax.net.ssl.SSLServerSocket; 964557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSession; 974557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSocket; 984557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport javax.net.ssl.SSLSocketFactory; 9901b7734160977458d44d1fb179984fd91672f08dKenny Rootimport javax.net.ssl.StandardConstants; 100aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport javax.net.ssl.TrustManager; 101aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstromimport javax.net.ssl.X509KeyManager; 1028c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstromimport javax.net.ssl.X509TrustManager; 103ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstromimport junit.framework.TestCase; 1045f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport libcore.java.security.StandardNames; 1055f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstromimport libcore.java.security.TestKeyStore; 106b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport libcore.tlswire.handshake.CipherSuite; 107b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport libcore.tlswire.handshake.ClientHello; 108b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport libcore.tlswire.handshake.CompressionMethod; 109c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Rootimport libcore.tlswire.handshake.EllipticCurve; 110c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Rootimport libcore.tlswire.handshake.EllipticCurvesHelloExtension; 111fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport libcore.tlswire.handshake.HandshakeMessage; 112b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport libcore.tlswire.handshake.HelloExtension; 113b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport libcore.tlswire.handshake.ServerNameHelloExtension; 114fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport libcore.tlswire.record.TlsProtocols; 115fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport libcore.tlswire.record.TlsRecord; 116b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport libcore.tlswire.util.TlsProtocolVersion; 11726f2557b26ea23326178f029e07a8adbfc27d0bfNeil Fullerimport tests.net.DelegatingSSLSocketFactory; 118b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport tests.util.ForEachRunner; 119b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubinimport tests.util.Pair; 120ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 121ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrompublic class SSLSocketTest extends TestCase { 122ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 123f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin public void test_SSLSocket_defaultConfiguration() throws Exception { 124782740701db73dd2dc4fef9df8cde270b0e631a4Alex Klyubin SSLConfigurationAsserts.assertSSLSocketDefaultConfiguration( 125f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin (SSLSocket) SSLSocketFactory.getDefault().createSocket()); 126f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin } 127f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin 128f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin public void test_SSLSocket_getSupportedCipherSuites_returnsCopies() throws Exception { 1298ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 1308ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 131f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin assertNotSame(ssl.getSupportedCipherSuites(), ssl.getSupportedCipherSuites()); 132ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 133ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 134204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception { 135a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom // note the rare usage of non-RSA keys 136101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson TestKeyStore testKeyStore = new TestKeyStore.Builder() 137101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson .keyAlgorithms("RSA", "DSA", "EC", "EC_RSA") 138101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson .aliasPrefix("rsa-dsa-ec") 139101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson .ca(true) 140101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson .build(); 1411f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root StringBuilder error = new StringBuilder(); 1422cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore, error); 1431f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root if (error.length() > 0) { 1441f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root throw new Exception("One or more problems in " 1451f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root + "test_SSLSocket_getSupportedCipherSuites_connect:\n" + error); 1466882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom } 1476882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom } 1486882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore, 1491f1dc0af2c01f2a2b6cf4907ecb21b4e05982e2bKenny Root StringBuilder error) 1506882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom throws Exception { 1516882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom 1526882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom String clientToServerString = "this is sent from the client to the server..."; 1536882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom String serverToClientString = "... and this from the server to the client"; 1542216155c3066236eb450f307983019f69a10303dKenny Root byte[] clientToServer = clientToServerString.getBytes(UTF_8); 1552216155c3066236eb450f307983019f69a10303dKenny Root byte[] serverToClient = serverToClientString.getBytes(UTF_8); 1566882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom 157c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager( 158c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin new PSKKeyManagerProxy() { 159c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin @Override 160c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin protected SecretKey getKey(String identityHint, String identity, Socket socket) { 1612216155c3066236eb450f307983019f69a10303dKenny Root return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW"); 162c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin } 163c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin }); 164c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers( 165c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin testKeyStore, testKeyStore, 166c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin new KeyManager[] {pskKeyManager}, new KeyManager[] {pskKeyManager}); 167c9461f39290f815f560f2ec50e9ccde5ff4eb8f7Alex Klyubin 1682cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin String[] cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites(); 1694ae3fd787741bfe1b808f447dcb0785250024119Brian Carlstrom 170204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom for (String cipherSuite : cipherSuites) { 171aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom boolean errorExpected = StandardNames.IS_RI && cipherSuite.endsWith("_SHA256"); 172a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom try { 173a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom /* 1746c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom * TLS_EMPTY_RENEGOTIATION_INFO_SCSV cannot be used on 1756c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom * its own, but instead in conjunction with other 1766c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom * cipher suites. 1776c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom */ 1786c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom if (cipherSuite.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)) { 1796c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom continue; 1806c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom } 1816c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom /* 182e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root * Similarly with the TLS_FALLBACK_SCSV suite, it is not 183e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root * a selectable suite, but is used in conjunction with 184e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root * other cipher suites. 185e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root */ 186e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root if (cipherSuite.equals(StandardNames.CIPHER_SUITE_FALLBACK)) { 187e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root continue; 188e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 189e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root /* 190a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom * Kerberos cipher suites require external setup. See "Kerberos Requirements" in 1916c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html 1926c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom * #KRBRequire 193a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom */ 194a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom if (cipherSuite.startsWith("TLS_KRB5_")) { 195a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom continue; 196a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom } 1976c78b7b94c232063ec559436b48b33751373ecf1Brian Carlstrom 1982cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin String[] clientCipherSuiteArray = new String[] { 1992cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin cipherSuite, 2002cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION }; 2012cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin String[] serverCipherSuiteArray = clientCipherSuiteArray; 202ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom SSLSocket[] pair = TestSSLSocketPair.connect(c, 203ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom clientCipherSuiteArray, 204ffeba5dd766602f6e2be9caa9081744348a53c04Brian Carlstrom serverCipherSuiteArray); 205a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom 206a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom SSLSocket server = pair[0]; 207a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom SSLSocket client = pair[1]; 208038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin 209038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin // Check that the client can read the message sent by the server 210a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom server.getOutputStream().write(serverToClient); 211038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin byte[] clientFromServer = new byte[serverToClient.length]; 21227088efe0caca697e257e08d41387af8130364e0Kenny Root readFully(client.getInputStream(), clientFromServer); 213038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin assertEquals(serverToClientString, new String(clientFromServer)); 214038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin 215038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin // Check that the server can read the message sent by the client 216a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom client.getOutputStream().write(clientToServer); 217038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin byte[] serverFromClient = new byte[clientToServer.length]; 21827088efe0caca697e257e08d41387af8130364e0Kenny Root readFully(server.getInputStream(), serverFromClient); 219038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin assertEquals(clientToServerString, new String(serverFromClient)); 220038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin 221038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin // Check that the server and the client cannot read anything else 222038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin // (reads should time out) 223038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin server.setSoTimeout(10); 224038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin try { 225038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin server.getInputStream().read(); 226038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin fail(); 227038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin } catch (IOException expected) {} 228038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin client.setSoTimeout(10); 229038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin try { 230038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin client.getInputStream().read(); 231038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin fail(); 232038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin } catch (IOException expected) {} 233038cb91ddb127750737055649f6171dc1af3985aAlex Klyubin 234a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom client.close(); 235b4bb9aba620d8a363fb3617b25839093caf39cf4Brian Carlstrom server.close(); 236aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertFalse(errorExpected); 237aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (Exception maybeExpected) { 238aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom if (!errorExpected) { 2392cca77af136c57106bd9a1652e54a0ee99154d89Alex Klyubin String message = ("Problem trying to connect cipher suite " + cipherSuite); 24039d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom System.out.println(message); 24139d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom maybeExpected.printStackTrace(); 24239d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom error.append(message); 24339d69d058be0c1a4555aeed4a237c2af05ae39c6Brian Carlstrom error.append('\n'); 244aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 245204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 246204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 247f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 248204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom } 249204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom 250f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Exception { 2518ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 2528ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 253f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites()); 254ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 255ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 256ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception { 257ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 258ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin SSLSocket ssl = (SSLSocket) sf.createSocket(); 259ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin String[] array = new String[] {ssl.getEnabledCipherSuites()[0]}; 260ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin String originalFirstElement = array[0]; 261ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin ssl.setEnabledCipherSuites(array); 262ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin array[0] = "Modified after having been set"; 263ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin assertEquals(originalFirstElement, ssl.getEnabledCipherSuites()[0]); 264ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin } 265ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin 266ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom public void test_SSLSocket_setEnabledCipherSuites() throws Exception { 2678ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 2688ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 269ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 270ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 271ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledCipherSuites(null); 272ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 273e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (IllegalArgumentException expected) { 274ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 275ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 276ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledCipherSuites(new String[1]); 277ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 278e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (IllegalArgumentException expected) { 279ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 280ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 281ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledCipherSuites(new String[] { "Bogus" } ); 282ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 283e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (IllegalArgumentException expected) { 284ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 285ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 286ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledCipherSuites(new String[0]); 287ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites()); 288ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites()); 289358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin 290358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin // Check that setEnabledCipherSuites affects getEnabledCipherSuites 291358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin String[] cipherSuites = new String[] { ssl.getSupportedCipherSuites()[0] }; 292358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin ssl.setEnabledCipherSuites(cipherSuites); 293358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites())); 294ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 295ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 296f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exception { 2978ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 2988ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 299f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin assertNotSame(ssl.getSupportedProtocols(), ssl.getSupportedProtocols()); 300ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 301ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 302f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception { 3038ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 3048ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 305f605c6822da13b32cd3643415a707882b62a3e91Alex Klyubin assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols()); 306ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 307ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 308ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception { 309ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 310ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin SSLSocket ssl = (SSLSocket) sf.createSocket(); 311ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin String[] array = new String[] {ssl.getEnabledProtocols()[0]}; 312ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin String originalFirstElement = array[0]; 313ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin ssl.setEnabledProtocols(array); 314ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin array[0] = "Modified after having been set"; 315ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin assertEquals(originalFirstElement, ssl.getEnabledProtocols()[0]); 316ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin } 317ee109f62e99f43bcf8b78c857af430be9cf02985Alex Klyubin 318ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom public void test_SSLSocket_setEnabledProtocols() throws Exception { 3198ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 3208ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 321ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 322ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 323ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledProtocols(null); 324ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 325e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (IllegalArgumentException expected) { 326ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 327ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 328ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledProtocols(new String[1]); 329ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 330e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (IllegalArgumentException expected) { 331ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 332ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 333ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledProtocols(new String[] { "Bogus" } ); 334ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 335e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (IllegalArgumentException expected) { 336ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 337ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledProtocols(new String[0]); 338ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledProtocols(ssl.getEnabledProtocols()); 339ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom ssl.setEnabledProtocols(ssl.getSupportedProtocols()); 340358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin 341358552b505a8985ec9ed3691d0a6d590b60d620fAlex Klyubin // Check that setEnabledProtocols affects getEnabledProtocols 3423ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root for (String protocol : ssl.getSupportedProtocols()) { 3433ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root if ("SSLv2Hello".equals(protocol)) { 3443ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root try { 3453ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root ssl.setEnabledProtocols(new String[] { protocol }); 3463ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root fail("Should fail when SSLv2Hello is set by itself"); 3473ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root } catch (IllegalArgumentException expected) {} 3483ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root } else { 3493ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root String[] protocols = new String[] { protocol }; 3503ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root ssl.setEnabledProtocols(protocols); 3513ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root assertEquals(Arrays.deepToString(protocols), 3523ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root Arrays.deepToString(ssl.getEnabledProtocols())); 3533ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root } 3543ad1704dc8e4653f4ceaeb5d8315ddb28318a1bbKenny Root } 355ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 356ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 357ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom public void test_SSLSocket_getSession() throws Exception { 3588ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 3598ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 3608ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom SSLSession session = ssl.getSession(); 361ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(session); 362ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertFalse(session.isValid()); 363ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 364ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 36501b7734160977458d44d1fb179984fd91672f08dKenny Root public void test_SSLSocket_getHandshakeSession() throws Exception { 36601b7734160977458d44d1fb179984fd91672f08dKenny Root SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 36701b7734160977458d44d1fb179984fd91672f08dKenny Root SSLSocket ssl = (SSLSocket) sf.createSocket(); 36801b7734160977458d44d1fb179984fd91672f08dKenny Root SSLSession session = ssl.getHandshakeSession(); 36901b7734160977458d44d1fb179984fd91672f08dKenny Root assertNull(session); 37001b7734160977458d44d1fb179984fd91672f08dKenny Root } 37101b7734160977458d44d1fb179984fd91672f08dKenny Root 372ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom public void test_SSLSocket_startHandshake() throws Exception { 373bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom final TestSSLContext c = TestSSLContext.create(); 374059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 375059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 376ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 377783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 378783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 379783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 380783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 381783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertNotNull(server.getSession()); 38201b7734160977458d44d1fb179984fd91672f08dKenny Root assertNull(server.getHandshakeSession()); 383ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 384783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.getSession().getPeerCertificates(); 385783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom fail(); 386783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } catch (SSLPeerUnverifiedException expected) { 387ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 388783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Certificate[] localCertificates = server.getSession().getLocalCertificates(); 389783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertNotNull(localCertificates); 390783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom TestKeyStore.assertChainLength(localCertificates); 391783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertNotNull(localCertificates[0]); 392783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom TestSSLContext.assertServerCertificateChain(c.serverTrustManager, 393783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom localCertificates); 394783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom TestSSLContext.assertCertificateInKeyStore(localCertificates[0], 395783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom c.serverKeyStore); 396783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 397ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 398ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 399783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 400ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.startHandshake(); 401ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(client.getSession()); 402ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNull(client.getSession().getLocalCertificates()); 403ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom Certificate[] peerCertificates = client.getSession().getPeerCertificates(); 404ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerCertificates); 405059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestKeyStore.assertChainLength(peerCertificates); 406ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerCertificates[0]); 407059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext.assertServerCertificateChain(c.clientTrustManager, 408059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom peerCertificates); 409059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore); 410783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 411f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 412f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 413f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 414ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 415ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 416b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom private static final class SSLServerSessionIdCallable implements Callable<byte[]> { 417b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom private final SSLSocket server; 418b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom private SSLServerSessionIdCallable(SSLSocket server) { 419b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom this.server = server; 420b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom } 421b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom @Override public byte[] call() throws Exception { 422b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom server.startHandshake(); 423b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertNotNull(server.getSession()); 424b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertNotNull(server.getSession().getId()); 425b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom return server.getSession().getId(); 426b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom } 427b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom } 428b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom 429b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom public void test_SSLSocket_confirmSessionReuse() throws Exception { 430b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final TestSSLContext c = TestSSLContext.create(); 431b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final ExecutorService executor = Executors.newSingleThreadExecutor(); 432b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom 4336309be4c19bb991aab3778575ce7bc6750c674eeKenny Root final SSLSocket client1 = (SSLSocket) c.clientContext.getSocketFactory() 4346309be4c19bb991aab3778575ce7bc6750c674eeKenny Root .createSocket(c.host.getHostName(), c.port); 435b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final SSLSocket server1 = (SSLSocket) c.serverSocket.accept(); 436b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final Future<byte[]> future1 = executor.submit(new SSLServerSessionIdCallable(server1)); 437b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom client1.startHandshake(); 438b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertNotNull(client1.getSession()); 439b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertNotNull(client1.getSession().getId()); 440b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final byte[] clientSessionId1 = client1.getSession().getId(); 441b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final byte[] serverSessionId1 = future1.get(); 442b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertTrue(Arrays.equals(clientSessionId1, serverSessionId1)); 443b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom client1.close(); 444b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom server1.close(); 445b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom 4466309be4c19bb991aab3778575ce7bc6750c674eeKenny Root final SSLSocket client2 = (SSLSocket) c.clientContext.getSocketFactory() 4476309be4c19bb991aab3778575ce7bc6750c674eeKenny Root .createSocket(c.host.getHostName(), c.port); 448b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final SSLSocket server2 = (SSLSocket) c.serverSocket.accept(); 449b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final Future<byte[]> future2 = executor.submit(new SSLServerSessionIdCallable(server2)); 450b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom client2.startHandshake(); 451b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertNotNull(client2.getSession()); 452b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertNotNull(client2.getSession().getId()); 453b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final byte[] clientSessionId2 = client2.getSession().getId(); 454b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom final byte[] serverSessionId2 = future2.get(); 455b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertTrue(Arrays.equals(clientSessionId2, serverSessionId2)); 456b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom client2.close(); 457b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom server2.close(); 458b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom 459b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom assertTrue(Arrays.equals(clientSessionId1, clientSessionId2)); 460b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom 461b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom executor.shutdown(); 462b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom c.close(); 463b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom } 464b88ab0efb05475fa9d4e2a06175e95e88f507cffBrian Carlstrom 465def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root public void test_SSLSocket_NoEnabledCipherSuites_Failure() throws Exception { 466def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null, 467def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root SSLContext.getDefault(), SSLContext.getDefault()); 468def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 469def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root c.port); 470def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root client.setEnabledCipherSuites(new String[0]); 471def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 472def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root ExecutorService executor = Executors.newSingleThreadExecutor(); 473def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root Future<Void> future = executor.submit(new Callable<Void>() { 474def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root @Override 475def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root public Void call() throws Exception { 476def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root try { 477def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root server.startHandshake(); 478def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root fail(); 479def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root } catch (SSLHandshakeException expected) { 480def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root } 481def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root return null; 482def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root } 483def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root }); 484def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root executor.shutdown(); 485def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root try { 486def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root client.startHandshake(); 487def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root fail(); 488def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root } catch (SSLHandshakeException expected) { 489def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root } 490def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root future.get(); 491def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root server.close(); 492def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root client.close(); 493def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root c.close(); 494def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root } 495def50a267d0100fa560cf7bbcd0b9a9d5f5e068fKenny Root 49617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_startHandshake_noKeyStore() throws Exception { 4976882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null, 4986882e31b7ce2d04ebbc91c7a55d7840e8fdce8a5Brian Carlstrom SSLContext.getDefault(), SSLContext.getDefault()); 499059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 500059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 501bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 502bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin ExecutorService executor = Executors.newSingleThreadExecutor(); 503bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin Future<Void> future = executor.submit(new Callable<Void>() { 504bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin @Override public Void call() throws Exception { 505bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin try { 506bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin server.startHandshake(); 507bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin fail(); 508bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin } catch (SSLHandshakeException expected) { 509aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 510bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin return null; 511aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 512bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin }); 513bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin executor.shutdown(); 514bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin try { 515bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin client.startHandshake(); 516bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin fail(); 517bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin } catch (SSLHandshakeException expected) { 51817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom } 519bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin future.get(); 520bccd4e67d528d52d368e4bbd319621ba2cc15e5fAlex Klyubin server.close(); 521f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 522f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 523ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 524ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 525e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception { 526059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext c = TestSSLContext.create(); 527059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLContext serverContext = c.serverContext; 528059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLContext clientContext = c.clientContext; 529e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom SSLSocket client = (SSLSocket) 530059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom clientContext.getSocketFactory().createSocket(c.host, c.port); 531059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 532783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 533783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 534783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 535783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 536783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 537e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 538e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom }); 539783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 540e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom client.startHandshake(); 541783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 542f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 543f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 544f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 545e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 546e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom 54717c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_HandshakeCompletedListener() throws Exception { 548bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom final TestSSLContext c = TestSSLContext.create(); 549059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom final SSLSocket client = (SSLSocket) 550059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.clientContext.getSocketFactory().createSocket(c.host, c.port); 55117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 552783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 553783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 554783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 555783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 556783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 557ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 558ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 559783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 560ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom final boolean[] handshakeCompletedListenerCalled = new boolean[1]; 561ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.addHandshakeCompletedListener(new HandshakeCompletedListener() { 5622216155c3066236eb450f307983019f69a10303dKenny Root @Override 5638ee2e66dc0ef38f4fbdf0fd649abc6e47876c9afBrian Carlstrom public void handshakeCompleted(HandshakeCompletedEvent event) { 564ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 565ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom SSLSession session = event.getSession(); 566ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom String cipherSuite = event.getCipherSuite(); 567ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom Certificate[] localCertificates = event.getLocalCertificates(); 568ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom Certificate[] peerCertificates = event.getPeerCertificates(); 569e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom javax.security.cert.X509Certificate[] peerCertificateChain 570e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom = event.getPeerCertificateChain(); 571ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom Principal peerPrincipal = event.getPeerPrincipal(); 572ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom Principal localPrincipal = event.getLocalPrincipal(); 573ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom Socket socket = event.getSocket(); 574ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 575ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom if (false) { 576ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom System.out.println("Session=" + session); 577ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom System.out.println("CipherSuite=" + cipherSuite); 578101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson System.out.println("LocalCertificates=" 579101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson + Arrays.toString(localCertificates)); 580101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson System.out.println("PeerCertificates=" 581101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson + Arrays.toString(peerCertificates)); 582101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson System.out.println("PeerCertificateChain=" 583101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson + Arrays.toString(peerCertificateChain)); 584ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom System.out.println("PeerPrincipal=" + peerPrincipal); 585ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom System.out.println("LocalPrincipal=" + localPrincipal); 586ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom System.out.println("Socket=" + socket); 587ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 588ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 589ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(session); 590ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom byte[] id = session.getId(); 591ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(id); 592ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertEquals(32, id.length); 593059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom assertNotNull(c.clientContext.getClientSessionContext().getSession(id)); 594ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 595ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(cipherSuite); 596e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom assertTrue(Arrays.asList( 597e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom client.getEnabledCipherSuites()).contains(cipherSuite)); 598e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom assertTrue(Arrays.asList( 599e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite)); 600ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 601ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNull(localCertificates); 602ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 603ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerCertificates); 604059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestKeyStore.assertChainLength(peerCertificates); 605ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerCertificates[0]); 606059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext.assertServerCertificateChain(c.clientTrustManager, 607059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom peerCertificates); 608059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], 609059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.serverKeyStore); 610ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 611ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerCertificateChain); 612059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestKeyStore.assertChainLength(peerCertificateChain); 613ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerCertificateChain[0]); 614204cab3c22b4d75c866c95e2d2eec42e14cbd924Brian Carlstrom TestSSLContext.assertCertificateInKeyStore( 615059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom peerCertificateChain[0].getSubjectDN(), c.serverKeyStore); 616ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 617ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(peerPrincipal); 618059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore); 619ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 620ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNull(localPrincipal); 621ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 622ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(socket); 623ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertSame(client, socket); 624ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 62570bf6bc3ad78ed9a0a7a5767381ad6c25debbd70Kenny Root assertTrue(socket instanceof SSLSocket); 62601b7734160977458d44d1fb179984fd91672f08dKenny Root assertNull(((SSLSocket) socket).getHandshakeSession()); 62770bf6bc3ad78ed9a0a7a5767381ad6c25debbd70Kenny Root 628cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom synchronized (handshakeCompletedListenerCalled) { 629cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom handshakeCompletedListenerCalled[0] = true; 630cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom handshakeCompletedListenerCalled.notify(); 631cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom } 632ecaf759ba374a3e53613c97b47920bf520bb93cfBrian Carlstrom handshakeCompletedListenerCalled[0] = true; 633ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } catch (RuntimeException e) { 634ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom throw e; 635ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } catch (Exception e) { 636ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom throw new RuntimeException(e); 637ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 638ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 639ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 640ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.startHandshake(); 641783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 6420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) { 643059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom assertNotNull(c.serverContext.getServerSessionContext().getSession( 6440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom client.getSession().getId())); 6450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom } 646cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom synchronized (handshakeCompletedListenerCalled) { 647cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom while (!handshakeCompletedListenerCalled[0]) { 648cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom handshakeCompletedListenerCalled.wait(); 649cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom } 650cac49819d66d7928fe524ccd3eb93590120d9d30Brian Carlstrom } 651f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 652f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 653f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 654ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 655ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 656283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom private static final class TestUncaughtExceptionHandler implements UncaughtExceptionHandler { 657283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom Throwable actualException; 658283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom @Override public void uncaughtException(Thread thread, Throwable ex) { 659283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom assertNull(actualException); 660283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom actualException = ex; 661283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom } 662283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom } 663283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom 664e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception { 665283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom final Thread self = Thread.currentThread(); 666283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom final UncaughtExceptionHandler original = self.getUncaughtExceptionHandler(); 667283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom 668283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom final RuntimeException expectedException = new RuntimeException("expected"); 669283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom final TestUncaughtExceptionHandler test = new TestUncaughtExceptionHandler(); 670283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom self.setUncaughtExceptionHandler(test); 671283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom 672e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom final TestSSLContext c = TestSSLContext.create(); 673059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom final SSLSocket client = (SSLSocket) 674059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.clientContext.getSocketFactory().createSocket(c.host, c.port); 675e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 676783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 677783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 678783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 679783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 680783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 681e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 682e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom }); 683783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 684e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom client.addHandshakeCompletedListener(new HandshakeCompletedListener() { 6852216155c3066236eb450f307983019f69a10303dKenny Root @Override 686e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom public void handshakeCompleted(HandshakeCompletedEvent event) { 687283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom throw expectedException; 688e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 689e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom }); 690e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom client.startHandshake(); 691783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 692f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 693f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 694f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 695283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom 696283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom assertSame(expectedException, test.actualException); 697283a5d1ff99659815a3fae78b9eab2ce856a908aBrian Carlstrom self.setUncaughtExceptionHandler(original); 698e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom } 699e688a4123f165ed2905878e312b074b8c825d119Brian Carlstrom 70017c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_getUseClientMode() throws Exception { 70117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 702059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 703059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 70417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom SSLSocket server = (SSLSocket) c.serverSocket.accept(); 705ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertTrue(client.getUseClientMode()); 70617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom assertFalse(server.getUseClientMode()); 707f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 708f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 709f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 710ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 711ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 71217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_setUseClientMode() throws Exception { 713ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom // client is client, server is server 71417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom test_SSLSocket_setUseClientMode(true, false); 715ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom // client is server, server is client 71617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom test_SSLSocket_setUseClientMode(true, false); 717ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom // both are client 718ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 71917c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom test_SSLSocket_setUseClientMode(true, true); 720ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 721e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (SSLProtocolException expected) { 722aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertTrue(StandardNames.IS_RI); 723aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (SSLHandshakeException expected) { 724aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertFalse(StandardNames.IS_RI); 725ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 726ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 727ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom // both are server 728ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 72917c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom test_SSLSocket_setUseClientMode(false, false); 730ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 731e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (SocketTimeoutException expected) { 732ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 733ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 734ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 73517c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom private void test_SSLSocket_setUseClientMode(final boolean clientClientMode, 73617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom final boolean serverClientMode) 737ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom throws Exception { 73817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 739059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 740059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 74117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 74217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom 743783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 744783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<IOException> future = executor.submit(new Callable<IOException>() { 745783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public IOException call() throws Exception { 746ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 747ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom if (!serverClientMode) { 748ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom server.setSoTimeout(1 * 1000); 749ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 750ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom server.setUseClientMode(serverClientMode); 751ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom server.startHandshake(); 752783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 753aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (SSLHandshakeException e) { 754783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return e; 755ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } catch (SocketTimeoutException e) { 756783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return e; 757ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 758ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 759ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 760783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 761ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom if (!clientClientMode) { 762ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.setSoTimeout(1 * 1000); 763ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 764ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.setUseClientMode(clientClientMode); 765ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.startHandshake(); 766783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom IOException ioe = future.get(); 767783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom if (ioe != null) { 768783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom throw ioe; 769ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 770f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 771f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 772f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 773ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 774ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 775783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception { 776783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 777783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom // can't set after handshake 778a784bce5655435d8641f7d384c8da3fab018c491Kenny Root TestSSLSocketPair pair = TestSSLSocketPair.create(); 779783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom try { 780783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom pair.server.setUseClientMode(false); 781783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom fail(); 782783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } catch (IllegalArgumentException expected) { 783783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } 784783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom try { 785783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom pair.client.setUseClientMode(false); 786783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom fail(); 787783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } catch (IllegalArgumentException expected) { 788783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } 789783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } 790783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 7912915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom public void test_SSLSocket_untrustedServer() throws Exception { 7922915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCA2(), 7932915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom TestKeyStore.getServer()); 7942915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 7952915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom c.port); 7962915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 797783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 798783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 799783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 8002915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom try { 8012915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom server.startHandshake(); 8024d8e05bc051c080e81f873a2d62b3c4867f485afKenny Root fail(); 803aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (SSLHandshakeException expected) { 8042915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom } 805783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 8062915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom } 8072915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom }); 808783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 8092915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom try { 8102915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom client.startHandshake(); 8112915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom fail(); 8122915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom } catch (SSLHandshakeException expected) { 8132915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom assertTrue(expected.getCause() instanceof CertificateException); 8142915378e253f08e47fe5a9bfd026cd1ca7c6c351Brian Carlstrom } 815a660f1cceca91b728df45656b14321b56eb16fa5Kenny Root future.get(); 816a3d357bd346336f7ff304a9a26c81e93f67f98e6Brian Carlstrom client.close(); 817a3d357bd346336f7ff304a9a26c81e93f67f98e6Brian Carlstrom server.close(); 818a660f1cceca91b728df45656b14321b56eb16fa5Kenny Root c.close(); 819ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 820ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 82117c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_clientAuth() throws Exception { 822059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCertificate(), 823059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestKeyStore.getServer()); 824059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 825059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 82617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 827783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 828783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 829783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 830783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertFalse(server.getWantClientAuth()); 831783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertFalse(server.getNeedClientAuth()); 832783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 833783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom // confirm turning one on by itself 834783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.setWantClientAuth(true); 835783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertTrue(server.getWantClientAuth()); 836783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertFalse(server.getNeedClientAuth()); 837783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 838783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom // confirm turning setting on toggles the other 839783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.setNeedClientAuth(true); 840783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertFalse(server.getWantClientAuth()); 841783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertTrue(server.getNeedClientAuth()); 842783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 843783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom // confirm toggling back 844783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.setWantClientAuth(true); 845783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertTrue(server.getWantClientAuth()); 846783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertFalse(server.getNeedClientAuth()); 847783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 848783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 849783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 850ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 851ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 852783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 853ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.startHandshake(); 854ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(client.getSession().getLocalCertificates()); 855059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestKeyStore.assertChainLength(client.getSession().getLocalCertificates()); 856059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom TestSSLContext.assertClientCertificateChain(c.clientTrustManager, 857059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom client.getSession().getLocalCertificates()); 858783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 859f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 860f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 861f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 862ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 863ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 864aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom public void test_SSLSocket_clientAuth_bogusAlias() throws Exception { 865aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 866aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom SSLContext clientContext = SSLContext.getInstance("TLS"); 867aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom X509KeyManager keyManager = new X509KeyManager() { 868aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom @Override public String chooseClientAlias(String[] keyType, 869aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom Principal[] issuers, 870aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom Socket socket) { 871aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom return "bogus"; 872aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 873aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom @Override public String chooseServerAlias(String keyType, 874aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom Principal[] issuers, 875aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom Socket socket) { 876aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom throw new AssertionError(); 877aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 878aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom @Override public X509Certificate[] getCertificateChain(String alias) { 879aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom // return null for "bogus" alias 880aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom return null; 881aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 882aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom @Override public String[] getClientAliases(String keyType, Principal[] issuers) { 883aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom throw new AssertionError(); 884aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 885aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom @Override public String[] getServerAliases(String keyType, Principal[] issuers) { 886aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom throw new AssertionError(); 887aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 888aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom @Override public PrivateKey getPrivateKey(String alias) { 889aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom // return null for "bogus" alias 890aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom return null; 891aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 892aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom }; 893aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom clientContext.init(new KeyManager[] { keyManager }, 894aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom new TrustManager[] { c.clientTrustManager }, 895aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom null); 896aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, 897aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom c.port); 898aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 899783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 900783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 901783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 902aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom try { 903aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom server.setNeedClientAuth(true); 904aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom server.startHandshake(); 905aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom fail(); 906aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (SSLHandshakeException expected) { 907aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 908783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 909aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 910aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom }); 911aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom 912783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 913aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom try { 914aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom client.startHandshake(); 915aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom fail(); 916aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (SSLHandshakeException expected) { 917aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom // before we would get a NullPointerException from passing 918aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom // due to the null PrivateKey return by the X509KeyManager. 919aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 920783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 921aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom client.close(); 922aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom server.close(); 923aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom c.close(); 924aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } 925aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom 926a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public void test_SSLSocket_clientAuth_OpaqueKey_RSA() throws Exception { 927a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientCertificate()); 928a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 929a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 930a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public void test_SSLSocket_clientAuth_OpaqueKey_EC_RSA() throws Exception { 931a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcRsaCertificate()); 932a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 933a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 934a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public void test_SSLSocket_clientAuth_OpaqueKey_EC_EC() throws Exception { 935a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore.getClientEcEcCertificate()); 936a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 937a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 938a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private void run_SSLSocket_clientAuth_OpaqueKey(TestKeyStore keyStore) throws Exception { 939a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root try { 940a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root Security.insertProviderAt(new OpaqueProvider(), 1); 941a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 942a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root final TestSSLContext c = TestSSLContext.create(keyStore, TestKeyStore.getServer()); 943a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root SSLContext clientContext = SSLContext.getInstance("TLS"); 944a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root final X509KeyManager delegateKeyManager = (X509KeyManager) c.clientKeyManagers[0]; 945a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root X509KeyManager keyManager = new X509KeyManager() { 946a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 947a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String chooseClientAlias(String[] keyType, Principal[] issuers, 948a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root Socket socket) { 949a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegateKeyManager.chooseClientAlias(keyType, issuers, socket); 950a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 951a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 952a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 953a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String chooseServerAlias(String keyType, Principal[] issuers, 954a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root Socket socket) { 955a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegateKeyManager.chooseServerAlias(keyType, issuers, socket); 956a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 957a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 958a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 959a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public X509Certificate[] getCertificateChain(String alias) { 960a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegateKeyManager.getCertificateChain(alias); 961a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 962a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 963a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 964a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String[] getClientAliases(String keyType, Principal[] issuers) { 965a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegateKeyManager.getClientAliases(keyType, issuers); 966a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 967a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 968a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 969a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String[] getServerAliases(String keyType, Principal[] issuers) { 970a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegateKeyManager.getServerAliases(keyType, issuers); 971a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 972a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 973a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 974a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public PrivateKey getPrivateKey(String alias) { 975a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root PrivateKey privKey = delegateKeyManager.getPrivateKey(alias); 976a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root if (privKey instanceof RSAPrivateKey) { 977a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return new OpaqueDelegatingRSAPrivateKey((RSAPrivateKey) privKey); 978a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } else if (privKey instanceof ECPrivateKey) { 979a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return new OpaqueDelegatingECPrivateKey((ECPrivateKey) privKey); 980a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } else { 981a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return null; 982a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 983a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 984a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root }; 985a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root clientContext.init(new KeyManager[] { 986a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root keyManager 987a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root }, new TrustManager[] { 988a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root c.clientTrustManager 989a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root }, null); 990a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, 991a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root c.port); 992a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 993a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root ExecutorService executor = Executors.newSingleThreadExecutor(); 994a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root Future<Void> future = executor.submit(new Callable<Void>() { 995a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 996a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public Void call() throws Exception { 997a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root server.setNeedClientAuth(true); 998a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root server.startHandshake(); 999a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return null; 1000a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1001a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root }); 1002a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root executor.shutdown(); 1003a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root client.startHandshake(); 1004a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root assertNotNull(client.getSession().getLocalCertificates()); 1005a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root TestKeyStore.assertChainLength(client.getSession().getLocalCertificates()); 1006a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root TestSSLContext.assertClientCertificateChain(c.clientTrustManager, 1007a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root client.getSession().getLocalCertificates()); 1008a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root future.get(); 1009a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root client.close(); 1010a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root server.close(); 1011a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root c.close(); 1012a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } finally { 1013a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root Security.removeProvider(OpaqueProvider.NAME); 1014a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1015a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1016a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1017a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @SuppressWarnings("serial") 1018a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public static class OpaqueProvider extends Provider { 1019a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public static final String NAME = "OpaqueProvider"; 1020a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1021a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public OpaqueProvider() { 1022a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root super(NAME, 1.0, "test provider"); 1023a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1024a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root put("Signature.NONEwithRSA", OpaqueSignatureSpi.RSA.class.getName()); 1025a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root put("Signature.NONEwithECDSA", OpaqueSignatureSpi.ECDSA.class.getName()); 1026a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root put("Cipher.RSA/ECB/NoPadding", OpaqueCipherSpi.class.getName()); 1027a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1028a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1029a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1030a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected static class OpaqueSignatureSpi extends SignatureSpi { 1031a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private final String algorithm; 1032a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1033a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private Signature delegate; 1034a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1035a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected OpaqueSignatureSpi(String algorithm) { 1036a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root this.algorithm = algorithm; 1037a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1038a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1039a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public final static class RSA extends OpaqueSignatureSpi { 1040a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public RSA() { 1041a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root super("NONEwithRSA"); 1042a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1043a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1044a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1045a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public final static class ECDSA extends OpaqueSignatureSpi { 1046a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public ECDSA() { 1047a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root super("NONEwithECDSA"); 1048a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1049a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1050a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1051a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1052a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { 1053a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root fail("Cannot verify"); 1054a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1055a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1056a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1057a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { 1058a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root DelegatingPrivateKey opaqueKey = (DelegatingPrivateKey) privateKey; 1059a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root try { 1060a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate = Signature.getInstance(algorithm); 1061a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } catch (NoSuchAlgorithmException e) { 1062a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throw new InvalidKeyException(e); 1063a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1064a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.initSign(opaqueKey.getDelegate()); 1065a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1066a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1067a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1068a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineUpdate(byte b) throws SignatureException { 1069a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.update(b); 1070a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1071a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1072a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1073a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { 1074a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.update(b, off, len); 1075a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1076a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1077a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1078a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected byte[] engineSign() throws SignatureException { 1079a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.sign(); 1080a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1081a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1082a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1083a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected boolean engineVerify(byte[] sigBytes) throws SignatureException { 1084a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.verify(sigBytes); 1085a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1086a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1087a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @SuppressWarnings("deprecation") 1088a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1089a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineSetParameter(String param, Object value) 1090a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throws InvalidParameterException { 1091a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.setParameter(param, value); 1092a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1093a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1094a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @SuppressWarnings("deprecation") 1095a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1096a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected Object engineGetParameter(String param) throws InvalidParameterException { 1097a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getParameter(param); 1098a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1099a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1100a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1101a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public static class OpaqueCipherSpi extends CipherSpi { 1102a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private Cipher delegate; 1103a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1104a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public OpaqueCipherSpi() { 1105a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1106a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1107a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1108a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineSetMode(String mode) throws NoSuchAlgorithmException { 1109a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root fail(); 1110a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1111a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1112a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1113a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineSetPadding(String padding) throws NoSuchPaddingException { 1114a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root fail(); 1115a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1116a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1117a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1118a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected int engineGetBlockSize() { 1119a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getBlockSize(); 1120a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1121a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1122a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1123a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected int engineGetOutputSize(int inputLen) { 1124a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getOutputSize(inputLen); 1125a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1126a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1127a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1128a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected byte[] engineGetIV() { 1129a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getIV(); 1130a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1131a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1132a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1133a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected AlgorithmParameters engineGetParameters() { 1134a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getParameters(); 1135a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1136a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1137a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1138a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineInit(int opmode, Key key, SecureRandom random) 1139a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throws InvalidKeyException { 1140a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root getCipher(); 1141a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.init(opmode, key, random); 1142a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1143a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1144a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void getCipher() throws InvalidKeyException { 1145a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root try { 1146a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate = Cipher.getInstance("RSA/ECB/NoPadding"); 1147a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 1148a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throw new InvalidKeyException(e); 1149a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1150a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1151a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1152a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1153a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, 1154a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root SecureRandom random) 1155a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throws InvalidKeyException, InvalidAlgorithmParameterException { 1156a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root getCipher(); 1157a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.init(opmode, key, params, random); 1158a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1159a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1160a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1161a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected void engineInit(int opmode, Key key, AlgorithmParameters params, 1162a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root SecureRandom random) 1163a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throws InvalidKeyException, InvalidAlgorithmParameterException { 1164a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root getCipher(); 1165a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root delegate.init(opmode, key, params, random); 1166a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1167a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1168a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1169a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) { 1170a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.update(input, inputOffset, inputLen); 1171a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1172a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1173a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1174a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, 1175a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root int outputOffset) throws ShortBufferException { 1176a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.update(input, inputOffset, inputLen, output, outputOffset); 1177a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1178a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1179a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1180a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) 1181a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throws IllegalBlockSizeException, BadPaddingException { 1182a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.update(input, inputOffset, inputLen); 1183a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1184a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1185a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1186a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, 1187a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root int outputOffset) 1188a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { 1189a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.doFinal(input, inputOffset, inputLen, output, outputOffset); 1190a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1191a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1192a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1193a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private interface DelegatingPrivateKey { 1194a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root PrivateKey getDelegate(); 1195a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1196a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1197a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @SuppressWarnings("serial") 119872ac463cd5718d2e5aa439e569c26cc0576f4962Kenny Root private static class OpaqueDelegatingECPrivateKey 119972ac463cd5718d2e5aa439e569c26cc0576f4962Kenny Root implements ECKey, PrivateKey, DelegatingPrivateKey { 1200a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private final ECPrivateKey delegate; 1201a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1202a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public OpaqueDelegatingECPrivateKey(ECPrivateKey delegate) { 1203a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root this.delegate = delegate; 1204a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1205a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1206a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1207a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public PrivateKey getDelegate() { 1208a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate; 1209a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1210a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1211a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1212a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String getAlgorithm() { 1213a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getAlgorithm(); 1214a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1215a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1216a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1217a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String getFormat() { 1218a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return null; 1219a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1220a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1221a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1222a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public byte[] getEncoded() { 1223a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return null; 1224a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1225a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1226a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1227a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public ECParameterSpec getParams() { 1228a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getParams(); 1229a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1230a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1231a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1232a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @SuppressWarnings("serial") 123372ac463cd5718d2e5aa439e569c26cc0576f4962Kenny Root private static class OpaqueDelegatingRSAPrivateKey 123472ac463cd5718d2e5aa439e569c26cc0576f4962Kenny Root implements RSAKey, PrivateKey, DelegatingPrivateKey { 1235a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root private final RSAPrivateKey delegate; 1236a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1237a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public OpaqueDelegatingRSAPrivateKey(RSAPrivateKey delegate) { 1238a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root this.delegate = delegate; 1239a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1240a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1241a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1242a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String getAlgorithm() { 1243a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getAlgorithm(); 1244a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1245a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1246a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1247a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public String getFormat() { 1248a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return null; 1249a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1250a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1251a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1252a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public byte[] getEncoded() { 1253a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return null; 1254a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1255a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1256a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1257a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public BigInteger getModulus() { 1258a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate.getModulus(); 1259a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1260a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 1261a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root @Override 1262a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root public PrivateKey getDelegate() { 1263a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root return delegate; 1264a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1265a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root } 1266a86c73bb4b81906c965a55de48e38dd4e44f49e6Kenny Root 12678c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom public void test_SSLSocket_TrustManagerRuntimeException() throws Exception { 12688c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 12698c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom SSLContext clientContext = SSLContext.getInstance("TLS"); 12708c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom X509TrustManager trustManager = new X509TrustManager() { 12718c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom @Override public void checkClientTrusted(X509Certificate[] chain, String authType) 12728c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom throws CertificateException { 12738c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom throw new AssertionError(); 12748c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } 12758c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom @Override public void checkServerTrusted(X509Certificate[] chain, String authType) 12768c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom throws CertificateException { 12778c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom throw new RuntimeException(); // throw a RuntimeException from custom TrustManager 12788c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } 12798c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom @Override public X509Certificate[] getAcceptedIssuers() { 12808c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom throw new AssertionError(); 12818c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } 12828c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom }; 12838c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom clientContext.init(null, new TrustManager[] { trustManager }, null); 12848c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(c.host, 12858c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom c.port); 12868c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 12878c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 12888c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 12898c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom @Override public Void call() throws Exception { 12904d8e05bc051c080e81f873a2d62b3c4867f485afKenny Root try { 12914d8e05bc051c080e81f873a2d62b3c4867f485afKenny Root server.startHandshake(); 1292a660f1cceca91b728df45656b14321b56eb16fa5Kenny Root fail(); 12934d8e05bc051c080e81f873a2d62b3c4867f485afKenny Root } catch (SSLHandshakeException expected) { 12944d8e05bc051c080e81f873a2d62b3c4867f485afKenny Root } 12958c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom return null; 12968c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } 12978c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom }); 12988c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom 12998c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom executor.shutdown(); 13008c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom try { 13018c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom client.startHandshake(); 13028c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom fail(); 13038c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } catch (SSLHandshakeException expected) { 13048c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom // before we would get a RuntimeException from checkServerTrusted. 13058c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } 13068c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom future.get(); 13078c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom client.close(); 13088c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom server.close(); 13098c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom c.close(); 13108c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom } 13118c4a407e34de1b348316a9175bd1c0577c887181Brian Carlstrom 131217c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_getEnableSessionCreation() throws Exception { 131317c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 1314059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 1315059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 131617c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom SSLSocket server = (SSLSocket) c.serverSocket.accept(); 1317ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertTrue(client.getEnableSessionCreation()); 131817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom assertTrue(server.getEnableSessionCreation()); 1319f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 1320f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 1321f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 1322ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1323ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 132417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_setEnableSessionCreation_server() throws Exception { 132517c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 1326059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 1327059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 132817c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 1329783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 1330783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 1331783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 1332783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.setEnableSessionCreation(false); 1333ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 1334783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 1335783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom fail(); 1336783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } catch (SSLException expected) { 1337ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1338783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 1339ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1340ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 1341783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 1342ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 1343ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.startHandshake(); 1344ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 1345e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (SSLException expected) { 1346ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1347783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 1348f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 1349f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 1350f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 1351ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1352ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 135317c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom public void test_SSLSocket_setEnableSessionCreation_client() throws Exception { 135417c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 1355059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host, 1356059dbc04218144f985b20a228bbe98139d400d0cBrian Carlstrom c.port); 135717c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 1358783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 1359783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 1360783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 1361ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 1362783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 1363783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom fail(); 1364783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } catch (SSLException expected) { 1365ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1366783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 1367ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1368ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom }); 1369783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 1370ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.setEnableSessionCreation(false); 1371ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom try { 1372ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom client.startHandshake(); 1373ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom fail(); 1374e9505132a9a878aa77b0fb40a40dd55c9e6affe7Brian Carlstrom } catch (SSLException expected) { 1375ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1376783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 1377f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom client.close(); 1378f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom server.close(); 1379f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom c.close(); 1380ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1381ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom 13820c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom public void test_SSLSocket_getSSLParameters() throws Exception { 13830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 13840c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 13850c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 13860c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters p = ssl.getSSLParameters(); 13870c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertNotNull(p); 13880c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 13890c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom String[] cipherSuites = p.getCipherSuites(); 13900c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertNotSame(cipherSuites, ssl.getEnabledCipherSuites()); 13910c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites())); 13920c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 13930c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom String[] protocols = p.getProtocols(); 13940c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertNotSame(protocols, ssl.getEnabledProtocols()); 13950c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols())); 13960c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 13970c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth()); 13980c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth()); 139901b7734160977458d44d1fb179984fd91672f08dKenny Root 140001b7734160977458d44d1fb179984fd91672f08dKenny Root assertNull(p.getEndpointIdentificationAlgorithm()); 140101b7734160977458d44d1fb179984fd91672f08dKenny Root p.setEndpointIdentificationAlgorithm(null); 140201b7734160977458d44d1fb179984fd91672f08dKenny Root assertNull(p.getEndpointIdentificationAlgorithm()); 140301b7734160977458d44d1fb179984fd91672f08dKenny Root p.setEndpointIdentificationAlgorithm("HTTPS"); 140401b7734160977458d44d1fb179984fd91672f08dKenny Root assertEquals("HTTPS", p.getEndpointIdentificationAlgorithm()); 140501b7734160977458d44d1fb179984fd91672f08dKenny Root p.setEndpointIdentificationAlgorithm("FOO"); 140601b7734160977458d44d1fb179984fd91672f08dKenny Root assertEquals("FOO", p.getEndpointIdentificationAlgorithm()); 14070c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom } 14080c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14090c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom public void test_SSLSocket_setSSLParameters() throws Exception { 14100c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 14110c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLSocket ssl = (SSLSocket) sf.createSocket(); 14120c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom String[] defaultCipherSuites = ssl.getEnabledCipherSuites(); 14130c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom String[] defaultProtocols = ssl.getEnabledProtocols(); 14140c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom String[] supportedCipherSuites = ssl.getSupportedCipherSuites(); 14150c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom String[] supportedProtocols = ssl.getSupportedProtocols(); 14160c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14170c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom { 14180c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters p = new SSLParameters(); 14190c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom ssl.setSSLParameters(p); 14200c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(Arrays.asList(defaultCipherSuites), 14210c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom Arrays.asList(ssl.getEnabledCipherSuites())); 14220c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(Arrays.asList(defaultProtocols), 14230c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom Arrays.asList(ssl.getEnabledProtocols())); 14240c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom } 14250c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14260c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom { 14270c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters p = new SSLParameters(supportedCipherSuites, 14280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom supportedProtocols); 14290c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom ssl.setSSLParameters(p); 14300c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(Arrays.asList(supportedCipherSuites), 14310c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom Arrays.asList(ssl.getEnabledCipherSuites())); 14320c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertEquals(Arrays.asList(supportedProtocols), 14330c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom Arrays.asList(ssl.getEnabledProtocols())); 14340c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom } 14350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom { 14360c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom SSLParameters p = new SSLParameters(); 14370c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14380c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom p.setNeedClientAuth(true); 14390c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getNeedClientAuth()); 14400c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getWantClientAuth()); 14410c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom ssl.setSSLParameters(p); 14420c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(ssl.getNeedClientAuth()); 14430c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getWantClientAuth()); 14440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14450c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom p.setWantClientAuth(true); 14460c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(ssl.getNeedClientAuth()); 14470c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getWantClientAuth()); 14480c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom ssl.setSSLParameters(p); 14490c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getNeedClientAuth()); 14500c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(ssl.getWantClientAuth()); 14510c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14520c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom p.setWantClientAuth(false); 14530c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getNeedClientAuth()); 14540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(ssl.getWantClientAuth()); 14550c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom ssl.setSSLParameters(p); 14560c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getNeedClientAuth()); 14570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertFalse(ssl.getWantClientAuth()); 14580c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom } 14590c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom } 14600c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom 14615f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom public void test_SSLSocket_close() throws Exception { 14625f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom TestSSLSocketPair pair = TestSSLSocketPair.create(); 14635f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom SSLSocket server = pair.server; 14645f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom SSLSocket client = pair.client; 14655f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertFalse(server.isClosed()); 14665f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertFalse(client.isClosed()); 14675f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom InputStream input = client.getInputStream(); 14685f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom OutputStream output = client.getOutputStream(); 14695f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom server.close(); 14705f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.close(); 14715f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertTrue(server.isClosed()); 14725f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertTrue(client.isClosed()); 14735f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 14745f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom // close after close is okay... 14755f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom server.close(); 14765f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.close(); 14775f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 14785f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom // ...so are a lot of other operations... 14795f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom HandshakeCompletedListener l = new HandshakeCompletedListener () { 14802216155c3066236eb450f307983019f69a10303dKenny Root @Override 14815f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom public void handshakeCompleted(HandshakeCompletedEvent e) {} 14825f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom }; 14835f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.addHandshakeCompletedListener(l); 14845f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertNotNull(client.getEnabledCipherSuites()); 14855f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertNotNull(client.getEnabledProtocols()); 14865f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.getEnableSessionCreation(); 14875f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.getNeedClientAuth(); 14885f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertNotNull(client.getSession()); 14895f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertNotNull(client.getSSLParameters()); 14905f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertNotNull(client.getSupportedProtocols()); 14915f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.getUseClientMode(); 14925f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.getWantClientAuth(); 14935f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.removeHandshakeCompletedListener(l); 14945f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setEnabledCipherSuites(new String[0]); 14955f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setEnabledProtocols(new String[0]); 14965f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setEnableSessionCreation(false); 14975f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setNeedClientAuth(false); 14985f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setSSLParameters(client.getSSLParameters()); 14995f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setWantClientAuth(false); 15005f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 15015f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom // ...but some operations are expected to give SocketException... 15025f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15035f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.startHandshake(); 15045f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 15055f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 15065f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15075f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15085f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.getInputStream(); 15095f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 15105f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 15115f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15125f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15135f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.getOutputStream(); 15145f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 15155f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 15165f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15175f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15185f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom input.read(); 15195f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 15205f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 15215f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15225f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15235f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom input.read(null, -1, -1); 15245f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 1525aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (NullPointerException expected) { 1526aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertTrue(StandardNames.IS_RI); 15275f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 1528aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertFalse(StandardNames.IS_RI); 15295f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15305f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15315f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom output.write(-1); 15325f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 15335f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 15345f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15355f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15365f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom output.write(null, -1, -1); 15375f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 1538aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom } catch (NullPointerException expected) { 1539aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertTrue(StandardNames.IS_RI); 15405f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (SocketException expected) { 1541aba5e8c281fb9c6be23229246473fa0b433dd997Brian Carlstrom assertFalse(StandardNames.IS_RI); 15425f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15435f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 15445f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom // ... and one gives IllegalArgumentException 15455f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom try { 15465f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom client.setUseClientMode(false); 15475f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom fail(); 15485f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } catch (IllegalArgumentException expected) { 15495f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 1550f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 1551f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom pair.close(); 15525f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom } 15535f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom 15541c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom /** 15551c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom * b/3350645 Test to confirm that an SSLSocket.close() performing 15561c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom * an SSL_shutdown does not throw an IOException if the peer 15571c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom * socket has been closed. 15581c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom */ 15591c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception { 15601c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 15611c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom final Socket underlying = new Socket(c.host, c.port); 15621c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom final SSLSocket wrapping = (SSLSocket) 15631c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom c.clientContext.getSocketFactory().createSocket(underlying, 15641c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom c.host.getHostName(), 15651c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom c.port, 15661c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom false); 1567783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 1568783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> clientFuture = executor.submit(new Callable<Void>() { 1569783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 1570783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom wrapping.startHandshake(); 1571783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom wrapping.getOutputStream().write(42); 1572783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom // close the underlying socket, 1573783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom // so that no SSL shutdown is sent 1574783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom underlying.close(); 1575783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom wrapping.close(); 1576783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 15771c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom } 15781c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom }); 1579783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 15801c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom 15811c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom SSLSocket server = (SSLSocket) c.serverSocket.accept(); 15821c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom server.startHandshake(); 15831c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom server.getInputStream().read(); 15841c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom // wait for thread to finish so we know client is closed. 1585783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom clientFuture.get(); 15861c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom // close should cause an SSL_shutdown which will fail 15871c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom // because the peer has closed, but it shouldn't throw. 15881c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom server.close(); 15891c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom } 15901c64b3adb85345659ac60ad82216268acba18764Brian Carlstrom 159101b7734160977458d44d1fb179984fd91672f08dKenny Root public void test_SSLSocket_endpointIdentification_Success() throws Exception { 159201b7734160977458d44d1fb179984fd91672f08dKenny Root final TestSSLContext c = TestSSLContext.create(); 159301b7734160977458d44d1fb179984fd91672f08dKenny Root SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(); 159401b7734160977458d44d1fb179984fd91672f08dKenny Root SSLParameters p = client.getSSLParameters(); 159501b7734160977458d44d1fb179984fd91672f08dKenny Root p.setEndpointIdentificationAlgorithm("HTTPS"); 159601b7734160977458d44d1fb179984fd91672f08dKenny Root client.connect(new InetSocketAddress(c.host, c.port)); 159701b7734160977458d44d1fb179984fd91672f08dKenny Root final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 159801b7734160977458d44d1fb179984fd91672f08dKenny Root ExecutorService executor = Executors.newSingleThreadExecutor(); 159901b7734160977458d44d1fb179984fd91672f08dKenny Root Future<Void> future = executor.submit(new Callable<Void>() { 160001b7734160977458d44d1fb179984fd91672f08dKenny Root @Override public Void call() throws Exception { 160101b7734160977458d44d1fb179984fd91672f08dKenny Root server.startHandshake(); 160201b7734160977458d44d1fb179984fd91672f08dKenny Root assertNotNull(server.getSession()); 160301b7734160977458d44d1fb179984fd91672f08dKenny Root try { 160401b7734160977458d44d1fb179984fd91672f08dKenny Root server.getSession().getPeerCertificates(); 160501b7734160977458d44d1fb179984fd91672f08dKenny Root fail(); 160601b7734160977458d44d1fb179984fd91672f08dKenny Root } catch (SSLPeerUnverifiedException expected) { 160701b7734160977458d44d1fb179984fd91672f08dKenny Root } 160801b7734160977458d44d1fb179984fd91672f08dKenny Root Certificate[] localCertificates = server.getSession().getLocalCertificates(); 160901b7734160977458d44d1fb179984fd91672f08dKenny Root assertNotNull(localCertificates); 161001b7734160977458d44d1fb179984fd91672f08dKenny Root TestKeyStore.assertChainLength(localCertificates); 161101b7734160977458d44d1fb179984fd91672f08dKenny Root assertNotNull(localCertificates[0]); 161201b7734160977458d44d1fb179984fd91672f08dKenny Root TestSSLContext.assertCertificateInKeyStore(localCertificates[0], 161301b7734160977458d44d1fb179984fd91672f08dKenny Root c.serverKeyStore); 161401b7734160977458d44d1fb179984fd91672f08dKenny Root return null; 161501b7734160977458d44d1fb179984fd91672f08dKenny Root } 161601b7734160977458d44d1fb179984fd91672f08dKenny Root }); 161701b7734160977458d44d1fb179984fd91672f08dKenny Root executor.shutdown(); 161801b7734160977458d44d1fb179984fd91672f08dKenny Root client.startHandshake(); 161901b7734160977458d44d1fb179984fd91672f08dKenny Root assertNotNull(client.getSession()); 162001b7734160977458d44d1fb179984fd91672f08dKenny Root assertNull(client.getSession().getLocalCertificates()); 162101b7734160977458d44d1fb179984fd91672f08dKenny Root Certificate[] peerCertificates = client.getSession().getPeerCertificates(); 162201b7734160977458d44d1fb179984fd91672f08dKenny Root assertNotNull(peerCertificates); 162301b7734160977458d44d1fb179984fd91672f08dKenny Root TestKeyStore.assertChainLength(peerCertificates); 162401b7734160977458d44d1fb179984fd91672f08dKenny Root assertNotNull(peerCertificates[0]); 162501b7734160977458d44d1fb179984fd91672f08dKenny Root TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore); 162601b7734160977458d44d1fb179984fd91672f08dKenny Root future.get(); 162701b7734160977458d44d1fb179984fd91672f08dKenny Root client.close(); 162801b7734160977458d44d1fb179984fd91672f08dKenny Root server.close(); 162901b7734160977458d44d1fb179984fd91672f08dKenny Root c.close(); 163001b7734160977458d44d1fb179984fd91672f08dKenny Root } 163101b7734160977458d44d1fb179984fd91672f08dKenny Root 163201b7734160977458d44d1fb179984fd91672f08dKenny Root public void test_SSLSocket_endpointIdentification_Failure() throws Exception { 163301b7734160977458d44d1fb179984fd91672f08dKenny Root final TestSSLContext c = TestSSLContext.create(); 16341ce90cc78f833da6ff674fb2028f2560938313ecKenny Root SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(); 163501b7734160977458d44d1fb179984fd91672f08dKenny Root SSLParameters p = client.getSSLParameters(); 163601b7734160977458d44d1fb179984fd91672f08dKenny Root p.setEndpointIdentificationAlgorithm("HTTPS"); 163701b7734160977458d44d1fb179984fd91672f08dKenny Root client.setSSLParameters(p); 16381ce90cc78f833da6ff674fb2028f2560938313ecKenny Root client.connect(c.getLoopbackAsHostname("unmatched.example.com", c.port)); 163901b7734160977458d44d1fb179984fd91672f08dKenny Root final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 164001b7734160977458d44d1fb179984fd91672f08dKenny Root ExecutorService executor = Executors.newSingleThreadExecutor(); 164101b7734160977458d44d1fb179984fd91672f08dKenny Root Future<Void> future = executor.submit(new Callable<Void>() { 164201b7734160977458d44d1fb179984fd91672f08dKenny Root @Override public Void call() throws Exception { 164301b7734160977458d44d1fb179984fd91672f08dKenny Root try { 164401b7734160977458d44d1fb179984fd91672f08dKenny Root server.startHandshake(); 164501b7734160977458d44d1fb179984fd91672f08dKenny Root fail("Should receive SSLHandshakeException as server"); 164601b7734160977458d44d1fb179984fd91672f08dKenny Root } catch (SSLHandshakeException expected) { 164701b7734160977458d44d1fb179984fd91672f08dKenny Root } 164801b7734160977458d44d1fb179984fd91672f08dKenny Root return null; 164901b7734160977458d44d1fb179984fd91672f08dKenny Root } 165001b7734160977458d44d1fb179984fd91672f08dKenny Root }); 165101b7734160977458d44d1fb179984fd91672f08dKenny Root executor.shutdown(); 165201b7734160977458d44d1fb179984fd91672f08dKenny Root try { 165301b7734160977458d44d1fb179984fd91672f08dKenny Root client.startHandshake(); 165401b7734160977458d44d1fb179984fd91672f08dKenny Root fail("Should throw when hostname does not match expected"); 165501b7734160977458d44d1fb179984fd91672f08dKenny Root } catch (SSLHandshakeException expected) { 165601b7734160977458d44d1fb179984fd91672f08dKenny Root } finally { 165701b7734160977458d44d1fb179984fd91672f08dKenny Root try { 165801b7734160977458d44d1fb179984fd91672f08dKenny Root future.get(); 165901b7734160977458d44d1fb179984fd91672f08dKenny Root } finally { 166001b7734160977458d44d1fb179984fd91672f08dKenny Root client.close(); 166101b7734160977458d44d1fb179984fd91672f08dKenny Root server.close(); 166201b7734160977458d44d1fb179984fd91672f08dKenny Root c.close(); 166301b7734160977458d44d1fb179984fd91672f08dKenny Root } 166401b7734160977458d44d1fb179984fd91672f08dKenny Root } 166501b7734160977458d44d1fb179984fd91672f08dKenny Root } 166601b7734160977458d44d1fb179984fd91672f08dKenny Root 1667a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom public void test_SSLSocket_setSoTimeout_basic() throws Exception { 1668a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom ServerSocket listening = new ServerSocket(0); 1669a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1670a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort()); 1671a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom assertEquals(0, underlying.getSoTimeout()); 1672a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1673a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 1674a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom Socket wrapping = sf.createSocket(underlying, null, -1, false); 1675a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom assertEquals(0, wrapping.getSoTimeout()); 1676a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1677a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom // setting wrapper sets underlying and ... 1678615225a35dbd838210270b282d1196deff643b51Brian Carlstrom int expectedTimeoutMillis = 1000; // 10 was too small because it was affected by rounding 1679fc1332710b0af3bbe658535a257048cf8c7577f2Brian Carlstrom wrapping.setSoTimeout(expectedTimeoutMillis); 16806566167989735858978d062a4385104ce5eca7e3Neil Fuller // The kernel can round the requested value based on the HZ setting. We allow up to 10ms. 16816566167989735858978d062a4385104ce5eca7e3Neil Fuller assertTrue(Math.abs(expectedTimeoutMillis - wrapping.getSoTimeout()) <= 10); 16826566167989735858978d062a4385104ce5eca7e3Neil Fuller assertTrue(Math.abs(expectedTimeoutMillis - underlying.getSoTimeout()) <= 10); 1683a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1684a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom // ... getting wrapper inspects underlying 1685a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom underlying.setSoTimeout(0); 1686a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom assertEquals(0, wrapping.getSoTimeout()); 1687a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom assertEquals(0, underlying.getSoTimeout()); 1688a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom } 1689a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1690a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom public void test_SSLSocket_setSoTimeout_wrapper() throws Exception { 1691a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom if (StandardNames.IS_RI) { 1692a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom // RI cannot handle this case 1693a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom return; 1694a5c608e59f9d574ea4bc65e9dff44aae2f34fd26Brian Carlstrom } 1695a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom ServerSocket listening = new ServerSocket(0); 1696a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1697a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom // setSoTimeout applies to read, not connect, so connect first 1698a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort()); 1699a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom Socket server = listening.accept(); 1700a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1701a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 1702a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom Socket clientWrapping = sf.createSocket(underlying, null, -1, false); 1703a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1704a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom underlying.setSoTimeout(1); 1705a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom try { 1706a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom clientWrapping.getInputStream().read(); 1707a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom fail(); 1708a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom } catch (SocketTimeoutException expected) { 1709a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom } 1710a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1711a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom clientWrapping.close(); 1712a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom server.close(); 1713a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom underlying.close(); 1714a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom listening.close(); 1715a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom } 1716a4a95792af235d4bf3256eab3208f74fae8ec262Brian Carlstrom 1717615225a35dbd838210270b282d1196deff643b51Brian Carlstrom public void test_SSLSocket_setSoWriteTimeout() throws Exception { 1718615225a35dbd838210270b282d1196deff643b51Brian Carlstrom if (StandardNames.IS_RI) { 1719615225a35dbd838210270b282d1196deff643b51Brian Carlstrom // RI does not support write timeout on sockets 1720615225a35dbd838210270b282d1196deff643b51Brian Carlstrom return; 1721615225a35dbd838210270b282d1196deff643b51Brian Carlstrom } 1722615225a35dbd838210270b282d1196deff643b51Brian Carlstrom 1723615225a35dbd838210270b282d1196deff643b51Brian Carlstrom final TestSSLContext c = TestSSLContext.create(); 172451cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(); 172551cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom 172651cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // Try to make the client SO_SNDBUF size as small as possible 172751cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // (it can default to 512k or even megabytes). Note that 172851cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // socket(7) says that the kernel will double the request to 172951cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // leave room for its own book keeping and that the minimal 173051cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // value will be 2048. Also note that tcp(7) says the value 173151cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // needs to be set before connect(2). 173251cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom int sendBufferSize = 1024; 173351cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom client.setSendBufferSize(sendBufferSize); 173451cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom sendBufferSize = client.getSendBufferSize(); 173551cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom 173651cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // In jb-mr2 it was found that we need to also set SO_RCVBUF 173751cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // to a minimal size or the write would not block. While 173851cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // tcp(2) says the value has to be set before listen(2), it 173951cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // seems fine to set it before accept(2). 174051cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom final int recvBufferSize = 128; 174151cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom c.serverSocket.setReceiveBufferSize(recvBufferSize); 174251cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom 174351cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom client.connect(new InetSocketAddress(c.host, c.port)); 174451cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom 1745615225a35dbd838210270b282d1196deff643b51Brian Carlstrom final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 1746615225a35dbd838210270b282d1196deff643b51Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 1747615225a35dbd838210270b282d1196deff643b51Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 1748615225a35dbd838210270b282d1196deff643b51Brian Carlstrom @Override public Void call() throws Exception { 1749615225a35dbd838210270b282d1196deff643b51Brian Carlstrom server.startHandshake(); 1750615225a35dbd838210270b282d1196deff643b51Brian Carlstrom return null; 1751615225a35dbd838210270b282d1196deff643b51Brian Carlstrom } 1752615225a35dbd838210270b282d1196deff643b51Brian Carlstrom }); 1753615225a35dbd838210270b282d1196deff643b51Brian Carlstrom executor.shutdown(); 1754615225a35dbd838210270b282d1196deff643b51Brian Carlstrom client.startHandshake(); 1755615225a35dbd838210270b282d1196deff643b51Brian Carlstrom 1756615225a35dbd838210270b282d1196deff643b51Brian Carlstrom // Reflection is used so this can compile on the RI 175770b79a2cc89dd2845582001cd3f2a8cf8301ce6cKenny Root String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl"; 17582216155c3066236eb450f307983019f69a10303dKenny Root Class<?> actualClass = client.getClass(); 1759615225a35dbd838210270b282d1196deff643b51Brian Carlstrom assertEquals(expectedClassName, actualClass.getName()); 1760615225a35dbd838210270b282d1196deff643b51Brian Carlstrom Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout", 17612216155c3066236eb450f307983019f69a10303dKenny Root new Class<?>[] { Integer.TYPE }); 1762615225a35dbd838210270b282d1196deff643b51Brian Carlstrom setSoWriteTimeout.invoke(client, 1); 1763615225a35dbd838210270b282d1196deff643b51Brian Carlstrom 1764615225a35dbd838210270b282d1196deff643b51Brian Carlstrom 1765615225a35dbd838210270b282d1196deff643b51Brian Carlstrom try { 176651cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // Add extra space to the write to exceed the send buffer 176751cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom // size and cause the write to block. 176851cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom final int extra = 1; 176951cf1b49bca54ec0229a51df400ad1bee580b1bbBrian Carlstrom client.getOutputStream().write(new byte[sendBufferSize + extra]); 1770615225a35dbd838210270b282d1196deff643b51Brian Carlstrom fail(); 1771615225a35dbd838210270b282d1196deff643b51Brian Carlstrom } catch (SocketTimeoutException expected) { 1772615225a35dbd838210270b282d1196deff643b51Brian Carlstrom } 1773615225a35dbd838210270b282d1196deff643b51Brian Carlstrom 1774615225a35dbd838210270b282d1196deff643b51Brian Carlstrom future.get(); 1775615225a35dbd838210270b282d1196deff643b51Brian Carlstrom client.close(); 1776615225a35dbd838210270b282d1196deff643b51Brian Carlstrom server.close(); 1777615225a35dbd838210270b282d1196deff643b51Brian Carlstrom c.close(); 1778615225a35dbd838210270b282d1196deff643b51Brian Carlstrom } 1779615225a35dbd838210270b282d1196deff643b51Brian Carlstrom 17809f7c676c1937bdafce079cf02a67ac121296a335Kenny Root public void test_SSLSocket_reusedNpnSocket() throws Exception { 17819f7c676c1937bdafce079cf02a67ac121296a335Kenny Root if (StandardNames.IS_RI) { 17829f7c676c1937bdafce079cf02a67ac121296a335Kenny Root // RI does not support NPN/ALPN 17839f7c676c1937bdafce079cf02a67ac121296a335Kenny Root return; 17849f7c676c1937bdafce079cf02a67ac121296a335Kenny Root } 17859f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 17869f7c676c1937bdafce079cf02a67ac121296a335Kenny Root byte[] npnProtocols = new byte[] { 17879f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 8, 'h', 't', 't', 'p', '/', '1', '.', '1' 17889f7c676c1937bdafce079cf02a67ac121296a335Kenny Root }; 17899f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 17909f7c676c1937bdafce079cf02a67ac121296a335Kenny Root final TestSSLContext c = TestSSLContext.create(); 17919f7c676c1937bdafce079cf02a67ac121296a335Kenny Root SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(); 17929f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 17939f7c676c1937bdafce079cf02a67ac121296a335Kenny Root // Reflection is used so this can compile on the RI 17949f7c676c1937bdafce079cf02a67ac121296a335Kenny Root String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl"; 17959f7c676c1937bdafce079cf02a67ac121296a335Kenny Root Class<?> actualClass = client.getClass(); 17969f7c676c1937bdafce079cf02a67ac121296a335Kenny Root assertEquals(expectedClassName, actualClass.getName()); 17979f7c676c1937bdafce079cf02a67ac121296a335Kenny Root Method setNpnProtocols = actualClass.getMethod("setNpnProtocols", byte[].class); 17989f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 17999f7c676c1937bdafce079cf02a67ac121296a335Kenny Root ExecutorService executor = Executors.newSingleThreadExecutor(); 18009f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18019f7c676c1937bdafce079cf02a67ac121296a335Kenny Root // First connection with NPN set on client and server 18029f7c676c1937bdafce079cf02a67ac121296a335Kenny Root { 18039f7c676c1937bdafce079cf02a67ac121296a335Kenny Root setNpnProtocols.invoke(client, npnProtocols); 18049f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client.connect(new InetSocketAddress(c.host, c.port)); 18059f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18069f7c676c1937bdafce079cf02a67ac121296a335Kenny Root final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 18079f7c676c1937bdafce079cf02a67ac121296a335Kenny Root assertEquals(expectedClassName, server.getClass().getName()); 18089f7c676c1937bdafce079cf02a67ac121296a335Kenny Root setNpnProtocols.invoke(server, npnProtocols); 18099f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18109f7c676c1937bdafce079cf02a67ac121296a335Kenny Root Future<Void> future = executor.submit(new Callable<Void>() { 18119f7c676c1937bdafce079cf02a67ac121296a335Kenny Root @Override 18129f7c676c1937bdafce079cf02a67ac121296a335Kenny Root public Void call() throws Exception { 18139f7c676c1937bdafce079cf02a67ac121296a335Kenny Root server.startHandshake(); 18149f7c676c1937bdafce079cf02a67ac121296a335Kenny Root return null; 18159f7c676c1937bdafce079cf02a67ac121296a335Kenny Root } 18169f7c676c1937bdafce079cf02a67ac121296a335Kenny Root }); 18179f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client.startHandshake(); 18189f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18199f7c676c1937bdafce079cf02a67ac121296a335Kenny Root future.get(); 18209f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client.close(); 18219f7c676c1937bdafce079cf02a67ac121296a335Kenny Root server.close(); 18229f7c676c1937bdafce079cf02a67ac121296a335Kenny Root } 18239f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18249f7c676c1937bdafce079cf02a67ac121296a335Kenny Root // Second connection with client NPN already set on the SSL context, but 18259f7c676c1937bdafce079cf02a67ac121296a335Kenny Root // without server NPN set. 18269f7c676c1937bdafce079cf02a67ac121296a335Kenny Root { 18279f7c676c1937bdafce079cf02a67ac121296a335Kenny Root SSLServerSocket serverSocket = (SSLServerSocket) c.serverContext 18289f7c676c1937bdafce079cf02a67ac121296a335Kenny Root .getServerSocketFactory().createServerSocket(0); 18299f7c676c1937bdafce079cf02a67ac121296a335Kenny Root InetAddress host = InetAddress.getLocalHost(); 18309f7c676c1937bdafce079cf02a67ac121296a335Kenny Root int port = serverSocket.getLocalPort(); 18319f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18329f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(); 18339f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client.connect(new InetSocketAddress(host, port)); 18349f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18359f7c676c1937bdafce079cf02a67ac121296a335Kenny Root final SSLSocket server = (SSLSocket) serverSocket.accept(); 18369f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18379f7c676c1937bdafce079cf02a67ac121296a335Kenny Root Future<Void> future = executor.submit(new Callable<Void>() { 18389f7c676c1937bdafce079cf02a67ac121296a335Kenny Root @Override 18399f7c676c1937bdafce079cf02a67ac121296a335Kenny Root public Void call() throws Exception { 18409f7c676c1937bdafce079cf02a67ac121296a335Kenny Root server.startHandshake(); 18419f7c676c1937bdafce079cf02a67ac121296a335Kenny Root return null; 18429f7c676c1937bdafce079cf02a67ac121296a335Kenny Root } 18439f7c676c1937bdafce079cf02a67ac121296a335Kenny Root }); 18449f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client.startHandshake(); 18459f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18469f7c676c1937bdafce079cf02a67ac121296a335Kenny Root future.get(); 18479f7c676c1937bdafce079cf02a67ac121296a335Kenny Root client.close(); 18489f7c676c1937bdafce079cf02a67ac121296a335Kenny Root server.close(); 18499f7c676c1937bdafce079cf02a67ac121296a335Kenny Root serverSocket.close(); 18509f7c676c1937bdafce079cf02a67ac121296a335Kenny Root } 18519f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 18529f7c676c1937bdafce079cf02a67ac121296a335Kenny Root c.close(); 18539f7c676c1937bdafce079cf02a67ac121296a335Kenny Root } 18549f7c676c1937bdafce079cf02a67ac121296a335Kenny Root 185584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom public void test_SSLSocket_interrupt() throws Exception { 185636f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom test_SSLSocket_interrupt_case(true, true); 185736f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom test_SSLSocket_interrupt_case(true, false); 185836f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom test_SSLSocket_interrupt_case(false, true); 1859d255af15f749d98cf06fe72fdf46ccf3988f10d2Narayan Kamath test_SSLSocket_interrupt_case(false, false); 186084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom } 186184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom 186236f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom private void test_SSLSocket_interrupt_case(boolean readUnderlying, boolean closeUnderlying) 186384f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom throws Exception { 186436f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom 186536f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom ServerSocket listening = new ServerSocket(0); 186636f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom 186736f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort()); 186836f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom Socket server = listening.accept(); 186936f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom 187036f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); 187136f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom Socket clientWrapping = sf.createSocket(underlying, null, -1, true); 187236f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom 187336f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom final Socket toRead = (readUnderlying) ? underlying : clientWrapping; 187436f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom final Socket toClose = (closeUnderlying) ? underlying : clientWrapping; 187536f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom 1876783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom ExecutorService executor = Executors.newSingleThreadExecutor(); 1877783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> future = executor.submit(new Callable<Void>() { 1878783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 1879783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Thread.sleep(1 * 1000); 1880783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom toClose.close(); 1881783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 188284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom } 1883783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom }); 1884783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 188584f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom try { 188636f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom toRead.setSoTimeout(5 * 1000); 188784f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom toRead.getInputStream().read(); 188884f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom fail(); 188984f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom } catch (SocketTimeoutException e) { 189084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom throw e; 189184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom } catch (SocketException expected) { 189284f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom } 1893783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom future.get(); 189436f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom 189536f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom server.close(); 189636f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom underlying.close(); 189736f1c15a1cb2e66b8852ea51f7a82c4ccc9ac886Brian Carlstrom listening.close(); 1898783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } 1899783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 1900783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom /** 1901783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom * b/7014266 Test to confirm that an SSLSocket.close() on one 19026ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root * thread will interrupt another thread blocked reading on the same 1903783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom * socket. 1904783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom */ 1905783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom public void test_SSLSocket_interrupt_read() throws Exception { 19069ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro final int readingTimeoutMillis = 5000; 1907783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom TestSSLContext c = TestSSLContext.create(); 1908783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom final Socket underlying = new Socket(c.host, c.port); 1909783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom final SSLSocket wrapping = (SSLSocket) 1910783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom c.clientContext.getSocketFactory().createSocket(underlying, 1911783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom c.host.getHostName(), 1912783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom c.port, 1913783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom false); 19146ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root 19156ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root // Create our own thread group so we can inspect the stack state later. 19166ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root final ThreadGroup clientGroup = new ThreadGroup("client"); 19176ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() { 19186ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root @Override 19196ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root public Thread newThread(Runnable r) { 19206ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root return new Thread(clientGroup, r); 19216ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root } 19226ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root }); 19236ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root 1924783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom Future<Void> clientFuture = executor.submit(new Callable<Void>() { 1925783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom @Override public Void call() throws Exception { 1926783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom try { 1927783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom wrapping.startHandshake(); 1928783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertFalse(StandardNames.IS_RI); 19299ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro wrapping.setSoTimeout(readingTimeoutMillis); 1930783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom assertEquals(-1, wrapping.getInputStream().read()); 1931783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } catch (Exception e) { 19329ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro if (!StandardNames.IS_RI) { 19339ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro throw e; 19349ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro } 1935783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } 1936783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom return null; 1937783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom } 1938783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom }); 1939783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom executor.shutdown(); 1940783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom 1941783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom SSLSocket server = (SSLSocket) c.serverSocket.accept(); 1942783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.startHandshake(); 19436ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root 19446ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root /* 19456ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root * Wait for the client to at least be in the "read" method before 19466ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root * calling close() 19476ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root */ 19486ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root Thread[] threads = new Thread[1]; 19496ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root clientGroup.enumerate(threads); 19506ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root if (threads[0] != null) { 19516ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root boolean clientInRead = false; 19526ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root while (!clientInRead) { 19536ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root StackTraceElement[] elements = threads[0].getStackTrace(); 19546ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root for (StackTraceElement element : elements) { 19556ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root if ("read".equals(element.getMethodName())) { 19569ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro // The client might be executing "read" but still not have reached the 19579ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro // point in which it's blocked reading. This is causing flakiness 19589ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro // (b/24367646). Delaying for a fraction of the timeout. 19599ada7e3ea3c181bf43a20481c15a5715d129d7cbSergio Giro Thread.sleep(1000); 19606ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root clientInRead = true; 19616ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root break; 19626ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root } 19636ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root } 19646ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root } 19656ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root } 19666ced3e6c746117d4145515a11762cff3de3c1fa9Kenny Root 1967783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom wrapping.close(); 1968783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom clientFuture.get(); 1969783004cceef470884b3ee6946cbbfc4af0f28ae7Brian Carlstrom server.close(); 197084f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom } 197184f161268b8ae93a9046c40ca8381aa92148f2f6Brian Carlstrom 19720c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom public void test_TestSSLSocketPair_create() { 197317c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLSocketPair test = TestSSLSocketPair.create(); 1974ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(test.c); 1975ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(test.server); 1976ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(test.client); 1977bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom assertTrue(test.server.isConnected()); 1978bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom assertTrue(test.client.isConnected()); 19795f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertFalse(test.server.isClosed()); 19805f2e6872311240319509aed64d9f58cd5b64719bBrian Carlstrom assertFalse(test.client.isClosed()); 1981ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(test.server.getSession()); 1982ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom assertNotNull(test.client.getSession()); 19830c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(test.server.getSession().isValid()); 19840c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom assertTrue(test.client.getSession().isValid()); 1985f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom test.close(); 1986ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom } 1987bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 1988b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void test_SSLSocket_ClientHello_record_size() throws Exception { 19890007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // This test checks the size of ClientHello of the default SSLSocket. TLS/SSL handshakes 19900007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // with older/unpatched F5/BIG-IP appliances are known to stall and time out when 19910007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // the fragment containing ClientHello is between 256 and 511 (inclusive) bytes long. 1992b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin SSLContext sslContext = SSLContext.getInstance("TLS"); 1993b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin sslContext.init(null, null, null); 1994b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); 1995b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin sslSocketFactory = new DelegatingSSLSocketFactory(sslSocketFactory) { 1996b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin @Override 199726f2557b26ea23326178f029e07a8adbfc27d0bfNeil Fuller protected SSLSocket configureSocket(SSLSocket socket) { 1998b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin // Enable SNI extension on the socket (this is typically enabled by default) 1999b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin // to increase the size of ClientHello. 2000b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin try { 2001b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin Method setHostname = 2002b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin socket.getClass().getMethod("setHostname", String.class); 2003b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin setHostname.invoke(socket, "sslsockettest.androidcts.google.com"); 2004b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } catch (NoSuchMethodException ignored) { 2005b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } catch (Exception e) { 2006b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin throw new RuntimeException("Failed to enable SNI", e); 2007b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2008b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2009b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin // Enable Session Tickets extension on the socket (this is typically enabled 2010b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin // by default) to increase the size of ClientHello. 2011b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin try { 2012b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin Method setUseSessionTickets = 2013b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin socket.getClass().getMethod( 2014b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin "setUseSessionTickets", boolean.class); 2015b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin setUseSessionTickets.invoke(socket, true); 2016b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } catch (NoSuchMethodException ignored) { 2017b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } catch (Exception e) { 2018b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin throw new RuntimeException("Failed to enable Session Tickets", e); 2019b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 202026f2557b26ea23326178f029e07a8adbfc27d0bfNeil Fuller return socket; 2021b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2022b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin }; 2023b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2024b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin TlsRecord firstReceivedTlsRecord = captureTlsHandshakeFirstTlsRecord(sslSocketFactory); 2025b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals("TLS record type", TlsProtocols.HANDSHAKE, firstReceivedTlsRecord.type); 2026b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin HandshakeMessage handshakeMessage = HandshakeMessage.read( 2027b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin new DataInputStream(new ByteArrayInputStream(firstReceivedTlsRecord.fragment))); 2028b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals("HandshakeMessage type", 2029b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type); 2030b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin int fragmentLength = firstReceivedTlsRecord.fragment.length; 2031b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin if ((fragmentLength >= 256) && (fragmentLength <= 511)) { 2032b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin fail("Fragment containing ClientHello is of dangerous length: " 2033b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin + fragmentLength + " bytes"); 2034b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2035b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2036b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2037b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void test_SSLSocket_ClientHello_cipherSuites() throws Exception { 2038b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() { 2039b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin @Override 2040b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void run(SSLSocketFactory sslSocketFactory) throws Exception { 2041b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory); 204281885494e46596c796cdcb5037b91d92915b65a7Kenny Root final String[] cipherSuites; 204381885494e46596c796cdcb5037b91d92915b65a7Kenny Root 204481885494e46596c796cdcb5037b91d92915b65a7Kenny Root // RFC 5746 allows you to send an empty "renegotiation_info" extension *or* 204581885494e46596c796cdcb5037b91d92915b65a7Kenny Root // a special signaling cipher suite. The TLS API has no way to check or 204681885494e46596c796cdcb5037b91d92915b65a7Kenny Root // indicate that a certain TLS extension should be used. 204781885494e46596c796cdcb5037b91d92915b65a7Kenny Root HelloExtension renegotiationInfoExtension = clientHello.findExtensionByType( 204881885494e46596c796cdcb5037b91d92915b65a7Kenny Root HelloExtension.TYPE_RENEGOTIATION_INFO); 204981885494e46596c796cdcb5037b91d92915b65a7Kenny Root if (renegotiationInfoExtension != null && 205081885494e46596c796cdcb5037b91d92915b65a7Kenny Root renegotiationInfoExtension.data.length == 1 && 205181885494e46596c796cdcb5037b91d92915b65a7Kenny Root renegotiationInfoExtension.data[0] == 0) { 205281885494e46596c796cdcb5037b91d92915b65a7Kenny Root cipherSuites = new String[clientHello.cipherSuites.size() + 1]; 205381885494e46596c796cdcb5037b91d92915b65a7Kenny Root cipherSuites[clientHello.cipherSuites.size()] = 205481885494e46596c796cdcb5037b91d92915b65a7Kenny Root StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION; 205581885494e46596c796cdcb5037b91d92915b65a7Kenny Root } else { 205681885494e46596c796cdcb5037b91d92915b65a7Kenny Root cipherSuites = new String[clientHello.cipherSuites.size()]; 205781885494e46596c796cdcb5037b91d92915b65a7Kenny Root } 205881885494e46596c796cdcb5037b91d92915b65a7Kenny Root 2059b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin for (int i = 0; i < clientHello.cipherSuites.size(); i++) { 2060b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin CipherSuite cipherSuite = clientHello.cipherSuites.get(i); 2061b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin cipherSuites[i] = cipherSuite.getAndroidName(); 2062b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2063b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin StandardNames.assertDefaultCipherSuites(cipherSuites); 2064b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2065b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin }, getSSLSocketFactoriesToTest()); 2066b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2067b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2068c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root public void test_SSLSocket_ClientHello_supportedCurves() throws Exception { 2069c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() { 2070c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root @Override 2071c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root public void run(SSLSocketFactory sslSocketFactory) throws Exception { 2072c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory); 2073c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root 2074c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root EllipticCurvesHelloExtension ecExtension = (EllipticCurvesHelloExtension) 2075c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root clientHello.findExtensionByType(HelloExtension.TYPE_ELLIPTIC_CURVES); 2076c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root final String[] supportedCurves; 2077c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root if (ecExtension == null) { 2078c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root supportedCurves = new String[0]; 2079c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root } else { 2080c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root assertTrue(ecExtension.wellFormed); 2081c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root supportedCurves = new String[ecExtension.supported.size()]; 2082c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root for (int i = 0; i < ecExtension.supported.size(); i++) { 2083c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root EllipticCurve curve = ecExtension.supported.get(i); 2084c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root supportedCurves[i] = curve.toString(); 2085c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root } 2086c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root } 2087c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root 2088c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root StandardNames.assertDefaultEllipticCurves(supportedCurves); 2089c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root } 2090c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root }, getSSLSocketFactoriesToTest()); 2091c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root } 2092c97ba7f9b6a7621a55b95a7d5fd00cdffd6f09d5Kenny Root 2093b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void test_SSLSocket_ClientHello_clientProtocolVersion() throws Exception { 2094b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() { 2095b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin @Override 2096b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void run(SSLSocketFactory sslSocketFactory) throws Exception { 2097b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory); 2098b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals(TlsProtocolVersion.TLSv1_2, clientHello.clientVersion); 2099b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2100b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin }, getSSLSocketFactoriesToTest()); 2101b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2102b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2103b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void test_SSLSocket_ClientHello_compressionMethods() throws Exception { 2104b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() { 2105b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin @Override 2106b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void run(SSLSocketFactory sslSocketFactory) throws Exception { 2107b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory); 2108b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals(Arrays.asList(CompressionMethod.NULL), clientHello.compressionMethods); 2109b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2110b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin }, getSSLSocketFactoriesToTest()); 2111b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2112b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2113b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void test_SSLSocket_ClientHello_SNI() throws Exception { 2114b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ForEachRunner.runNamed(new ForEachRunner.Callback<SSLSocketFactory>() { 2115b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin @Override 2116b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin public void run(SSLSocketFactory sslSocketFactory) throws Exception { 2117b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ClientHello clientHello = captureTlsHandshakeClientHello(sslSocketFactory); 2118b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ServerNameHelloExtension sniExtension = (ServerNameHelloExtension) 2119b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin clientHello.findExtensionByType(HelloExtension.TYPE_SERVER_NAME); 2120b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertNotNull(sniExtension); 2121b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals(Arrays.asList("localhost.localdomain"), sniExtension.hostnames); 2122b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2123b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin }, getSSLSocketFactoriesToTest()); 2124b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2125b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2126b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin private List<Pair<String, SSLSocketFactory>> getSSLSocketFactoriesToTest() 2127b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin throws NoSuchAlgorithmException, KeyManagementException { 2128b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin List<Pair<String, SSLSocketFactory>> result = 2129b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin new ArrayList<Pair<String, SSLSocketFactory>>(); 2130b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin result.add(Pair.of("default", (SSLSocketFactory) SSLSocketFactory.getDefault())); 2131b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin for (String sslContextProtocol : StandardNames.SSL_CONTEXT_PROTOCOLS) { 2132b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin SSLContext sslContext = SSLContext.getInstance(sslContextProtocol); 2133b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(sslContextProtocol)) { 2134b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin continue; 2135b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2136b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin sslContext.init(null, null, null); 2137b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin result.add(Pair.of( 2138b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin "SSLContext(\"" + sslContext.getProtocol() + "\")", 2139b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin sslContext.getSocketFactory())); 2140b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2141b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin return result; 2142b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2143b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2144b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin private ClientHello captureTlsHandshakeClientHello(SSLSocketFactory sslSocketFactory) 2145b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin throws Exception { 2146b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin TlsRecord record = captureTlsHandshakeFirstTlsRecord(sslSocketFactory); 2147b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals("TLS record type", TlsProtocols.HANDSHAKE, record.type); 2148b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ByteArrayInputStream fragmentIn = new ByteArrayInputStream(record.fragment); 2149b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin HandshakeMessage handshakeMessage = HandshakeMessage.read(new DataInputStream(fragmentIn)); 2150b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals("HandshakeMessage type", 2151b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin HandshakeMessage.TYPE_CLIENT_HELLO, handshakeMessage.type); 2152b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin // Assert that the fragment does not contain any more messages 2153b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals(0, fragmentIn.available()); 2154b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2155b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin return (ClientHello) handshakeMessage; 2156b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2157b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2158b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin private TlsRecord captureTlsHandshakeFirstTlsRecord(SSLSocketFactory sslSocketFactory) 2159b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin throws Exception { 2160b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin byte[] firstReceivedChunk = captureTlsHandshakeFirstTransmittedChunkBytes(sslSocketFactory); 2161b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin ByteArrayInputStream firstReceivedChunkIn = new ByteArrayInputStream(firstReceivedChunk); 2162b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin TlsRecord record = TlsRecord.read(new DataInputStream(firstReceivedChunkIn)); 2163b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin // Assert that the chunk does not contain any more data 2164b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin assertEquals(0, firstReceivedChunkIn.available()); 2165b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2166b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin return record; 2167b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin } 2168b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin 2169b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin private byte[] captureTlsHandshakeFirstTransmittedChunkBytes( 2170b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin final SSLSocketFactory sslSocketFactory) throws Exception { 21710007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // Since there's no straightforward way to obtain a ClientHello from SSLSocket, this test 21720007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // does the following: 21730007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // 1. Creates a listening server socket (a plain one rather than a TLS/SSL one). 21740007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // 2. Creates a client SSLSocket, which connects to the server socket and initiates the 21750007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // TLS/SSL handshake. 21760007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // 3. Makes the server socket accept an incoming connection on the server socket, and reads 21770007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // the first chunk of data received. This chunk is assumed to be the ClientHello. 21780007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // NOTE: Steps 2 and 3 run concurrently. 21790007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin ServerSocket listeningSocket = null; 21800007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin ExecutorService executorService = Executors.newFixedThreadPool(2); 21810007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin 21820007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // Some Socket operations are not interruptible via Thread.interrupt for some reason. To 21830007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // work around, we unblock these sockets using Socket.close. 21840007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin final Socket[] sockets = new Socket[2]; 21850007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin try { 21860007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // 1. Create the listening server socket. 21870007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin listeningSocket = ServerSocketFactory.getDefault().createServerSocket(0); 21880007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin final ServerSocket finalListeningSocket = listeningSocket; 21890007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // 2. (in background) Wait for an incoming connection and read its first chunk. 21900007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin final Future<byte[]> readFirstReceivedChunkFuture = 21910007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin executorService.submit(new Callable<byte[]>() { 21920007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin @Override 21930007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin public byte[] call() throws Exception { 21940007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin Socket socket = finalListeningSocket.accept(); 21950007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin sockets[1] = socket; 21960007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin try { 21970007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin byte[] buffer = new byte[64 * 1024]; 21980007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin int bytesRead = socket.getInputStream().read(buffer); 21990007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin if (bytesRead == -1) { 22000007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin throw new EOFException("Failed to read anything"); 22010007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22020007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin return Arrays.copyOf(buffer, bytesRead); 22030007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } finally { 220427088efe0caca697e257e08d41387af8130364e0Kenny Root closeQuietly(socket); 22050007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22060007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22070007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin }); 22080007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin 22090007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // 3. Create a client socket, connect it to the server socket, and start the TLS/SSL 22100007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // handshake. 22110007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin executorService.submit(new Callable<Void>() { 22120007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin @Override 22130007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin public Void call() throws Exception { 2214b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin Socket client = new Socket(); 22150007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin sockets[0] = client; 22160007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin try { 22170007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin client.connect(finalListeningSocket.getLocalSocketAddress()); 22180007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // Initiate the TLS/SSL handshake which is expected to fail as soon as the 22190007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // server socket receives a ClientHello. 22200007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin try { 2221b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket( 2222b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin client, 2223b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin "localhost.localdomain", 2224b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin finalListeningSocket.getLocalPort(), 2225b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin true); 2226b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin sslSocket.startHandshake(); 22270007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin fail(); 22280007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin return null; 22290007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } catch (IOException expected) {} 22300007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin return null; 22310007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } finally { 223227088efe0caca697e257e08d41387af8130364e0Kenny Root closeQuietly(client); 22330007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22340007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22350007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin }); 22360007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin 22370007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin // Wait for the ClientHello to arrive 2238b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin return readFirstReceivedChunkFuture.get(10, TimeUnit.SECONDS); 22390007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } finally { 22400007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin executorService.shutdownNow(); 224127088efe0caca697e257e08d41387af8130364e0Kenny Root closeQuietly(listeningSocket); 224227088efe0caca697e257e08d41387af8130364e0Kenny Root closeQuietly(sockets[0]); 224327088efe0caca697e257e08d41387af8130364e0Kenny Root closeQuietly(sockets[1]); 22440007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) { 22450007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin fail("Timed out while waiting for the test to shut down"); 22460007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22470007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22480007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin } 22490007cf607af1bcc958b584242bb5d8d191ee22c4Alex Klyubin 22504e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath // http://b/18428603 22514e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath public void test_SSLSocket_getPortWithSNI() throws Exception { 22524e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath TestSSLContext context = TestSSLContext.create(); 22534e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath 22544e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath SSLSocket client = null; 22554e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath try { 22564e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(); 22574e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath client.connect(new InetSocketAddress(context.host, context.port)); 22584e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath try { 22594e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath // This is crucial to reproducing issue 18428603. 22604e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath Method setHostname = client.getClass().getMethod("setHostname", String.class); 22614e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath setHostname.invoke(client, "sslsockettest.androidcts.google.com"); 22624e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath } catch (NoSuchMethodException ignored) { 22634e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath } 22644e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath 22654e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath assertTrue(client.getPort() > 0); 22664e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath } finally { 22674e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath client.close(); 22684e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath context.close(); 22694e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath } 22704e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath } 22714e05c844ea6c6359345b66120182d4d86fc9e22bNarayan Kamath 2272b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root public void test_SSLSocket_SNIHostName() throws Exception { 2273b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root TestSSLContext c = TestSSLContext.create(); 2274b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root 2275b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root final SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(); 2276b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root SSLParameters clientParams = client.getSSLParameters(); 2277b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root clientParams.setServerNames(Collections.singletonList( 2278b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root (SNIServerName) new SNIHostName("www.example.com"))); 2279b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root client.setSSLParameters(clientParams); 2280b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root 2281b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root SSLParameters serverParams = c.serverSocket.getSSLParameters(); 2282b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root serverParams.setSNIMatchers(Collections.singletonList( 2283b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root SNIHostName.createSNIMatcher("www\\.example\\.com"))); 2284b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root c.serverSocket.setSSLParameters(serverParams); 2285b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root 2286b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root client.connect(new InetSocketAddress(c.host, c.port)); 2287b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root final SSLSocket server = (SSLSocket) c.serverSocket.accept(); 2288b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root 2289b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root ExecutorService executor = Executors.newSingleThreadExecutor(); 2290b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root Future<Void> future = executor.submit(new Callable<Void>() { 2291b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root @Override public Void call() throws Exception { 2292b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root client.startHandshake(); 2293b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root return null; 2294b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root } 2295b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root }); 2296b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root executor.shutdown(); 2297b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root server.startHandshake(); 2298b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root 2299b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root SSLSession serverSession = server.getSession(); 2300f4c5da45b0c9ff0992e6d29c89953ed3ae820843Neil Fuller assertTrue(serverSession instanceof ExtendedSSLSession); 2301b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root ExtendedSSLSession extendedServerSession = (ExtendedSSLSession) serverSession; 2302b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root List<SNIServerName> requestedNames = extendedServerSession.getRequestedServerNames(); 2303b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root assertNotNull(requestedNames); 2304b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root assertEquals(1, requestedNames.size()); 2305b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root SNIServerName serverName = requestedNames.get(0); 2306ab1a6e203cb03add037f1c2e48e1a8aabcbdfc55Kenny Root assertEquals(StandardConstants.SNI_HOST_NAME, serverName.getType()); 2307b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root assertTrue(serverName instanceof SNIHostName); 2308b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root SNIHostName serverHostName = (SNIHostName) serverName; 2309b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root assertEquals("www.example.com", serverHostName.getAsciiName()); 2310b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root } 2311b96141a0e46ce6e769c70565bec7ec3fdd58d717Kenny Root 2312e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root public void test_SSLSocket_sendsTlsFallbackScsv_Fallback_Success() throws Exception { 2313e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root TestSSLContext context = TestSSLContext.create(); 2314e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2315e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final SSLSocket client = (SSLSocket) 2316e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root context.clientContext.getSocketFactory().createSocket(context.host, context.port); 2317e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final SSLSocket server = (SSLSocket) context.serverSocket.accept(); 2318e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2319e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final String[] serverCipherSuites = server.getEnabledCipherSuites(); 2320e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final String[] clientCipherSuites = new String[serverCipherSuites.length + 1]; 2321e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length); 2322e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK; 2323e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2324e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root ExecutorService executor = Executors.newFixedThreadPool(2); 2325e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root Future<Void> s = executor.submit(new Callable<Void>() { 23262216155c3066236eb450f307983019f69a10303dKenny Root @Override 2327e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root public Void call() throws Exception { 2328e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.setEnabledProtocols(new String[] { "TLSv1.2" }); 2329e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.setEnabledCipherSuites(serverCipherSuites); 2330e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.startHandshake(); 2331e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root return null; 2332e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2333e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root }); 2334e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root Future<Void> c = executor.submit(new Callable<Void>() { 23352216155c3066236eb450f307983019f69a10303dKenny Root @Override 2336e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root public Void call() throws Exception { 2337e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.setEnabledProtocols(new String[] { "TLSv1.2" }); 2338e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.setEnabledCipherSuites(clientCipherSuites); 2339e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.startHandshake(); 2340e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root return null; 2341e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2342e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root }); 2343e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root executor.shutdown(); 2344e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2345e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root s.get(); 2346e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root c.get(); 2347e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.close(); 2348e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.close(); 2349e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root context.close(); 2350e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2351e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2352bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller // Confirms that communication without the TLS_FALLBACK_SCSV cipher works as it always did. 2353bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller public void test_SSLSocket_sendsNoTlsFallbackScsv_Fallback_Success() throws Exception { 2354bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller TestSSLContext context = TestSSLContext.create(); 2355bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller 2356bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller final SSLSocket client = (SSLSocket) 2357bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller context.clientContext.getSocketFactory().createSocket(context.host, context.port); 2358bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller final SSLSocket server = (SSLSocket) context.serverSocket.accept(); 2359bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller 2360bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller // Confirm absence of TLS_FALLBACK_SCSV. 2361bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller assertFalse(Arrays.asList(client.getEnabledCipherSuites()) 2362bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller .contains(StandardNames.CIPHER_SUITE_FALLBACK)); 2363bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller 2364bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller ExecutorService executor = Executors.newFixedThreadPool(2); 2365bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller Future<Void> s = executor.submit(new Callable<Void>() { 23662216155c3066236eb450f307983019f69a10303dKenny Root @Override 2367bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller public Void call() throws Exception { 23688f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker server.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1.1" }); 2369bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller server.startHandshake(); 2370bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller return null; 2371bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller } 2372bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller }); 2373bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller Future<Void> c = executor.submit(new Callable<Void>() { 23742216155c3066236eb450f307983019f69a10303dKenny Root @Override 2375bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller public Void call() throws Exception { 23768f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker client.setEnabledProtocols(new String[] { "TLSv1.1" }); 2377bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller client.startHandshake(); 2378bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller return null; 2379bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller } 2380bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller }); 2381bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller executor.shutdown(); 2382bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller 2383bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller s.get(); 2384bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller c.get(); 2385bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller client.close(); 2386bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller server.close(); 2387bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller context.close(); 2388bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller } 2389bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller 239043e063b43daab0962554639dda272428a59f3c24Kenny Root private static void assertInappropriateFallbackIsCause(Throwable cause) { 239143e063b43daab0962554639dda272428a59f3c24Kenny Root assertTrue(cause.getMessage(), cause.getMessage().contains("inappropriate fallback") 239243e063b43daab0962554639dda272428a59f3c24Kenny Root || cause.getMessage().contains("INAPPROPRIATE_FALLBACK")); 239343e063b43daab0962554639dda272428a59f3c24Kenny Root } 239443e063b43daab0962554639dda272428a59f3c24Kenny Root 2395e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root public void test_SSLSocket_sendsTlsFallbackScsv_InappropriateFallback_Failure() throws Exception { 2396e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root TestSSLContext context = TestSSLContext.create(); 2397e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2398e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final SSLSocket client = (SSLSocket) 2399e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root context.clientContext.getSocketFactory().createSocket(context.host, context.port); 2400e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final SSLSocket server = (SSLSocket) context.serverSocket.accept(); 2401e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2402e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final String[] serverCipherSuites = server.getEnabledCipherSuites(); 2403bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller 2404bc1ea6573c76663718d441f7b0b849a91f3eefbdNeil Fuller // Add TLS_FALLBACK_SCSV 2405e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root final String[] clientCipherSuites = new String[serverCipherSuites.length + 1]; 2406e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root System.arraycopy(serverCipherSuites, 0, clientCipherSuites, 0, serverCipherSuites.length); 2407e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root clientCipherSuites[serverCipherSuites.length] = StandardNames.CIPHER_SUITE_FALLBACK; 2408e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2409e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root ExecutorService executor = Executors.newFixedThreadPool(2); 2410e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root Future<Void> s = executor.submit(new Callable<Void>() { 24112216155c3066236eb450f307983019f69a10303dKenny Root @Override 2412e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root public Void call() throws Exception { 24138f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker server.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1" }); 2414e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.setEnabledCipherSuites(serverCipherSuites); 2415e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root try { 2416e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.startHandshake(); 2417e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root fail("Should result in inappropriate fallback"); 2418e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } catch (SSLHandshakeException expected) { 2419cce4d86d447d0e86f94035dd0285726c4025fae6Kenny Root Throwable cause = expected.getCause(); 2420cce4d86d447d0e86f94035dd0285726c4025fae6Kenny Root assertEquals(SSLProtocolException.class, cause.getClass()); 242143e063b43daab0962554639dda272428a59f3c24Kenny Root assertInappropriateFallbackIsCause(cause); 2422e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2423e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root return null; 2424e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2425e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root }); 2426e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root Future<Void> c = executor.submit(new Callable<Void>() { 24272216155c3066236eb450f307983019f69a10303dKenny Root @Override 2428e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root public Void call() throws Exception { 24298f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker client.setEnabledProtocols(new String[] { "TLSv1" }); 2430e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.setEnabledCipherSuites(clientCipherSuites); 2431e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root try { 2432e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.startHandshake(); 2433e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root fail("Should receive TLS alert inappropriate fallback"); 2434e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } catch (SSLHandshakeException expected) { 2435cce4d86d447d0e86f94035dd0285726c4025fae6Kenny Root Throwable cause = expected.getCause(); 2436cce4d86d447d0e86f94035dd0285726c4025fae6Kenny Root assertEquals(SSLProtocolException.class, cause.getClass()); 243743e063b43daab0962554639dda272428a59f3c24Kenny Root assertInappropriateFallbackIsCause(cause); 2438e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2439e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root return null; 2440e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2441e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root }); 2442e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root executor.shutdown(); 2443e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 2444e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root s.get(); 2445e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root c.get(); 2446e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root client.close(); 2447e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root server.close(); 244858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root context.close(); 244958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 245058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 245158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root public void test_SSLSocket_ClientGetsAlertDuringHandshake_HasGoodExceptionMessage() 245258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root throws Exception { 245358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root TestSSLContext context = TestSSLContext.create(); 245458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 245558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root final ServerSocket listener = ServerSocketFactory.getDefault().createServerSocket(0); 245658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( 245758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root context.host, listener.getLocalPort()); 245858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root final Socket server = listener.accept(); 245958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 246058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root ExecutorService executor = Executors.newFixedThreadPool(2); 246158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root Future<Void> c = executor.submit(new Callable<Void>() { 24622216155c3066236eb450f307983019f69a10303dKenny Root @Override 246358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root public Void call() throws Exception { 246458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root try { 246558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.startHandshake(); 246658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root fail("Should receive handshake exception"); 246758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } catch (SSLHandshakeException expected) { 246858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN")); 246958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root assertFalse(expected.getMessage().contains("You should never see this.")); 247058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 247158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root return null; 247258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 247358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 247458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root Future<Void> s = executor.submit(new Callable<Void>() { 24752216155c3066236eb450f307983019f69a10303dKenny Root @Override 247658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root public Void call() throws Exception { 247758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Wait until the client sends something. 247858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root byte[] scratch = new byte[8192]; 247958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root server.getInputStream().read(scratch); 248058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 248158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Write a bogus TLS alert: 248258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Protocol Version) 248358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root server.getOutputStream().write(new byte[] { 248458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46 248558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 248658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 248758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // TLSv1.2 Record Layer: Alert (Level: Warning, Description: Close Notify) 248858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root server.getOutputStream().write(new byte[] { 248958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00 249058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 249158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 249258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root return null; 249358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 249458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 249558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 249658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 249758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root executor.shutdown(); 249858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root c.get(5, TimeUnit.SECONDS); 249958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root s.get(5, TimeUnit.SECONDS); 250058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.close(); 250158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root server.close(); 250258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root listener.close(); 250358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root context.close(); 250458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 250558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 250658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root public void test_SSLSocket_ServerGetsAlertDuringHandshake_HasGoodExceptionMessage() 250758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root throws Exception { 250858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root TestSSLContext context = TestSSLContext.create(); 250958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 251058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root final Socket client = SocketFactory.getDefault().createSocket(context.host, context.port); 251158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root final SSLSocket server = (SSLSocket) context.serverSocket.accept(); 251258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 251358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root ExecutorService executor = Executors.newFixedThreadPool(2); 251458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root Future<Void> s = executor.submit(new Callable<Void>() { 25152216155c3066236eb450f307983019f69a10303dKenny Root @Override 251658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root public Void call() throws Exception { 251758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root try { 251858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root server.startHandshake(); 251958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root fail("Should receive handshake exception"); 252058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } catch (SSLHandshakeException expected) { 252158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root assertFalse(expected.getMessage().contains("SSL_ERROR_ZERO_RETURN")); 252258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root assertFalse(expected.getMessage().contains("You should never see this.")); 252358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 252458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root return null; 252558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 252658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 252758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root Future<Void> c = executor.submit(new Callable<Void>() { 25282216155c3066236eb450f307983019f69a10303dKenny Root @Override 252958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root public Void call() throws Exception { 253058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Send bogus ClientHello: 253158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // TLSv1.2 Record Layer: Handshake Protocol: Client Hello 253258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.getOutputStream().write(new byte[] { 253358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x16, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0xb9, 253458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xb5, (byte) 0x03, 253558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x03, (byte) 0x5a, (byte) 0x31, (byte) 0xba, (byte) 0x44, 253658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x24, (byte) 0xfd, (byte) 0xf0, (byte) 0x56, (byte) 0x46, 253758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0xea, (byte) 0xee, (byte) 0x1c, (byte) 0x62, (byte) 0x8f, 253858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x18, (byte) 0x04, (byte) 0xbd, (byte) 0x1c, (byte) 0xbc, 253958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0xbf, (byte) 0x6d, (byte) 0x84, (byte) 0x12, (byte) 0xe9, 254058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x94, (byte) 0xf5, (byte) 0x1c, (byte) 0x15, (byte) 0x3e, 254158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x79, (byte) 0x01, (byte) 0xe2, (byte) 0x00, (byte) 0x00, 254258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x28, (byte) 0xc0, (byte) 0x2b, (byte) 0xc0, (byte) 0x2c, 254358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0xc0, (byte) 0x2f, (byte) 0xc0, (byte) 0x30, (byte) 0x00, 254458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x9e, (byte) 0x00, (byte) 0x9f, (byte) 0xc0, (byte) 0x09, 254558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0xc0, (byte) 0x0a, (byte) 0xc0, (byte) 0x13, (byte) 0xc0, 254658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x14, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x39, 254758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0xc0, (byte) 0x07, (byte) 0xc0, (byte) 0x11, (byte) 0x00, 254858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x9c, (byte) 0x00, (byte) 0x9d, (byte) 0x00, (byte) 0x2f, 254958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x35, (byte) 0x00, (byte) 0x05, (byte) 0x00, 255058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0xff, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x64, 255158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x04, (byte) 0x03, 255258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x0a, 255358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x32, (byte) 0x00, 255458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x0e, (byte) 0x00, (byte) 0x0d, (byte) 0x00, (byte) 0x19, 255558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x0c, (byte) 0x00, 255658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x18, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x0a, 255758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x16, (byte) 0x00, (byte) 0x17, (byte) 0x00, 255858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x08, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x07, 255958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x15, (byte) 0x00, 256058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x04, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x12, 256158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x13, (byte) 0x00, (byte) 0x01, (byte) 0x00, 256258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x0f, 256358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x11, (byte) 0x00, 256458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x0d, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x1e, 256558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x06, (byte) 0x01, (byte) 0x06, (byte) 0x02, (byte) 0x06, 256658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x03, (byte) 0x05, (byte) 0x01, (byte) 0x05, (byte) 0x02, 256758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x05, (byte) 0x03, (byte) 0x04, (byte) 0x01, (byte) 0x04, 256858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x02, (byte) 0x04, (byte) 0x03, (byte) 0x03, (byte) 0x01, 256958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x03, (byte) 0x02, 257058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x03, 257158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 257258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 257358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Wait until the server sends something. 257458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root byte[] scratch = new byte[8192]; 257558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.getInputStream().read(scratch); 257658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 257758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Write a bogus TLS alert: 257858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // TLSv1.2 Record Layer: Alert (Level: Warning, Description: 257958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Protocol Version) 258058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.getOutputStream().write(new byte[] { 258158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x46 258258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 258358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 258458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // TLSv1.2 Record Layer: Alert (Level: Warning, Description: 258558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root // Close Notify) 258658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.getOutputStream().write(new byte[] { 258758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x00 258858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 258958d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 259058d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root return null; 259158d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root } 259258d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root }); 259358d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root 259458d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root executor.shutdown(); 259558d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root c.get(5, TimeUnit.SECONDS); 259658d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root s.get(5, TimeUnit.SECONDS); 259758d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root client.close(); 259858d0df7981667d3add1b94c57eb9d7e1b29dc2b1Kenny Root server.close(); 2599e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root context.close(); 2600e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root } 2601e6a6e935e98f426c7000b2bf4086f87101f4441cKenny Root 26028f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker public void test_SSLSocket_SSLv3Unsupported() throws Exception { 26038f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker TestSSLContext context = TestSSLContext.create(); 26048f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker 26058f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker final SSLSocket client = (SSLSocket) 26068f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker context.clientContext.getSocketFactory().createSocket(); 26078f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker 2608621cb842e7656a5baa594a0d1f2a7a20fae270a4Kenny Root // For app compatibility, SSLv3 is stripped out when setting only. 2609621cb842e7656a5baa594a0d1f2a7a20fae270a4Kenny Root client.setEnabledProtocols(new String[] {"SSLv3"}); 2610621cb842e7656a5baa594a0d1f2a7a20fae270a4Kenny Root assertEquals(0, client.getEnabledProtocols().length); 26118f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker 26128f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker try { 26138f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker client.setEnabledProtocols(new String[] {"SSL"}); 26148f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker fail("SSLSocket should not support SSL protocol"); 26158f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker } catch (IllegalArgumentException expected) { 26168f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker } 26178f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker } 26188f2073552a3aa97ce95f8380f5cab1742d77de91Chad Brubaker 2619846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian // We modified the toString() of SSLSocket, and it's based on the output 2620846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian // of Socket.toString(), so we want to make sure that a change in 2621846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian // Socket.toString() doesn't cause us to output nonsense. 2622846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian public void test_SSLSocket_toString() throws Exception { 2623846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian // The actual implementation from a security provider might do something 2624846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian // special for its toString(), so we create our own implementation 2625846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian SSLSocket socket = new SSLSocket() { 2626846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public String[] getSupportedCipherSuites() { return new String[0]; } 2627846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public String[] getEnabledCipherSuites() { return new String[0]; } 2628846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void setEnabledCipherSuites(String[] strings) { } 2629846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public String[] getSupportedProtocols() { return new String[0]; } 2630846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public String[] getEnabledProtocols() { return new String[0]; } 2631846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void setEnabledProtocols(String[] strings) { } 2632846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public SSLSession getSession() { return null; } 2633846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void addHandshakeCompletedListener( 2634846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian HandshakeCompletedListener handshakeCompletedListener) { } 2635846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void removeHandshakeCompletedListener( 2636846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian HandshakeCompletedListener handshakeCompletedListener) { } 2637846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void startHandshake() throws IOException { } 2638846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void setUseClientMode(boolean b) { } 2639846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public boolean getUseClientMode() { return false; } 2640846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void setNeedClientAuth(boolean b) { } 2641846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public boolean getNeedClientAuth() { return false; } 2642846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void setWantClientAuth(boolean b) { } 2643846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public boolean getWantClientAuth() { return false; } 2644846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public void setEnableSessionCreation(boolean b) { } 2645846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian @Override public boolean getEnableSessionCreation() { return false; } 2646846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian }; 2647846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian assertTrue(socket.toString().startsWith("SSLSocket[")); 2648846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian } 2649846d0260638a42ed6b5bbca7fa5ea1ad92ce8858Adam Vartanian 2650bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom /** 2651bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom * Not run by default by JUnit, but can be run by Vogar by 2652101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson * specifying it explicitly (or with main method below) 2653bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom */ 26540c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom public void stress_test_TestSSLSocketPair_create() { 2655bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom final boolean verbose = true; 2656bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom while (true) { 265717c744222e249ed5f7ab36e49ed11f9bb062a302Brian Carlstrom TestSSLSocketPair test = TestSSLSocketPair.create(); 2658bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom if (verbose) { 2659bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom System.out.println("client=" + test.client.getLocalPort() 2660bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom + " server=" + test.server.getLocalPort()); 2661bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } else { 2662bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom System.out.print("X"); 2663bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 2664f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 2665f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom /* 2666f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom We don't close on purpose in this stress test to add 2667f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom races in file descriptors reuse when the garbage 2668f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom collector runs concurrently and finalizes sockets 2669f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom */ 2670f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom // test.close(); 2671f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom 2672bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 2673bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 2674bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom 267527088efe0caca697e257e08d41387af8130364e0Kenny Root private static final void readFully(InputStream in, byte[] dst) throws IOException { 267627088efe0caca697e257e08d41387af8130364e0Kenny Root int offset = 0; 267727088efe0caca697e257e08d41387af8130364e0Kenny Root int byteCount = dst.length; 267827088efe0caca697e257e08d41387af8130364e0Kenny Root while (byteCount > 0) { 267927088efe0caca697e257e08d41387af8130364e0Kenny Root int bytesRead = in.read(dst, offset, byteCount); 268027088efe0caca697e257e08d41387af8130364e0Kenny Root if (bytesRead < 0) { 268127088efe0caca697e257e08d41387af8130364e0Kenny Root throw new EOFException(); 268227088efe0caca697e257e08d41387af8130364e0Kenny Root } 268327088efe0caca697e257e08d41387af8130364e0Kenny Root offset += bytesRead; 268427088efe0caca697e257e08d41387af8130364e0Kenny Root byteCount -= bytesRead; 268527088efe0caca697e257e08d41387af8130364e0Kenny Root } 268627088efe0caca697e257e08d41387af8130364e0Kenny Root } 268727088efe0caca697e257e08d41387af8130364e0Kenny Root 268827088efe0caca697e257e08d41387af8130364e0Kenny Root private static final void closeQuietly(Closeable socket) { 268927088efe0caca697e257e08d41387af8130364e0Kenny Root if (socket != null) { 269027088efe0caca697e257e08d41387af8130364e0Kenny Root try { 269127088efe0caca697e257e08d41387af8130364e0Kenny Root socket.close(); 269227088efe0caca697e257e08d41387af8130364e0Kenny Root } catch (Exception ignored) { 269327088efe0caca697e257e08d41387af8130364e0Kenny Root } 269427088efe0caca697e257e08d41387af8130364e0Kenny Root } 269527088efe0caca697e257e08d41387af8130364e0Kenny Root } 269627088efe0caca697e257e08d41387af8130364e0Kenny Root 2697101547d4a82ba21031dc7cb62018720dbd493758Jesse Wilson public static void main (String[] args) { 26980c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom new SSLSocketTest().stress_test_TestSSLSocketPair_create(); 2699bcfb325d5b1f9529b439cc0805a1c140521510f7Brian Carlstrom } 2700ebabb91c8c87ac2be2dca70ae343130f9755047fBrian Carlstrom} 2701