1da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian/* 2da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * Copyright 2017 The Android Open Source Project 3da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * 4da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * Licensed under the Apache License, Version 2.0 (the "License"); 5da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * you may not use this file except in compliance with the License. 6da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * You may obtain a copy of the License at 7da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * 8da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * http://www.apache.org/licenses/LICENSE-2.0 9da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * 10da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * Unless required by applicable law or agreed to in writing, software 11da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * distributed under the License is distributed on an "AS IS" BASIS, 12da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * See the License for the specific language governing permissions and 14da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian * limitations under the License. 15da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian */ 16da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 17da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianpackage org.conscrypt; 18da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 19da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.conscrypt.TestUtils.LOCALHOST; 20da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.conscrypt.TestUtils.getConscryptServerSocketFactory; 21da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.conscrypt.TestUtils.getJdkSocketFactory; 22da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.conscrypt.TestUtils.getProtocols; 23da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.conscrypt.TestUtils.newTextMessage; 24da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.conscrypt.TestUtils.pickUnusedPort; 25da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport static org.junit.Assert.assertArrayEquals; 26da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 27da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport java.io.IOException; 28da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport java.util.Arrays; 29da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport java.util.concurrent.Future; 30da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport java.util.concurrent.TimeUnit; 31da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport javax.net.ssl.SSLServerSocket; 32da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport javax.net.ssl.SSLServerSocketFactory; 33da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport javax.net.ssl.SSLSocket; 34da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport javax.net.ssl.SSLSocketFactory; 35da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.After; 36da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.Before; 37da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.Test; 38da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.runner.RunWith; 39da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.runners.Parameterized; 40da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.runners.Parameterized.Parameter; 41da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianimport org.junit.runners.Parameterized.Parameters; 42da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 43da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian@RunWith(Parameterized.class) 44da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianpublic class OpenSSLServerSocketImplTest { 45da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian private static final String CIPHER = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; 467bc9febe8749e98a3812a0dc4380ceae75c29450Johann private static final int MESSAGE_SIZE = 4096; 477bc9febe8749e98a3812a0dc4380ceae75c29450Johann 487bc9febe8749e98a3812a0dc4380ceae75c29450Johann /** 497bc9febe8749e98a3812a0dc4380ceae75c29450Johann * Various factories for SSL server sockets. 507bc9febe8749e98a3812a0dc4380ceae75c29450Johann */ 517bc9febe8749e98a3812a0dc4380ceae75c29450Johann public enum SocketType { 527bc9febe8749e98a3812a0dc4380ceae75c29450Johann DEFAULT(getConscryptServerSocketFactory(false)), 537bc9febe8749e98a3812a0dc4380ceae75c29450Johann ENGINE(getConscryptServerSocketFactory(true)); 547bc9febe8749e98a3812a0dc4380ceae75c29450Johann 557bc9febe8749e98a3812a0dc4380ceae75c29450Johann @SuppressWarnings("ImmutableEnumChecker") 567bc9febe8749e98a3812a0dc4380ceae75c29450Johann private final SSLServerSocketFactory serverSocketFactory; 577bc9febe8749e98a3812a0dc4380ceae75c29450Johann 587bc9febe8749e98a3812a0dc4380ceae75c29450Johann SocketType(SSLServerSocketFactory serverSocketFactory) { 597bc9febe8749e98a3812a0dc4380ceae75c29450Johann this.serverSocketFactory = serverSocketFactory; 607bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 617bc9febe8749e98a3812a0dc4380ceae75c29450Johann 627bc9febe8749e98a3812a0dc4380ceae75c29450Johann final SSLServerSocket newServerSocket(String cipher) { 637bc9febe8749e98a3812a0dc4380ceae75c29450Johann try { 647bc9febe8749e98a3812a0dc4380ceae75c29450Johann int port = pickUnusedPort(); 657bc9febe8749e98a3812a0dc4380ceae75c29450Johann SSLServerSocket sslSocket = 667bc9febe8749e98a3812a0dc4380ceae75c29450Johann (SSLServerSocket) serverSocketFactory.createServerSocket(port); 677bc9febe8749e98a3812a0dc4380ceae75c29450Johann sslSocket.setEnabledProtocols(getProtocols()); 687bc9febe8749e98a3812a0dc4380ceae75c29450Johann sslSocket.setEnabledCipherSuites(new String[] {cipher}); 697bc9febe8749e98a3812a0dc4380ceae75c29450Johann return sslSocket; 70da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } catch (IOException e) { 71da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian throw new RuntimeException(e); 72da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 737bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 747bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 757bc9febe8749e98a3812a0dc4380ceae75c29450Johann 76da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian @Parameters(name = "{0}") 77da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian public static Iterable<SocketType> data() { 78da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Android-changed: Temporarily (2017 Q2) disable ENGINE tests. http://b/37271061#comment9 79da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // This experimental (unused by default) implementation is unstable and causing test 80da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // failures on Android. 81da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // return Arrays.asList(SocketType.DEFAULT, SocketType.ENGINE); 82da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian return Arrays.asList(SocketType.DEFAULT); 83da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 84da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 857bc9febe8749e98a3812a0dc4380ceae75c29450Johann @Parameter public SocketType socketType; 867bc9febe8749e98a3812a0dc4380ceae75c29450Johann 877bc9febe8749e98a3812a0dc4380ceae75c29450Johann private TestClient client; 887bc9febe8749e98a3812a0dc4380ceae75c29450Johann private TestServer server; 897bc9febe8749e98a3812a0dc4380ceae75c29450Johann 907bc9febe8749e98a3812a0dc4380ceae75c29450Johann @Before 917bc9febe8749e98a3812a0dc4380ceae75c29450Johann public void setup() throws Exception { 927bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Create and start the server. 93da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian server = new TestServer(socketType.newServerSocket(CIPHER), MESSAGE_SIZE); 94da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian Future<?> connectedFuture = server.start(); 95da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 96da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Create and start the client. 97da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SSLSocketFactory socketFactory = getJdkSocketFactory(); 98da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SSLSocket socket = (SSLSocket) socketFactory.createSocket(LOCALHOST, server.port()); 99da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian socket.setEnabledProtocols(getProtocols()); 100da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian socket.setEnabledCipherSuites(new String[] {CIPHER}); 101da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian client = new TestClient(socket); 102da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian client.start(); 103da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 104da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Wait for the initial connection to complete. 105da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian connectedFuture.get(5, TimeUnit.SECONDS); 106da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 107da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 108da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian @After 109da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian public void teardown() throws Exception { 110da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian client.stop(); 111da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian server.stop(); 112da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 113da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 114da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian @Test 115da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian public void pingPong() throws IOException { 116da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian byte[] request = newTextMessage(MESSAGE_SIZE); 117da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian byte[] responseBuffer = new byte[MESSAGE_SIZE]; 118da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian client.sendMessage(request); 119da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian client.flush(); 120da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int numBytes = client.readMessage(responseBuffer); 121da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian byte[] response = Arrays.copyOfRange(responseBuffer, 0, numBytes); 122da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian assertArrayEquals(request, response); 123da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 124da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian} 125da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian