From 1cde8a70b625fa9b6fa16a02f435f2584fef2088 Mon Sep 17 00:00:00 2001 From: marci4 Date: Mon, 20 May 2019 20:30:28 +0200 Subject: [PATCH] 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