blob: 621f299e94582748a6be73664a210540ace0c8b9 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package libcore.javax.net.ssl;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Arrays;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLProtocolException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import junit.framework.TestCase;
import libcore.java.security.StandardNames;
import libcore.java.security.TestKeyStore;
public class SSLSocketTest extends TestCase {
public void test_SSLSocket_getSupportedCipherSuites_names() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] cipherSuites = ssl.getSupportedCipherSuites();
StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
assertNotSame(cipherSuites, ssl.getSupportedCipherSuites());
}
public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
// note the rare usage of DSA keys here in addition to RSA
TestKeyStore testKeyStore = TestKeyStore.create(new String[] { "RSA", "DSA" },
null,
null,
"rsa-dsa",
TestKeyStore.localhost(),
true,
null);
if (StandardNames.IS_RI) {
test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
StandardNames.JSSE_PROVIDER_NAME,
StandardNames.JSSE_PROVIDER_NAME);
} else {
test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
"HarmonyJSSE",
"HarmonyJSSE");
test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
"AndroidOpenSSL",
"AndroidOpenSSL");
test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
"HarmonyJSSE",
"AndroidOpenSSL");
test_SSLSocket_getSupportedCipherSuites_connect(testKeyStore,
"AndroidOpenSSL",
"HarmonyJSSE");
}
}
private void test_SSLSocket_getSupportedCipherSuites_connect(TestKeyStore testKeyStore,
String clientProvider,
String serverProvider)
throws Exception {
String clientToServerString = "this is sent from the client to the server...";
String serverToClientString = "... and this from the server to the client";
byte[] clientToServer = clientToServerString.getBytes();
byte[] serverToClient = serverToClientString.getBytes();
TestSSLContext c = TestSSLContext.create(testKeyStore, testKeyStore,
clientProvider, serverProvider);
String[] cipherSuites = c.clientContext.getSocketFactory().getSupportedCipherSuites();
for (String cipherSuite : cipherSuites) {
/*
* Kerberos cipher suites require external setup. See "Kerberos Requirements" in
* https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#KRBRequire
*/
if (cipherSuite.startsWith("TLS_KRB5_")) {
continue;
}
// System.out.println("Trying to connect cipher suite " + cipherSuite
// + " client=" + clientProvider
// + " server=" + serverProvider);
String[] cipherSuiteArray = new String[] { cipherSuite };
SSLSocket[] pair = TestSSLSocketPair.connect(c, cipherSuiteArray, cipherSuiteArray);
SSLSocket server = pair[0];
SSLSocket client = pair[1];
server.getOutputStream().write(serverToClient);
client.getOutputStream().write(clientToServer);
// arrays are too big to make sure we get back only what we expect
byte[] clientFromServer = new byte[serverToClient.length+1];
byte[] serverFromClient = new byte[clientToServer.length+1];
int readFromServer = client.getInputStream().read(clientFromServer);
int readFromClient = server.getInputStream().read(serverFromClient);
assertEquals(serverToClient.length, readFromServer);
assertEquals(clientToServer.length, readFromClient);
assertEquals(clientToServerString, new String(serverFromClient, 0, readFromClient));
assertEquals(serverToClientString, new String(clientFromServer, 0, readFromServer));
server.close();
client.close();
}
}
public void test_SSLSocket_getEnabledCipherSuites() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] cipherSuites = ssl.getEnabledCipherSuites();
StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
}
public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
try {
ssl.setEnabledCipherSuites(null);
fail();
} catch (IllegalArgumentException expected) {
}
try {
ssl.setEnabledCipherSuites(new String[1]);
fail();
} catch (IllegalArgumentException expected) {
}
try {
ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
fail();
} catch (IllegalArgumentException expected) {
}
ssl.setEnabledCipherSuites(new String[0]);
ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
}
public void test_SSLSocket_getSupportedProtocols() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] protocols = ssl.getSupportedProtocols();
StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
assertNotSame(protocols, ssl.getSupportedProtocols());
}
public void test_SSLSocket_getEnabledProtocols() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] protocols = ssl.getEnabledProtocols();
StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
assertNotSame(protocols, ssl.getEnabledProtocols());
}
public void test_SSLSocket_setEnabledProtocols() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
try {
ssl.setEnabledProtocols(null);
fail();
} catch (IllegalArgumentException expected) {
}
try {
ssl.setEnabledProtocols(new String[1]);
fail();
} catch (IllegalArgumentException expected) {
}
try {
ssl.setEnabledProtocols(new String[] { "Bogus" } );
fail();
} catch (IllegalArgumentException expected) {
}
ssl.setEnabledProtocols(new String[0]);
ssl.setEnabledProtocols(ssl.getEnabledProtocols());
ssl.setEnabledProtocols(ssl.getSupportedProtocols());
}
public void test_SSLSocket_getSession() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
SSLSession session = ssl.getSession();
assertNotNull(session);
assertFalse(session.isValid());
}
public void test_SSLSocket_startHandshake() throws Exception {
final TestSSLContext c = TestSSLContext.create();
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
server.startHandshake();
assertNotNull(server.getSession());
try {
server.getSession().getPeerCertificates();
fail();
} catch (SSLPeerUnverifiedException expected) {
}
Certificate[] localCertificates = server.getSession().getLocalCertificates();
assertNotNull(localCertificates);
TestKeyStore.assertChainLength(localCertificates);
assertNotNull(localCertificates[0]);
TestSSLContext.assertServerCertificateChain(c.serverTrustManager,
localCertificates);
TestSSLContext.assertCertificateInKeyStore(localCertificates[0],
c.serverKeyStore);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
client.startHandshake();
assertNotNull(client.getSession());
assertNull(client.getSession().getLocalCertificates());
Certificate[] peerCertificates = client.getSession().getPeerCertificates();
assertNotNull(peerCertificates);
TestKeyStore.assertChainLength(peerCertificates);
assertNotNull(peerCertificates[0]);
TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
peerCertificates);
TestSSLContext.assertCertificateInKeyStore(peerCertificates[0], c.serverKeyStore);
thread.join();
}
public void test_SSLSocket_startHandshake_noKeyStore() throws Exception {
TestSSLContext c = TestSSLContext.create(null, null, null, null, null, null, null, null,
SSLContext.getDefault(), SSLContext.getDefault());
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
try {
SSLSocket server = (SSLSocket) c.serverSocket.accept();
fail();
} catch (SSLException expected) {
}
}
public void test_SSLSocket_startHandshake_noClientCertificate() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLContext serverContext = c.serverContext;
SSLContext clientContext = c.clientContext;
SSLSocket client = (SSLSocket)
clientContext.getSocketFactory().createSocket(c.host, c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
server.startHandshake();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
client.startHandshake();
thread.join();
}
public void test_SSLSocket_HandshakeCompletedListener() throws Exception {
final TestSSLContext c = TestSSLContext.create();
final SSLSocket client = (SSLSocket)
c.clientContext.getSocketFactory().createSocket(c.host, c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
server.startHandshake();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
final boolean[] handshakeCompletedListenerCalled = new boolean[1];
client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
public void handshakeCompleted(HandshakeCompletedEvent event) {
try {
SSLSession session = event.getSession();
String cipherSuite = event.getCipherSuite();
Certificate[] localCertificates = event.getLocalCertificates();
Certificate[] peerCertificates = event.getPeerCertificates();
javax.security.cert.X509Certificate[] peerCertificateChain
= event.getPeerCertificateChain();
Principal peerPrincipal = event.getPeerPrincipal();
Principal localPrincipal = event.getLocalPrincipal();
Socket socket = event.getSocket();
if (false) {
System.out.println("Session=" + session);
System.out.println("CipherSuite=" + cipherSuite);
System.out.println("LocalCertificates=" + localCertificates);
System.out.println("PeerCertificates=" + peerCertificates);
System.out.println("PeerCertificateChain=" + peerCertificateChain);
System.out.println("PeerPrincipal=" + peerPrincipal);
System.out.println("LocalPrincipal=" + localPrincipal);
System.out.println("Socket=" + socket);
}
assertNotNull(session);
byte[] id = session.getId();
assertNotNull(id);
assertEquals(32, id.length);
assertNotNull(c.clientContext.getClientSessionContext().getSession(id));
assertNotNull(cipherSuite);
assertTrue(Arrays.asList(
client.getEnabledCipherSuites()).contains(cipherSuite));
assertTrue(Arrays.asList(
c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
assertNull(localCertificates);
assertNotNull(peerCertificates);
TestKeyStore.assertChainLength(peerCertificates);
assertNotNull(peerCertificates[0]);
TestSSLContext.assertServerCertificateChain(c.clientTrustManager,
peerCertificates);
TestSSLContext.assertCertificateInKeyStore(peerCertificates[0],
c.serverKeyStore);
assertNotNull(peerCertificateChain);
TestKeyStore.assertChainLength(peerCertificateChain);
assertNotNull(peerCertificateChain[0]);
TestSSLContext.assertCertificateInKeyStore(
peerCertificateChain[0].getSubjectDN(), c.serverKeyStore);
assertNotNull(peerPrincipal);
TestSSLContext.assertCertificateInKeyStore(peerPrincipal, c.serverKeyStore);
assertNull(localPrincipal);
assertNotNull(socket);
assertSame(client, socket);
synchronized (handshakeCompletedListenerCalled) {
handshakeCompletedListenerCalled[0] = true;
handshakeCompletedListenerCalled.notify();
}
handshakeCompletedListenerCalled[0] = true;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
client.startHandshake();
thread.join();
if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
assertNotNull(c.serverContext.getServerSessionContext().getSession(
client.getSession().getId()));
}
synchronized (handshakeCompletedListenerCalled) {
while (!handshakeCompletedListenerCalled[0]) {
handshakeCompletedListenerCalled.wait();
}
}
}
public void test_SSLSocket_HandshakeCompletedListener_RuntimeException() throws Exception {
final TestSSLContext c = TestSSLContext.create();
final SSLSocket client = (SSLSocket)
c.clientContext.getSocketFactory().createSocket(c.host, c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
server.startHandshake();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
public void handshakeCompleted(HandshakeCompletedEvent event) {
throw new RuntimeException("RuntimeException from handshakeCompleted");
}
});
client.startHandshake();
thread.join();
}
public void test_SSLSocket_getUseClientMode() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
SSLSocket server = (SSLSocket) c.serverSocket.accept();
assertTrue(client.getUseClientMode());
assertFalse(server.getUseClientMode());
}
public void test_SSLSocket_setUseClientMode() throws Exception {
// client is client, server is server
test_SSLSocket_setUseClientMode(true, false);
// client is server, server is client
test_SSLSocket_setUseClientMode(true, false);
// both are client
try {
test_SSLSocket_setUseClientMode(true, true);
fail();
} catch (SSLProtocolException expected) {
}
// both are server
try {
test_SSLSocket_setUseClientMode(false, false);
fail();
} catch (SocketTimeoutException expected) {
}
}
public void test_SSLSocket_setUseClientMode_afterHandshake() throws Exception {
// can't set after handshake
TestSSLEnginePair pair = TestSSLEnginePair.create(null);
try {
pair.server.setUseClientMode(false);
fail();
} catch (IllegalArgumentException expected) {
}
try {
pair.client.setUseClientMode(false);
fail();
} catch (IllegalArgumentException expected) {
}
}
private void test_SSLSocket_setUseClientMode(final boolean clientClientMode,
final boolean serverClientMode)
throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
final SSLProtocolException[] sslProtocolException = new SSLProtocolException[1];
final SocketTimeoutException[] socketTimeoutException = new SocketTimeoutException[1];
Thread thread = new Thread(new Runnable () {
public void run() {
try {
if (!serverClientMode) {
server.setSoTimeout(1 * 1000);
}
server.setUseClientMode(serverClientMode);
server.startHandshake();
} catch (SSLProtocolException e) {
sslProtocolException[0] = e;
} catch (SocketTimeoutException e) {
socketTimeoutException[0] = e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
if (!clientClientMode) {
client.setSoTimeout(1 * 1000);
}
client.setUseClientMode(clientClientMode);
client.startHandshake();
thread.join();
if (sslProtocolException[0] != null) {
throw sslProtocolException[0];
}
if (socketTimeoutException[0] != null) {
throw socketTimeoutException[0];
}
}
public void test_SSLSocket_untrustedServer() throws Exception {
TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCA2(),
TestKeyStore.getServer());
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
server.startHandshake();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
try {
client.startHandshake();
fail();
} catch (SSLHandshakeException expected) {
assertTrue(expected.getCause() instanceof CertificateException);
}
thread.join();
}
public void test_SSLSocket_clientAuth() throws Exception {
TestSSLContext c = TestSSLContext.create(TestKeyStore.getClientCertificate(),
TestKeyStore.getServer());
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
assertFalse(server.getWantClientAuth());
assertFalse(server.getNeedClientAuth());
// confirm turning one on by itself
server.setWantClientAuth(true);
assertTrue(server.getWantClientAuth());
assertFalse(server.getNeedClientAuth());
// confirm turning setting on toggles the other
server.setNeedClientAuth(true);
assertFalse(server.getWantClientAuth());
assertTrue(server.getNeedClientAuth());
// confirm toggling back
server.setWantClientAuth(true);
assertTrue(server.getWantClientAuth());
assertFalse(server.getNeedClientAuth());
server.startHandshake();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
client.startHandshake();
assertNotNull(client.getSession().getLocalCertificates());
TestKeyStore.assertChainLength(client.getSession().getLocalCertificates());
TestSSLContext.assertClientCertificateChain(c.clientTrustManager,
client.getSession().getLocalCertificates());
thread.join();
}
public void test_SSLSocket_getEnableSessionCreation() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
SSLSocket server = (SSLSocket) c.serverSocket.accept();
assertTrue(client.getEnableSessionCreation());
assertTrue(server.getEnableSessionCreation());
}
public void test_SSLSocket_setEnableSessionCreation_server() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
server.setEnableSessionCreation(false);
try {
server.startHandshake();
fail();
} catch (SSLException expected) {
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
try {
client.startHandshake();
fail();
} catch (SSLException expected) {
}
thread.join();
}
public void test_SSLSocket_setEnableSessionCreation_client() throws Exception {
TestSSLContext c = TestSSLContext.create();
SSLSocket client = (SSLSocket) c.clientContext.getSocketFactory().createSocket(c.host,
c.port);
final SSLSocket server = (SSLSocket) c.serverSocket.accept();
Thread thread = new Thread(new Runnable () {
public void run() {
try {
try {
server.startHandshake();
fail();
} catch (SSLException expected) {
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
thread.start();
client.setEnableSessionCreation(false);
try {
client.startHandshake();
fail();
} catch (SSLException expected) {
}
thread.join();
}
public void test_SSLSocket_getSSLParameters() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
SSLParameters p = ssl.getSSLParameters();
assertNotNull(p);
String[] cipherSuites = p.getCipherSuites();
StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
String[] protocols = p.getProtocols();
StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
assertNotSame(protocols, ssl.getEnabledProtocols());
assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
}
public void test_SSLSocket_setSSLParameters() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
String[] defaultProtocols = ssl.getEnabledProtocols();
String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
String[] supportedProtocols = ssl.getSupportedProtocols();
{
SSLParameters p = new SSLParameters();
ssl.setSSLParameters(p);
assertEquals(Arrays.asList(defaultCipherSuites),
Arrays.asList(ssl.getEnabledCipherSuites()));
assertEquals(Arrays.asList(defaultProtocols),
Arrays.asList(ssl.getEnabledProtocols()));
}
{
SSLParameters p = new SSLParameters(supportedCipherSuites,
supportedProtocols);
ssl.setSSLParameters(p);
assertEquals(Arrays.asList(supportedCipherSuites),
Arrays.asList(ssl.getEnabledCipherSuites()));
assertEquals(Arrays.asList(supportedProtocols),
Arrays.asList(ssl.getEnabledProtocols()));
}
{
SSLParameters p = new SSLParameters();
p.setNeedClientAuth(true);
assertFalse(ssl.getNeedClientAuth());
assertFalse(ssl.getWantClientAuth());
ssl.setSSLParameters(p);
assertTrue(ssl.getNeedClientAuth());
assertFalse(ssl.getWantClientAuth());
p.setWantClientAuth(true);
assertTrue(ssl.getNeedClientAuth());
assertFalse(ssl.getWantClientAuth());
ssl.setSSLParameters(p);
assertFalse(ssl.getNeedClientAuth());
assertTrue(ssl.getWantClientAuth());
p.setWantClientAuth(false);
assertFalse(ssl.getNeedClientAuth());
assertTrue(ssl.getWantClientAuth());
ssl.setSSLParameters(p);
assertFalse(ssl.getNeedClientAuth());
assertFalse(ssl.getWantClientAuth());
}
}
public void test_SSLSocket_close() throws Exception {
TestSSLSocketPair pair = TestSSLSocketPair.create();
SSLSocket server = pair.server;
SSLSocket client = pair.client;
assertFalse(server.isClosed());
assertFalse(client.isClosed());
InputStream input = client.getInputStream();
OutputStream output = client.getOutputStream();
server.close();
client.close();
assertTrue(server.isClosed());
assertTrue(client.isClosed());
// close after close is okay...
server.close();
client.close();
// ...so are a lot of other operations...
HandshakeCompletedListener l = new HandshakeCompletedListener () {
public void handshakeCompleted(HandshakeCompletedEvent e) {}
};
client.addHandshakeCompletedListener(l);
assertNotNull(client.getEnabledCipherSuites());
assertNotNull(client.getEnabledProtocols());
client.getEnableSessionCreation();
client.getNeedClientAuth();
assertNotNull(client.getSession());
assertNotNull(client.getSSLParameters());
assertNotNull(client.getSupportedProtocols());
client.getUseClientMode();
client.getWantClientAuth();
client.removeHandshakeCompletedListener(l);
client.setEnabledCipherSuites(new String[0]);
client.setEnabledProtocols(new String[0]);
client.setEnableSessionCreation(false);
client.setNeedClientAuth(false);
client.setSSLParameters(client.getSSLParameters());
client.setWantClientAuth(false);
// ...but some operations are expected to give SocketException...
try {
client.startHandshake();
fail();
} catch (SocketException expected) {
}
try {
client.getInputStream();
fail();
} catch (SocketException expected) {
}
try {
client.getOutputStream();
fail();
} catch (SocketException expected) {
}
try {
input.read();
fail();
} catch (SocketException expected) {
}
try {
input.read(null, -1, -1);
fail();
} catch (SocketException expected) {
}
try {
output.write(-1);
fail();
} catch (SocketException expected) {
}
try {
output.write(null, -1, -1);
fail();
} catch (SocketException expected) {
}
// ... and one gives IllegalArgumentException
try {
client.setUseClientMode(false);
fail();
} catch (IllegalArgumentException expected) {
}
}
/**
* b/3350645 Test to confirm that an SSLSocket.close() performing
* an SSL_shutdown does not throw an IOException if the peer
* socket has been closed.
*/
public void test_SSLSocket_shutdownCloseOnClosedPeer() throws Exception {
TestSSLContext c = TestSSLContext.create();
final Socket underlying = new Socket(c.host, c.port);
final SSLSocket wrapping = (SSLSocket)
c.clientContext.getSocketFactory().createSocket(underlying,
c.host.getHostName(),
c.port,
false);
Thread clientThread = new Thread(new Runnable () {
public void run() {
try {
try {
wrapping.startHandshake();
wrapping.getOutputStream().write(42);
// close the underlying socket,
// so that no SSL shutdown is sent
underlying.close();
wrapping.close();
} catch (SSLException expected) {
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
clientThread.start();
SSLSocket server = (SSLSocket) c.serverSocket.accept();
server.startHandshake();
server.getInputStream().read();
// wait for thread to finish so we know client is closed.
clientThread.join();
// close should cause an SSL_shutdown which will fail
// because the peer has closed, but it shouldn't throw.
server.close();
}
public void test_SSLSocket_setSoTimeout_basic() throws Exception {
ServerSocket listening = new ServerSocket(0);
Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
assertEquals(0, underlying.getSoTimeout());
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket wrapping = sf.createSocket(underlying, null, -1, false);
assertEquals(0, wrapping.getSoTimeout());
// setting wrapper sets underlying and ...
wrapping.setSoTimeout(10);
assertEquals(10, wrapping.getSoTimeout());
assertEquals(10, underlying.getSoTimeout());
// ... getting wrapper inspects underlying
underlying.setSoTimeout(0);
assertEquals(0, wrapping.getSoTimeout());
assertEquals(0, underlying.getSoTimeout());
}
public void test_SSLSocket_setSoTimeout_wrapper() throws Exception {
ServerSocket listening = new ServerSocket(0);
// setSoTimeout applies to read, not connect, so connect first
Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
Socket server = listening.accept();
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket clientWrapping = sf.createSocket(underlying, null, -1, false);
underlying.setSoTimeout(1);
try {
clientWrapping.getInputStream().read();
fail();
} catch (SocketTimeoutException expected) {
}
clientWrapping.close();
server.close();
underlying.close();
listening.close();
}
public void test_SSLSocket_interrupt() throws Exception {
ServerSocket listening = new ServerSocket(0);
for (int i = 0; i < 3; i++) {
Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort());
Socket server = listening.accept();
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket clientWrapping = sf.createSocket(underlying, null, -1, true);
switch (i) {
case 0:
test_SSLSocket_interrupt_case(underlying, underlying);
break;
case 1:
test_SSLSocket_interrupt_case(underlying, clientWrapping);
break;
case 2:
test_SSLSocket_interrupt_case(clientWrapping, underlying);
break;
case 3:
test_SSLSocket_interrupt_case(clientWrapping, clientWrapping);
break;
default:
fail();
}
server.close();
underlying.close();
}
listening.close();
}
private void test_SSLSocket_interrupt_case(Socket toRead, final Socket toClose)
throws Exception {
new Thread() {
@Override
public void run() {
try {
Thread.sleep(1 * 1000);
toClose.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}.start();
try {
toRead.setSoTimeout(5 * 1000);
toRead.getInputStream().read();
fail();
} catch (SocketTimeoutException e) {
throw e;
} catch (SocketException expected) {
}
}
public void test_TestSSLSocketPair_create() {
TestSSLSocketPair test = TestSSLSocketPair.create();
assertNotNull(test.c);
assertNotNull(test.server);
assertNotNull(test.client);
assertTrue(test.server.isConnected());
assertTrue(test.client.isConnected());
assertFalse(test.server.isClosed());
assertFalse(test.client.isClosed());
assertNotNull(test.server.getSession());
assertNotNull(test.client.getSession());
assertTrue(test.server.getSession().isValid());
assertTrue(test.client.getSession().isValid());
}
/**
* Not run by default by JUnit, but can be run by Vogar by
* specifying it explictly (or with main method below)
*/
public void stress_test_TestSSLSocketPair_create() {
final boolean verbose = true;
while (true) {
TestSSLSocketPair test = TestSSLSocketPair.create();
if (verbose) {
System.out.println("client=" + test.client.getLocalPort()
+ " server=" + test.server.getLocalPort());
} else {
System.out.print("X");
}
}
}
public static final void main (String[] args) {
new SSLSocketTest().stress_test_TestSSLSocketPair_create();
}
}