1 /* 2 * Copyright 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.conscrypt; 18 19 import static org.conscrypt.TestUtils.LOCALHOST; 20 import static org.conscrypt.TestUtils.getConscryptServerSocketFactory; 21 import static org.conscrypt.TestUtils.getJdkSocketFactory; 22 import static org.conscrypt.TestUtils.getProtocols; 23 import static org.conscrypt.TestUtils.newTextMessage; 24 import static org.conscrypt.TestUtils.pickUnusedPort; 25 import static org.junit.Assert.assertArrayEquals; 26 27 import java.io.IOException; 28 import java.util.Arrays; 29 import java.util.concurrent.Future; 30 import java.util.concurrent.TimeUnit; 31 import javax.net.ssl.SSLServerSocket; 32 import javax.net.ssl.SSLServerSocketFactory; 33 import javax.net.ssl.SSLSocket; 34 import javax.net.ssl.SSLSocketFactory; 35 import org.junit.After; 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.junit.runners.Parameterized; 40 import org.junit.runners.Parameterized.Parameter; 41 import org.junit.runners.Parameterized.Parameters; 42 43 @RunWith(Parameterized.class) 44 public class OpenSSLServerSocketImplTest { 45 private static final String CIPHER = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; 46 private static final int MESSAGE_SIZE = 4096; 47 48 /** 49 * Various factories for SSL server sockets. 50 */ 51 public enum SocketType { 52 DEFAULT(getConscryptServerSocketFactory(false)), 53 ENGINE(getConscryptServerSocketFactory(true)); 54 55 @SuppressWarnings("ImmutableEnumChecker") 56 private final SSLServerSocketFactory serverSocketFactory; 57 SocketType(SSLServerSocketFactory serverSocketFactory)58 SocketType(SSLServerSocketFactory serverSocketFactory) { 59 this.serverSocketFactory = serverSocketFactory; 60 } 61 newServerSocket(String cipher)62 final SSLServerSocket newServerSocket(String cipher) { 63 try { 64 int port = pickUnusedPort(); 65 SSLServerSocket sslSocket = 66 (SSLServerSocket) serverSocketFactory.createServerSocket(port); 67 sslSocket.setEnabledProtocols(getProtocols()); 68 sslSocket.setEnabledCipherSuites(new String[] {cipher}); 69 return sslSocket; 70 } catch (IOException e) { 71 throw new RuntimeException(e); 72 } 73 } 74 } 75 76 @Parameters(name = "{0}") data()77 public static Iterable<SocketType> data() { 78 // Android-changed: Temporarily (2017 Q2) disable ENGINE tests. http://b/37271061#comment9 79 // This experimental (unused by default) implementation is unstable and causing test 80 // failures on Android. 81 // return Arrays.asList(SocketType.DEFAULT, SocketType.ENGINE); 82 return Arrays.asList(SocketType.DEFAULT); 83 } 84 85 @Parameter public SocketType socketType; 86 87 private TestClient client; 88 private TestServer server; 89 90 @Before setup()91 public void setup() throws Exception { 92 // Create and start the server. 93 server = new TestServer(socketType.newServerSocket(CIPHER), MESSAGE_SIZE); 94 Future<?> connectedFuture = server.start(); 95 96 // Create and start the client. 97 SSLSocketFactory socketFactory = getJdkSocketFactory(); 98 SSLSocket socket = (SSLSocket) socketFactory.createSocket(LOCALHOST, server.port()); 99 socket.setEnabledProtocols(getProtocols()); 100 socket.setEnabledCipherSuites(new String[] {CIPHER}); 101 client = new TestClient(socket); 102 client.start(); 103 104 // Wait for the initial connection to complete. 105 connectedFuture.get(5, TimeUnit.SECONDS); 106 } 107 108 @After teardown()109 public void teardown() throws Exception { 110 client.stop(); 111 server.stop(); 112 } 113 114 @Test pingPong()115 public void pingPong() throws IOException { 116 byte[] request = newTextMessage(MESSAGE_SIZE); 117 byte[] responseBuffer = new byte[MESSAGE_SIZE]; 118 client.sendMessage(request); 119 client.flush(); 120 int numBytes = client.readMessage(responseBuffer); 121 byte[] response = Arrays.copyOfRange(responseBuffer, 0, numBytes); 122 assertArrayEquals(request, response); 123 } 124 } 125