blob: 55ce3bba8c9feef4dc28a2086b026f7ba86e5d51 [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.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLSocket;
/**
* TestSSLSocketPair is a convenience class for other tests that want
* a pair of connected and handshaked client and server SSLSockets for
* testing.
*/
public final class TestSSLSocketPair {
public final TestSSLContext c;
public final SSLSocket server;
public final SSLSocket client;
private TestSSLSocketPair (TestSSLContext c,
SSLSocket server,
SSLSocket client) {
this.c = c;
this.server = server;
this.client = client;
}
public void close() {
c.close();
try {
server.close();
client.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* based on test_SSLSocket_startHandshake
*/
public static TestSSLSocketPair create () {
TestSSLContext c = TestSSLContext.create();
SSLSocket[] sockets = connect(c, null, null);
return new TestSSLSocketPair(c, sockets[0], sockets[1]);
}
/**
* Create a new connected server/client socket pair within a
* existing SSLContext. Optionally specify clientCipherSuites to
* allow forcing new SSLSession to test SSLSessionContext
* caching. Optionally specify serverCipherSuites for testing
* cipher suite negotiation.
*/
public static SSLSocket[] connect (final TestSSLContext context,
final String[] clientCipherSuites,
final String[] serverCipherSuites) {
try {
final SSLSocket client = (SSLSocket)
context.clientContext.getSocketFactory().createSocket(context.host, context.port);
final SSLSocket server = (SSLSocket) context.serverSocket.accept();
ExecutorService executor = Executors.newFixedThreadPool(2);
Future s = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
if (serverCipherSuites != null) {
server.setEnabledCipherSuites(serverCipherSuites);
}
server.startHandshake();
return null;
}
});
Future c = executor.submit(new Callable<Void>() {
public Void call() throws Exception {
if (clientCipherSuites != null) {
client.setEnabledCipherSuites(clientCipherSuites);
}
client.startHandshake();
return null;
}
});
executor.shutdown();
// catch client and server exceptions separately so we can
// potentially log both.
Exception serverException;
try {
s.get(30, TimeUnit.SECONDS);
serverException = null;
} catch (Exception e) {
serverException = e;
e.printStackTrace();
}
Exception clientException;
try {
c.get(30, TimeUnit.SECONDS);
clientException = null;
} catch (Exception e) {
clientException = e;
e.printStackTrace();
}
if (serverException != null) {
throw serverException;
}
if (clientException != null) {
throw clientException;
}
return new SSLSocket[] { server, client };
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}