From 1cde8a70b625fa9b6fa16a02f435f2584fef2088 Mon Sep 17 00:00:00 2001 From: marci4 Date: Mon, 20 May 2019 20:30:28 +0200 Subject: [PATCH 1/5] Provide a way to access the SSLEngine of a websocket instance Fixes #890 --- .../org/java_websocket/SSLSocketChannel.java | 8 +++- .../org/java_websocket/SSLSocketChannel2.java | 7 ++- .../java/org/java_websocket/WebSocket.java | 17 ++++++++ .../org/java_websocket/WebSocketImpl.java | 16 +++++++ .../client/WebSocketClient.java | 10 +++++ .../interfaces/ISSLChannel.java | 43 +++++++++++++++++++ .../interfaces/package-info.java | 30 +++++++++++++ 7 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/java_websocket/interfaces/ISSLChannel.java create mode 100644 src/main/java/org/java_websocket/interfaces/package-info.java diff --git a/src/main/java/org/java_websocket/SSLSocketChannel.java b/src/main/java/org/java_websocket/SSLSocketChannel.java index 6f54f569..a3cfd3de 100644 --- a/src/main/java/org/java_websocket/SSLSocketChannel.java +++ b/src/main/java/org/java_websocket/SSLSocketChannel.java @@ -25,6 +25,7 @@ package org.java_websocket; +import org.java_websocket.interfaces.ISSLChannel; import org.java_websocket.util.ByteBufferUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,7 +63,7 @@ *

