下面列出了怎么用javax.net.ssl.SSLSocket的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType,
Socket socket) throws CertificateException {
if (!option.isAuthPeer()) {
return;
}
String ip = null;
if (socket != null && socket.isConnected()
&& socket instanceof SSLSocket) {
InetAddress inetAddress = socket.getInetAddress();
if (inetAddress != null) {
ip = inetAddress.getHostAddress();
}
}
checkTrustedCustom(chain, ip);
trustManager.checkClientTrusted(chain, authType, socket);
}
/**
* Returns {@code true} if the socket, as currently configured, supports this connection spec. In
* order for a socket to be compatible the enabled cipher suites and protocols must intersect.
*
* <p>For cipher suites, at least one of the {@link #cipherSuites() required cipher suites} must
* match the socket's enabled cipher suites. If there are no required cipher suites the socket
* must have at least one cipher suite enabled.
*
* <p>For protocols, at least one of the {@link #tlsVersions() required protocols} must match the
* socket's enabled protocols.
*/
public boolean isCompatible(SSLSocket socket) {
if (!tls) {
return false;
}
if (tlsVersions != null && !nonEmptyIntersection(
Util.NATURAL_ORDER, tlsVersions, socket.getEnabledProtocols())) {
return false;
}
if (cipherSuites != null && !nonEmptyIntersection(
CipherSuite.ORDER_BY_NAME, cipherSuites, socket.getEnabledCipherSuites())) {
return false;
}
return true;
}
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();
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(new Callable<Void>() {
@Override public Void call() throws Exception {
server.startHandshake();
return null;
}
});
executor.shutdown();
client.startHandshake();
future.get();
client.close();
server.close();
c.close();
}
public static void main(String[] args) throws Exception {
try (Server server = new Server()) {
new Thread(server).start();
SocketFactory factory = SSLSocketFactory.getDefault();
try (SSLSocket socket = (SSLSocket) factory.createSocket("localhost",
server.getPort())) {
socket.setSoTimeout(2000);
System.out.println("Client established TCP connection");
boolean failed = false;
for (TestCase testCase : testCases) {
try {
testCase.test(socket);
System.out.println("ERROR: no exception");
failed = true;
} catch (IOException e) {
System.out.println("Failed as expected: " + e);
}
}
if (failed) {
throw new Exception("One or more tests failed");
}
}
}
}
public static void main(String[] args) throws Exception {
try (Server server = new Server()) {
new Thread(server).start();
SocketFactory factory = SSLSocketFactory.getDefault();
try (SSLSocket socket = (SSLSocket) factory.createSocket("localhost",
server.getPort())) {
socket.setSoTimeout(2000);
System.out.println("Client established TCP connection");
boolean failed = false;
for (TestCase testCase : testCases) {
try {
testCase.test(socket);
System.out.println("ERROR: no exception");
failed = true;
} catch (IOException e) {
System.out.println("Failed as expected: " + e);
}
}
if (failed) {
throw new Exception("One or more tests failed");
}
}
}
}
/**
* Returns the DN extracted from the peer certificate (the server DN if run on the client; the client DN (if available) if run on the server).
*
* If the client auth setting is WANT or NONE and a client certificate is not present, this method will return {@code null}.
* If the client auth is NEED, it will throw a {@link CertificateException}.
*
* @param socket the SSL Socket
* @return the extracted DN
* @throws CertificateException if there is a problem parsing the certificate
*/
public static String extractPeerDNFromSSLSocket(Socket socket) throws CertificateException {
String dn = null;
if (socket instanceof SSLSocket) {
final SSLSocket sslSocket = (SSLSocket) socket;
boolean clientMode = sslSocket.getUseClientMode();
logger.debug("SSL Socket in {} mode", clientMode ? "client" : "server");
ClientAuth clientAuth = getClientAuthStatus(sslSocket);
logger.debug("SSL Socket client auth status: {}", clientAuth);
if (clientMode) {
logger.debug("This socket is in client mode, so attempting to extract certificate from remote 'server' socket");
dn = extractPeerDNFromServerSSLSocket(sslSocket);
} else {
logger.debug("This socket is in server mode, so attempting to extract certificate from remote 'client' socket");
dn = extractPeerDNFromClientSSLSocket(sslSocket);
}
}
return dn;
}
@Test
public void noTLS() throws NoSuchAlgorithmException, IOException {
SdkTlsSocketFactory f = new SdkTlsSocketFactory(SSLContext.getDefault(), null);
try (SSLSocket socket = new TestSSLSocket() {
@Override
public String[] getSupportedProtocols() {
return shuffle(new String[] {"SSLv2Hello", "SSLv3"});
}
@Override
public String[] getEnabledProtocols() {
return new String[] {"SSLv3"};
}
@Override
public void setEnabledProtocols(String[] protocols) {
// For backward compatibility
assertTrue(Arrays.equals(protocols, new String[] {"SSLv3"}));
}
}) {
f.prepareSocket(socket);
}
}
public static void main(String[] args) throws Exception {
try (Server server = new Server()) {
new Thread(server).start();
SocketFactory factory = SSLSocketFactory.getDefault();
try (SSLSocket socket = (SSLSocket) factory.createSocket("localhost",
server.getPort())) {
socket.setSoTimeout(2000);
System.out.println("Client established TCP connection");
boolean failed = false;
for (TestCase testCase : testCases) {
try {
testCase.test(socket);
System.out.println("ERROR: no exception");
failed = true;
} catch (IOException e) {
System.out.println("Failed as expected: " + e);
}
}
if (failed) {
throw new Exception("One or more tests failed");
}
}
}
}
public static void printInfo(SSLSocket socket) {
System.out.println();
System.out.println("--- SSL Socket Info ---");
System.out.print(" SupportedProtocols : ");
printStringArray(socket.getSupportedProtocols());
System.out.println(" EnabledProtocols : "
+ socket.getEnabledProtocols()[0]);
System.out.print(" SupportedCipherSuites : ");
String[] supportedCipherSuites = socket.getEnabledCipherSuites();
Arrays.sort(supportedCipherSuites);
printStringArray(supportedCipherSuites);
System.out.println(" EnabledCipherSuites : "
+ socket.getEnabledCipherSuites()[0]);
System.out.println(" NeedClientAuth : "
+ socket.getNeedClientAuth());
System.out.println(" WantClientAuth : "
+ socket.getWantClientAuth());
System.out.println("-----------------------");
}
public Entry(URI uri, RawHeaders varyHeaders, HttpURLConnection httpConnection)
throws IOException {
this.uri = uri.toString();
this.varyHeaders = varyHeaders;
this.requestMethod = httpConnection.getRequestMethod();
this.responseHeaders = RawHeaders.fromMultimap(httpConnection.getHeaderFields(), true);
SSLSocket sslSocket = getSslSocket(httpConnection);
if (sslSocket != null) {
cipherSuite = sslSocket.getSession().getCipherSuite();
Certificate[] peerCertificatesNonFinal = null;
try {
peerCertificatesNonFinal = sslSocket.getSession().getPeerCertificates();
} catch (SSLPeerUnverifiedException ignored) {
}
peerCertificates = peerCertificatesNonFinal;
localCertificates = sslSocket.getSession().getLocalCertificates();
} else {
cipherSuite = null;
peerCertificates = null;
localCertificates = null;
}
}
/**
* Configure ssl socket.
*
* @param socket
* the socket
* @return the socket
*/
private Socket configureSSLSocket(Socket socket) {
if (socket != null) {
if (this.properties == null) {
this.properties = new Properties();
}
boolean setEnabledProtocols = RpcPropertyDefs.getPropertyAsBoolean(properties,
RpcPropertyDefs.RPC_SECURE_SOCKET_SET_ENABLED_PROTOCOLS_NICK,
RpcPropertyDefs.RPC_DEFAULT_SECURE_SOCKET_SET_ENABLED_PROTOCOLS);
if (setEnabledProtocols) {
String[] enabledProtocols = RpcPropertyDefs.getProperty(properties,
RpcPropertyDefs.RPC_SECURE_SOCKET_ENABLED_PROTOCOLS_NICK,
RpcPropertyDefs.RPC_DEFAULT_SECURE_SOCKET_ENABLED_PROTOCOLS).split("\\s*,\\s*");
((SSLSocket)socket).setEnabledProtocols(enabledProtocols);
}
}
return socket;
}
/**
* @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
* java.lang.String, int, java.net.InetAddress, int,
* org.apache.http.params.HttpParams)
*/
public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params)
throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
// we need to bind explicitly
if (localPort < 0) {
localPort = 0; // indicates "any"
}
InetSocketAddress isa = new InetSocketAddress(localAddress,
localPort);
sslsock.bind(isa);
}
sslsock.connect(remoteAddress, connTimeout);
sslsock.setSoTimeout(soTimeout);
return sslsock;
}
/**
* <p>Creates a server socket that accepts SSL connections
* configured according to this factory's SSL socket configuration
* parameters.</p>
*/
public ServerSocket createServerSocket(int port) throws IOException {
final SSLSocketFactory sslSocketFactory =
context == null ?
getDefaultSSLSocketFactory() : context.getSocketFactory();
return new ServerSocket(port) {
public Socket accept() throws IOException {
Socket socket = super.accept();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
socket, socket.getInetAddress().getHostName(),
socket.getPort(), true);
sslSocket.setUseClientMode(false);
if (enabledCipherSuites != null) {
sslSocket.setEnabledCipherSuites(enabledCipherSuites);
}
if (enabledProtocols != null) {
sslSocket.setEnabledProtocols(enabledProtocols);
}
sslSocket.setNeedClientAuth(needClientAuth);
return sslSocket;
}
};
}
public Entry(URI uri, RawHeaders varyHeaders, HttpURLConnection httpConnection)
throws IOException {
this.uri = uri.toString();
this.varyHeaders = varyHeaders;
this.requestMethod = httpConnection.getRequestMethod();
this.responseHeaders = RawHeaders.fromMultimap(httpConnection.getHeaderFields(), true);
SSLSocket sslSocket = getSslSocket(httpConnection);
if (sslSocket != null) {
cipherSuite = sslSocket.getSession().getCipherSuite();
Certificate[] peerCertificatesNonFinal = null;
try {
peerCertificatesNonFinal = sslSocket.getSession().getPeerCertificates();
} catch (SSLPeerUnverifiedException ignored) {
}
peerCertificates = peerCertificatesNonFinal;
localCertificates = sslSocket.getSession().getLocalCertificates();
} else {
cipherSuite = null;
peerCertificates = null;
localCertificates = null;
}
}
public Entry(URI uri, RawHeaders varyHeaders, HttpURLConnection httpConnection)
throws IOException {
this.uri = uri.toString();
this.varyHeaders = varyHeaders;
this.requestMethod = httpConnection.getRequestMethod();
this.responseHeaders = RawHeaders.fromMultimap(httpConnection.getHeaderFields(), true);
SSLSocket sslSocket = getSslSocket(httpConnection);
if (sslSocket != null) {
cipherSuite = sslSocket.getSession().getCipherSuite();
Certificate[] peerCertificatesNonFinal = null;
try {
peerCertificatesNonFinal = sslSocket.getSession().getPeerCertificates();
} catch (SSLPeerUnverifiedException ignored) {
}
peerCertificates = peerCertificatesNonFinal;
localCertificates = sslSocket.getSession().getLocalCertificates();
} else {
cipherSuite = null;
peerCertificates = null;
localCertificates = null;
}
}
/**
* 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);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> clientFuture = executor.submit(new Callable<Void>() {
@Override public Void call() throws Exception {
wrapping.startHandshake();
wrapping.getOutputStream().write(42);
// close the underlying socket,
// so that no SSL shutdown is sent
underlying.close();
wrapping.close();
return null;
}
});
executor.shutdown();
SSLSocket server = (SSLSocket) c.serverSocket.accept();
server.startHandshake();
server.getInputStream().read();
// wait for thread to finish so we know client is closed.
clientFuture.get();
// close should cause an SSL_shutdown which will fail
// because the peer has closed, but it shouldn't throw.
server.close();
}
/**
* javax.net.ssl.SSLSocket#getSupportedCipherSuites()
*/
public void j2objcNotImplemented_test_getSupportedCipherSuites() throws IOException {
SSLSocket ssl = getSSLSocket();
String[] res = ssl.getSupportedCipherSuites();
assertTrue("no supported cipher suites", res.length > 0);
ssl.close();
}
public NoSSLv3SSLSocket(SSLSocket socket) {
super(socket);
try {
socket.getClass().getMethod("setUseSessionTickets", boolean.class).invoke(socket, true);
} catch (Exception e) {
// Reflective operation, ignore exception
}
}
/**
* Configures the supplied {@link SSLSocket} to connect to the specified host using an appropriate
* {@link ConnectionSpec}. Returns the chosen {@link ConnectionSpec}, never {@code null}.
*
* @throws IOException if the socket does not support any of the TLS modes available
*/
public ConnectionSpec configureSecureSocket(SSLSocket sslSocket) throws IOException {
ConnectionSpec tlsConfiguration = null;
for (int i = nextModeIndex, size = connectionSpecs.size(); i < size; i++) {
ConnectionSpec connectionSpec = connectionSpecs.get(i);
if (connectionSpec.isCompatible(sslSocket)) {
tlsConfiguration = connectionSpec;
nextModeIndex = i + 1;
break;
}
}
if (tlsConfiguration == null) {
// This may be the first time a connection has been attempted and the socket does not support
// any the required protocols, or it may be a retry (but this socket supports fewer
// protocols than was suggested by a prior socket).
throw new UnknownServiceException(
"Unable to find acceptable protocols. isFallback=" + isFallback
+ ", modes=" + connectionSpecs
+ ", supported protocols=" + Arrays.toString(sslSocket.getEnabledProtocols()));
}
isFallbackPossible = isFallbackPossible(sslSocket);
Internal.instance.apply(tlsConfiguration, sslSocket, isFallback);
return tlsConfiguration;
}
@Override public Principal getLocalPrincipal() {
SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
if (cacheResponse != null) {
return cacheResponse.getLocalPrincipal();
}
SSLSocket sslSocket = getSslSocket();
if (sslSocket != null) {
return sslSocket.getSession().getLocalPrincipal();
}
return null;
}
@Override
public synchronized Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress,
InetSocketAddress localAddress, HttpContext context) throws IOException {
Socket result = super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context);
if (!SSLSocket.class.isInstance(result)) {
throw new IOException("Expected tls socket");
}
SSLSocket sslSocket = (SSLSocket) result;
java.security.cert.Certificate[] peerCertificateChain = sslSocket.getSession().getPeerCertificates();
if (peerCertificateChain.length != 1) {
throw new IOException("Expected root ca cert");
}
if (!X509Certificate.class.isInstance(peerCertificateChain[0])) {
throw new IOException("Expected root ca cert in X509 format");
}
String cn;
try {
X509Certificate certificate = (X509Certificate) peerCertificateChain[0];
cn = IETFUtils.valueToString(new JcaX509CertificateHolder(certificate).getSubject().getRDNs(BCStyle.CN)[0].getFirst().getValue());
certificates.add(certificate);
} catch (Exception e) {
throw new IOException(e);
}
if (!caHostname.equals(cn)) {
throw new IOException("Expected cn of " + caHostname + " but got " + cn);
}
return result;
}
@Test
public void negotiate_success() throws Exception {
when(platform.getSelectedProtocol(Mockito.<SSLSocket>any())).thenReturn("h2");
OkHttpProtocolNegotiator negotiator = new OkHttpProtocolNegotiator(platform);
String actual = negotiator.negotiate(sock, "hostname", ImmutableList.of(Protocol.HTTP_2));
assertEquals("h2", actual);
verify(sock).startHandshake();
verify(platform).getSelectedProtocol(sock);
verify(platform).afterHandshake(sock);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
Socket socket = mBase.createSocket(address, port,
localAddress, localPort);
limitProtocolsAndCiphers((SSLSocket) socket);
return socket;
}
private String[] getCiphers(SSLSocket sslSocket) {
String[] ciphers = sslSocket.getEnabledCipherSuites();
List<String> enabledCiphers = new ArrayList(Arrays.asList(ciphers));
// On Android 5.0 release, Jetty doesn't seem to play nice with these ciphers
// Issue seems to have been fixed in M, and now won't work without them. Because Google
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
enabledCiphers.remove("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
enabledCiphers.remove("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
}
ciphers = enabledCiphers.toArray(new String[enabledCiphers.size()]);
return ciphers;
}
/**
* Returns a copy of this that omits cipher suites and TLS versions not enabled by
* {@code sslSocket}.
*/
private ConnectionSpec supportedSpec(SSLSocket sslSocket, boolean isFallback) {
String[] cipherSuitesToEnable = null;
if (cipherSuites != null) {
String[] cipherSuitesToSelectFrom = sslSocket.getEnabledCipherSuites();
cipherSuitesToEnable =
Util.intersect(String.class, cipherSuites, cipherSuitesToSelectFrom);
}
if (isFallback) {
// In accordance with https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
// the SCSV cipher is added to signal that a protocol fallback has taken place.
final String fallbackScsv = "TLS_FALLBACK_SCSV";
boolean socketSupportsFallbackScsv =
Arrays.asList(sslSocket.getSupportedCipherSuites()).contains(fallbackScsv);
if (socketSupportsFallbackScsv) {
// Add the SCSV cipher to the set of enabled cipher suites iff it is supported.
String[] oldEnabledCipherSuites = cipherSuitesToEnable != null
? cipherSuitesToEnable
: sslSocket.getEnabledCipherSuites();
String[] newEnabledCipherSuites = new String[oldEnabledCipherSuites.length + 1];
System.arraycopy(oldEnabledCipherSuites, 0,
newEnabledCipherSuites, 0, oldEnabledCipherSuites.length);
newEnabledCipherSuites[newEnabledCipherSuites.length - 1] = fallbackScsv;
cipherSuitesToEnable = newEnabledCipherSuites;
}
}
String[] protocolsToSelectFrom = sslSocket.getEnabledProtocols();
String[] protocolsToEnable = Util.intersect(String.class, tlsVersions, protocolsToSelectFrom);
return new Builder(this)
.cipherSuites(cipherSuitesToEnable)
.tlsVersions(protocolsToEnable)
.build();
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
Socket ssl = defaultFactory.createSocket(host, port);
if (ssl instanceof SSLSocket) {
upgradeTLS((SSLSocket) ssl);
}
return ssl;
}
@Override public Principal getLocalPrincipal() {
SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
if (cacheResponse != null) {
return cacheResponse.getLocalPrincipal();
}
SSLSocket sslSocket = getSslSocket();
if (sslSocket != null) {
return sslSocket.getSession().getLocalPrincipal();
}
return null;
}
static SSLClient init(int port, String ciphersuite)
throws NoSuchAlgorithmException, IOException {
SSLContext context = SSLContext.getDefault();
SSLSocketFactory ssf = (SSLSocketFactory)
context.getSocketFactory();
SSLSocket socket = (SSLSocket) ssf.createSocket("localhost", port);
if (ciphersuite != null) {
System.out.println("Client: enable cipher suite: "
+ ciphersuite);
socket.setEnabledCipherSuites(new String[] { ciphersuite });
}
return new SSLClient(socket);
}
@Override public Certificate[] getLocalCertificates() {
SecureCacheResponse cacheResponse = delegate.getSecureCacheResponse();
if (cacheResponse != null) {
List<Certificate> result = cacheResponse.getLocalCertificateChain();
return result != null ? result.toArray(new Certificate[result.size()]) : null;
}
SSLSocket sslSocket = getSslSocket();
if (sslSocket != null) {
return sslSocket.getSession().getLocalCertificates();
}
return null;
}
/**
* javax.net.ssl.SSLSocket#setNeedClientAuth(boolean need)
* javax.net.ssl.SSLSocket#getNeedClientAuthCreation()
*/
public void j2objcNotImplemented_test_NeedClientAuth()
throws UnknownHostException, IOException {
SSLSocket ssl = getSSLSocket();
ssl.setNeedClientAuth(true);
assertTrue(ssl.getNeedClientAuth());
ssl.setNeedClientAuth(false);
assertFalse(ssl.getNeedClientAuth());
ssl.close();
}