* Permission for usage recieved at May 25, 2017 by Alex Karnezis */ -public class SSLSocketChannel implements WrappedByteChannel, ByteChannel { +public class SSLSocketChannel implements WrappedByteChannel, ByteChannel, ISSLChannel { /** * Logger instance @@ -512,4 +513,9 @@ public boolean isOpen() { public void close() throws IOException { closeConnection(); } + + @Override + public SSLEngine getSSLEngine() { + return engine; + } } \ No newline at end of file diff --git a/src/main/java/org/java_websocket/SSLSocketChannel2.java b/src/main/java/org/java_websocket/SSLSocketChannel2.java index 64e83aa7..75a56c68 100644 --- a/src/main/java/org/java_websocket/SSLSocketChannel2.java +++ b/src/main/java/org/java_websocket/SSLSocketChannel2.java @@ -24,6 +24,7 @@ */ package org.java_websocket; +import org.java_websocket.interfaces.ISSLChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +53,7 @@ /** * Implements the relevant portions of the SocketChannel interface with the SSLEngine wrapper. */ -public class SSLSocketChannel2 implements ByteChannel, WrappedByteChannel { +public class SSLSocketChannel2 implements ByteChannel, WrappedByteChannel, ISSLChannel { /** * Logger instance @@ -425,4 +426,8 @@ public boolean isBlocking() { return socketChannel.isBlocking(); } + @Override + public SSLEngine getSSLEngine() { + return sslEngine; + } } \ No newline at end of file diff --git a/src/main/java/org/java_websocket/WebSocket.java b/src/main/java/org/java_websocket/WebSocket.java index f0b87961..b23775eb 100644 --- a/src/main/java/org/java_websocket/WebSocket.java +++ b/src/main/java/org/java_websocket/WebSocket.java @@ -35,6 +35,8 @@ import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.java_websocket.framing.Framedata; +import javax.net.ssl.SSLEngine; + public interface WebSocket { /** @@ -207,4 +209,19 @@ public interface WebSocket { * @since 1.3.7 **/ T getAttachment(); + + /** + * Does this websocket use an encrypted (wss/ssl) or unencrypted (ws) connection + * @return true, if the websocket does use wss and therefore has a SSLEngine + * @since 1.4.1 + */ + boolean hasSSLEngine(); + + /** + * Returns the ssl engine of websocket, if ssl/wss is used for this instance. + * @return the ssl engine of this websocket instance + * @throws IllegalArgumentException the underlying channel does not use ssl (use hasSSLEngine() to check) + * @since 1.4.1 + */ + SSLEngine getSSLEngine() throws IllegalArgumentException; } \ No newline at end of file diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index 80427f81..a7c1c405 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -25,6 +25,7 @@ package org.java_websocket; +import org.java_websocket.interfaces.ISSLChannel; import org.java_websocket.drafts.Draft; import org.java_websocket.drafts.Draft_6455; import org.java_websocket.enums.*; @@ -51,6 +52,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.net.ssl.SSLEngine; + /** * Represents one end (client or server) of a single WebSocketImpl connection. * Takes care of the "handshake" phase, then allows for easy sending of @@ -820,6 +823,19 @@ public T getAttachment() { return (T) attachment; } + @Override + public boolean hasSSLEngine() { + return channel instanceof ISSLChannel; + } + + @Override + public SSLEngine getSSLEngine() { + if (!hasSSLEngine()) { + throw new IllegalArgumentException("This websocket does use ws instead of wss. No SSLEngine available."); + } + return ((ISSLChannel) channel).getSSLEngine(); + } + @Override public void setAttachment(T attachment) { this.attachment = attachment; diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java index fc86d813..de7c0e31 100644 --- a/src/main/java/org/java_websocket/client/WebSocketClient.java +++ b/src/main/java/org/java_websocket/client/WebSocketClient.java @@ -42,6 +42,7 @@ import javax.net.SocketFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocketFactory; @@ -850,6 +851,15 @@ public String getResourceDescriptor() { return uri.getPath(); } + @Override + public boolean hasSSLEngine() { + return engine.hasSSLEngine(); + } + + @Override + public SSLEngine getSSLEngine() { + return engine.getSSLEngine(); + } /** * Method to give some additional info for specific IOExceptions diff --git a/src/main/java/org/java_websocket/interfaces/ISSLChannel.java b/src/main/java/org/java_websocket/interfaces/ISSLChannel.java new file mode 100644 index 00000000..6afd9b83 --- /dev/null +++ b/src/main/java/org/java_websocket/interfaces/ISSLChannel.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010-2019 Nathan Rajlich + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.java_websocket.interfaces; + +import javax.net.ssl.SSLEngine; + +/** + * Interface which specifies all required methods a SSLSocketChannel has to make public. + * + * @since 1.4.1 + */ +public interface ISSLChannel { + + /** + * Get the ssl engine used for the de- and encryption of the communication. + * @return the ssl engine of this channel + */ + SSLEngine getSSLEngine(); +} diff --git a/src/main/java/org/java_websocket/interfaces/package-info.java b/src/main/java/org/java_websocket/interfaces/package-info.java new file mode 100644 index 00000000..88dfa849 --- /dev/null +++ b/src/main/java/org/java_websocket/interfaces/package-info.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010-2019 Nathan Rajlich + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** + * This package encapsulates all new interfaces. + */ +package org.java_websocket.interfaces; \ No newline at end of file From 47ff6e751d1aeecf575750beef1ebb0a1f9ba5ed Mon Sep 17 00:00:00 2001 From: marci4 Date: Mon, 20 May 2019 20:42:15 +0200 Subject: [PATCH 2/5] Make only the SSLSession public --- src/main/java/org/java_websocket/WebSocket.java | 14 +++++++------- .../java/org/java_websocket/WebSocketImpl.java | 12 ++++++------ .../org/java_websocket/client/WebSocketClient.java | 13 +++++-------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/java_websocket/WebSocket.java b/src/main/java/org/java_websocket/WebSocket.java index b23775eb..559ef897 100644 --- a/src/main/java/org/java_websocket/WebSocket.java +++ b/src/main/java/org/java_websocket/WebSocket.java @@ -35,7 +35,7 @@ import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.java_websocket.framing.Framedata; -import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSession; public interface WebSocket { @@ -212,16 +212,16 @@ public interface WebSocket { /** * Does this websocket use an encrypted (wss/ssl) or unencrypted (ws) connection - * @return true, if the websocket does use wss and therefore has a SSLEngine + * @return true, if the websocket does use wss and therefore has a SSLSession * @since 1.4.1 */ - boolean hasSSLEngine(); + boolean hasSSLSupport(); /** - * Returns the ssl engine of websocket, if ssl/wss is used for this instance. - * @return the ssl engine of this websocket instance - * @throws IllegalArgumentException the underlying channel does not use ssl (use hasSSLEngine() to check) + * Returns the ssl session of websocket, if ssl/wss is used for this instance. + * @return the ssl session of this websocket instance + * @throws IllegalArgumentException the underlying channel does not use ssl (use hasSSLSupport() to check) * @since 1.4.1 */ - SSLEngine getSSLEngine() throws IllegalArgumentException; + SSLSession getSSLSession() throws IllegalArgumentException; } \ No newline at end of file diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index a7c1c405..5e213ede 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -52,7 +52,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLSession; /** * Represents one end (client or server) of a single WebSocketImpl connection. @@ -824,16 +824,16 @@ public T getAttachment() { } @Override - public boolean hasSSLEngine() { + public boolean hasSSLSupport() { return channel instanceof ISSLChannel; } @Override - public SSLEngine getSSLEngine() { - if (!hasSSLEngine()) { - throw new IllegalArgumentException("This websocket does use ws instead of wss. No SSLEngine available."); + public SSLSession getSSLSession() { + if (!hasSSLSupport()) { + throw new IllegalArgumentException("This websocket does use ws instead of wss. No SSLSession available."); } - return ((ISSLChannel) channel).getSSLEngine(); + return ((ISSLChannel) channel).getSSLEngine().getSession(); } @Override diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java index de7c0e31..32c9309f 100644 --- a/src/main/java/org/java_websocket/client/WebSocketClient.java +++ b/src/main/java/org/java_websocket/client/WebSocketClient.java @@ -41,10 +41,7 @@ import java.util.concurrent.TimeUnit; import javax.net.SocketFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.*; import org.java_websocket.AbstractWebSocket; import org.java_websocket.WebSocket; @@ -852,13 +849,13 @@ public String getResourceDescriptor() { } @Override - public boolean hasSSLEngine() { - return engine.hasSSLEngine(); + public boolean hasSSLSupport() { + return engine.hasSSLSupport(); } @Override - public SSLEngine getSSLEngine() { - return engine.getSSLEngine(); + public SSLSession getSSLSession() { + return engine.getSSLSession(); } /** From e351a2932fe780738b018f3a7bed87f377628fd1 Mon Sep 17 00:00:00 2001 From: marci4 Date: Mon, 20 May 2019 21:08:22 +0200 Subject: [PATCH 3/5] Test development --- .../java_websocket/issues/Issue764Test.java | 20 +-- .../java_websocket/issues/Issue825Test.java | 19 +- .../java_websocket/issues/Issue890Test.java | 170 ++++++++++++++++++ .../java_websocket/util/SSLContextUtil.java | 62 +++++++ 4 files changed, 236 insertions(+), 35 deletions(-) create mode 100644 src/test/java/org/java_websocket/issues/Issue890Test.java create mode 100644 src/test/java/org/java_websocket/util/SSLContextUtil.java diff --git a/src/test/java/org/java_websocket/issues/Issue764Test.java b/src/test/java/org/java_websocket/issues/Issue764Test.java index 98552628..78120bf6 100644 --- a/src/test/java/org/java_websocket/issues/Issue764Test.java +++ b/src/test/java/org/java_websocket/issues/Issue764Test.java @@ -32,6 +32,7 @@ import org.java_websocket.handshake.ServerHandshake; import org.java_websocket.server.DefaultSSLWebSocketServerFactory; import org.java_websocket.server.WebSocketServer; +import org.java_websocket.util.SSLContextUtil; import org.java_websocket.util.SocketUtil; import org.junit.Test; @@ -76,24 +77,7 @@ public void onError(Exception ex) { }; WebSocketServer server = new MyWebSocketServer(port, webSocket, countServerDownLatch); - // load up the key store - String STORETYPE = "JKS"; - String KEYSTORE = String.format("src%1$stest%1$1sjava%1$1sorg%1$1sjava_websocket%1$1skeystore.jks", File.separator); - String STOREPASSWORD = "storepassword"; - String KEYPASSWORD = "keypassword"; - - KeyStore ks = KeyStore.getInstance(STORETYPE); - File kf = new File(KEYSTORE); - ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray()); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, KEYPASSWORD.toCharArray()); - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ks); - - SSLContext sslContext = null; - sslContext = SSLContext.getInstance("TLS"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + SSLContext sslContext = SSLContextUtil.getContext(); server.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext)); webSocket.setSocketFactory(sslContext.getSocketFactory()); diff --git a/src/test/java/org/java_websocket/issues/Issue825Test.java b/src/test/java/org/java_websocket/issues/Issue825Test.java index 1861fa00..bf2276c9 100644 --- a/src/test/java/org/java_websocket/issues/Issue825Test.java +++ b/src/test/java/org/java_websocket/issues/Issue825Test.java @@ -32,6 +32,7 @@ import org.java_websocket.handshake.ServerHandshake; import org.java_websocket.server.DefaultSSLWebSocketServerFactory; import org.java_websocket.server.WebSocketServer; +import org.java_websocket.util.SSLContextUtil; import org.java_websocket.util.SocketUtil; import org.junit.Test; @@ -75,23 +76,7 @@ public void onError(Exception ex) { WebSocketServer server = new MyWebSocketServer(port, countServerDownLatch, countClientDownLatch); // load up the key store - String STORETYPE = "JKS"; - String KEYSTORE = String.format("src%1$stest%1$1sjava%1$1sorg%1$1sjava_websocket%1$1skeystore.jks", File.separator); - String STOREPASSWORD = "storepassword"; - String KEYPASSWORD = "keypassword"; - - KeyStore ks = KeyStore.getInstance(STORETYPE); - File kf = new File(KEYSTORE); - ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray()); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, KEYPASSWORD.toCharArray()); - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ks); - - SSLContext sslContext = null; - sslContext = SSLContext.getInstance("TLS"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + SSLContext sslContext = SSLContextUtil.getContext(); server.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext)); webSocket.setSocketFactory(sslContext.getSocketFactory()); diff --git a/src/test/java/org/java_websocket/issues/Issue890Test.java b/src/test/java/org/java_websocket/issues/Issue890Test.java new file mode 100644 index 00000000..45d42d38 --- /dev/null +++ b/src/test/java/org/java_websocket/issues/Issue890Test.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2010-2019 Nathan Rajlich + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.java_websocket.issues; + +import org.java_websocket.WebSocket; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.handshake.ServerHandshake; +import org.java_websocket.server.DefaultSSLWebSocketServerFactory; +import org.java_websocket.server.WebSocketServer; +import org.java_websocket.util.SSLContextUtil; +import org.java_websocket.util.SocketUtil; +import org.junit.Test; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.*; +import java.security.cert.CertificateException; +import java.util.concurrent.CountDownLatch; + +import static org.junit.Assert.*; + +public class Issue890Test { + + + @Test(timeout = 4000) + public void testWithSSLSession() throws IOException, URISyntaxException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException, CertificateException, InterruptedException { + int port = SocketUtil.getAvailablePort(); + final CountDownLatch countServerDownLatch = new CountDownLatch(1); + final WebSocketClient webSocket = new WebSocketClient(new URI("wss://localhost:" + port)) { + @Override + public void onOpen(ServerHandshake handshakedata) { + countServerDownLatch.countDown(); + } + + @Override + public void onMessage(String message) { + } + + @Override + public void onClose(int code, String reason, boolean remote) { + } + + @Override + public void onError(Exception ex) { + } + }; + TestResult testResult = new TestResult(); + WebSocketServer server = new MyWebSocketServer(port, testResult, countServerDownLatch); + SSLContext sslContext = SSLContextUtil.getContext(); + + server.setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext)); + webSocket.setSocketFactory(sslContext.getSocketFactory()); + server.start(); + countServerDownLatch.await(); + webSocket.connectBlocking(); + assertTrue(testResult.hasSSLSupport); + assertNotNull(testResult.sslSession); + } + + @Test(timeout = 4000) + public void testWithOutSSLSession() throws IOException, URISyntaxException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException, CertificateException, InterruptedException { + int port = SocketUtil.getAvailablePort(); + final CountDownLatch countServerDownLatch = new CountDownLatch(1); + final WebSocketClient webSocket = new WebSocketClient(new URI("ws://localhost:" + port)) { + @Override + public void onOpen(ServerHandshake handshakedata) { + countServerDownLatch.countDown(); + } + + @Override + public void onMessage(String message) { + } + + @Override + public void onClose(int code, String reason, boolean remote) { + } + + @Override + public void onError(Exception ex) { + } + }; + TestResult testResult = new TestResult(); + WebSocketServer server = new MyWebSocketServer(port, testResult, countServerDownLatch); + server.start(); + countServerDownLatch.await(); + webSocket.connectBlocking(); + assertFalse(testResult.hasSSLSupport); + assertNull(testResult.sslSession); + } + + + private static class MyWebSocketServer extends WebSocketServer { + + private final TestResult testResult; + private final CountDownLatch countServerDownLatch; + + public MyWebSocketServer(int port, TestResult testResult, CountDownLatch countServerDownLatch) { + super(new InetSocketAddress(port)); + this.testResult = testResult; + this.countServerDownLatch = countServerDownLatch; + } + @Override + public void onOpen(WebSocket conn, ClientHandshake handshake) { + testResult.hasSSLSupport = conn.hasSSLSupport(); + try { + testResult.sslSession = conn.getSSLSession(); + } catch (IllegalArgumentException e){ + // Ignore + } + } + + @Override + public void onClose(WebSocket conn, int code, String reason, boolean remote) { + } + + @Override + public void onMessage(WebSocket conn, String message) { + + } + + @Override + public void onError(WebSocket conn, Exception ex) { + ex.printStackTrace(); + } + + @Override + public void onStart() { + countServerDownLatch.countDown(); + } + } + + private class TestResult { + public SSLSession sslSession = null; + + public boolean hasSSLSupport = false; + } +} diff --git a/src/test/java/org/java_websocket/util/SSLContextUtil.java b/src/test/java/org/java_websocket/util/SSLContextUtil.java new file mode 100644 index 00000000..9f56913a --- /dev/null +++ b/src/test/java/org/java_websocket/util/SSLContextUtil.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010-2019 Nathan Rajlich + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.java_websocket.util; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.*; +import java.security.cert.CertificateException; + +public class SSLContextUtil { + + public static SSLContext getContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException { + // load up the key store + String STORETYPE = "JKS"; + String KEYSTORE = String.format("src%1$stest%1$1sjava%1$1sorg%1$1sjava_websocket%1$1skeystore.jks", File.separator); + String STOREPASSWORD = "storepassword"; + String KEYPASSWORD = "keypassword"; + + KeyStore ks = KeyStore.getInstance(STORETYPE); + File kf = new File(KEYSTORE); + ks.load(new FileInputStream(kf), STOREPASSWORD.toCharArray()); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, KEYPASSWORD.toCharArray()); + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ks); + + SSLContext sslContext = null; + sslContext = SSLContext.getInstance("TLS"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + return sslContext; + } +} From 95a10ec100febd5a4d97f023b2ab5e60db0cfbcc Mon Sep 17 00:00:00 2001 From: marci4 Date: Tue, 28 May 2019 18:56:29 +0200 Subject: [PATCH 4/5] Rework after review Use IllegalStateException instead of IllegalArgumentException --- src/main/java/org/java_websocket/WebSocketImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index 5e213ede..3a45c886 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -831,7 +831,7 @@ public boolean hasSSLSupport() { @Override public SSLSession getSSLSession() { if (!hasSSLSupport()) { - throw new IllegalArgumentException("This websocket does use ws instead of wss. No SSLSession available."); + throw new IllegalStateException("This websocket does use ws instead of wss. No SSLSession available."); } return ((ISSLChannel) channel).getSSLEngine().getSession(); } From 3e3d91d1f988eb143f17630ed201ead98eadd3ef Mon Sep 17 00:00:00 2001 From: Marcel Prestel Date: Sat, 13 Jul 2019 10:22:17 +0200 Subject: [PATCH 5/5] Rework after review --- src/main/java/org/java_websocket/WebSocketImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/java_websocket/WebSocketImpl.java b/src/main/java/org/java_websocket/WebSocketImpl.java index 3a45c886..c2a85d03 100644 --- a/src/main/java/org/java_websocket/WebSocketImpl.java +++ b/src/main/java/org/java_websocket/WebSocketImpl.java @@ -831,7 +831,7 @@ public boolean hasSSLSupport() { @Override public SSLSession getSSLSession() { if (!hasSSLSupport()) { - throw new IllegalStateException("This websocket does use ws instead of wss. No SSLSession available."); + throw new IllegalArgumentException("This websocket uses ws instead of wss. No SSLSession available."); } return ((ISSLChannel) channel).getSSLEngine().getSession(); }