Skip to content

Commit a3a5a91

Browse files
Refactor to use SSLParameters and extend DefaultSSLWebSocketServerFactory
1 parent 85061c1 commit a3a5a91

4 files changed

Lines changed: 172 additions & 44 deletions

File tree

src/main/example/SSLClientExample.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ public static void main( String[] args ) throws Exception {
111111
while ( true ) {
112112
String line = reader.readLine();
113113
if( line.equals( "close" ) ) {
114-
chatclient.close();
114+
chatclient.closeBlocking();
115+
} else if ( line.equals( "open" ) ) {
116+
chatclient.reconnect();
115117
} else {
116118
chatclient.send( line );
117119
}

src/main/example/TwoWaySSLServerExample.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,15 @@
2525
* OTHER DEALINGS IN THE SOFTWARE.
2626
*/
2727

28-
import org.java_websocket.server.SSLEngineWebSocketServerFactory;
28+
import org.java_websocket.server.SSLParametersWebSocketServerFactory;
2929

3030
import javax.net.ssl.KeyManagerFactory;
3131
import javax.net.ssl.SSLContext;
32-
import javax.net.ssl.SSLEngine;
32+
import javax.net.ssl.SSLParameters;
3333
import javax.net.ssl.TrustManagerFactory;
3434
import java.io.File;
3535
import java.io.FileInputStream;
3636
import java.security.KeyStore;
37-
import java.util.ArrayList;
38-
import java.util.Arrays;
39-
import java.util.List;
4037

4138
/**
4239
* Copy of SSLServerExample except we use @link SSLEngineWebSocketServerFactory to customize clientMode/ClientAuth to force client to present a cert.
@@ -70,13 +67,10 @@ public static void main( String[] args ) throws Exception {
7067
SSLContext sslContext = SSLContext.getInstance( "TLS" );
7168
sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
7269

73-
SSLEngine engine = sslContext.createSSLEngine();
74-
75-
// Here we force the client to present a certificate
76-
engine.setUseClientMode(false);
77-
engine.setNeedClientAuth(true);
78-
79-
chatserver.setWebSocketFactory( new SSLEngineWebSocketServerFactory( engine ) );
70+
SSLParameters sslParameters = new SSLParameters();
71+
// This is all we need
72+
sslParameters.setNeedClientAuth(true);
73+
chatserver.setWebSocketFactory( new SSLParametersWebSocketServerFactory(sslContext, sslParameters));
8074

8175
chatserver.start();
8276

src/main/java/org/java_websocket/server/SSLEngineWebSocketServerFactory.java renamed to src/main/java/org/java_websocket/server/SSLParametersWebSocketServerFactory.java

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,55 +26,56 @@
2626
package org.java_websocket.server;
2727

2828
import org.java_websocket.SSLSocketChannel2;
29-
import org.java_websocket.WebSocketAdapter;
30-
import org.java_websocket.WebSocketImpl;
31-
import org.java_websocket.WebSocketServerFactory;
32-
import org.java_websocket.drafts.Draft;
3329

30+
import javax.net.ssl.SSLContext;
3431
import javax.net.ssl.SSLEngine;
32+
import javax.net.ssl.SSLParameters;
3533
import java.io.IOException;
3634
import java.nio.channels.ByteChannel;
3735
import java.nio.channels.SelectionKey;
3836
import java.nio.channels.SocketChannel;
39-
import java.util.List;
4037
import java.util.concurrent.ExecutorService;
4138
import java.util.concurrent.Executors;
4239

4340
/**
44-
* WebSocketFactory that take a SSLEngine as a parameter allow for customization of SSLParameters, Cipher Suites, Supported Protocols, ClientMode, ClientAuth ...
45-
* @link https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLEngine.html
41+
* WebSocketFactory that can be configured to only support specific protocols and cipher suites.
4642
*/
47-
public class SSLEngineWebSocketServerFactory implements WebSocketServerFactory {
43+
public class SSLParametersWebSocketServerFactory extends DefaultSSLWebSocketServerFactory {
4844

49-
private final SSLEngine sslEngine;
50-
protected ExecutorService exec;
45+
private final SSLParameters sslParameters;
5146

52-
public SSLEngineWebSocketServerFactory(SSLEngine sslEngine) {
53-
this(sslEngine, Executors.newSingleThreadScheduledExecutor());
47+
/**
48+
* New CustomSSLWebSocketServerFactory configured to only support given protocols and given cipher suites.
49+
*
50+
* @param sslContext - can not be <code>null</code>
51+
* @param sslParameters - sslParameters
52+
*/
53+
public SSLParametersWebSocketServerFactory(SSLContext sslContext, SSLParameters sslParameters) {
54+
this(sslContext, Executors.newSingleThreadScheduledExecutor(), sslParameters);
5455
}
5556

56-
private SSLEngineWebSocketServerFactory(SSLEngine sslEngine, ExecutorService exec) {
57-
this.sslEngine = sslEngine;
58-
this.exec = exec;
59-
}
60-
61-
@Override
62-
public WebSocketImpl createWebSocket( WebSocketAdapter a, Draft d) {
63-
return new WebSocketImpl( a, d );
64-
}
65-
66-
@Override
67-
public WebSocketImpl createWebSocket( WebSocketAdapter a, List<Draft> d) {
68-
return new WebSocketImpl( a, d );
57+
/**
58+
* New CustomSSLWebSocketServerFactory configured to only support given protocols and given cipher suites.
59+
*
60+
* @param sslContext - can not be <code>null</code>
61+
* @param executerService - can not be <code>null</code>
62+
* @param sslParameters - sslParameters
63+
*/
64+
public SSLParametersWebSocketServerFactory(SSLContext sslContext, ExecutorService executerService, SSLParameters sslParameters) {
65+
super(sslContext, executerService);
66+
if (sslParameters == null) {
67+
throw new IllegalArgumentException();
68+
}
69+
this.sslParameters = sslParameters;
6970
}
7071

7172
@Override
7273
public ByteChannel wrapChannel(SocketChannel channel, SelectionKey key) throws IOException {
73-
return new SSLSocketChannel2(channel, sslEngine, exec, key);
74-
}
75-
76-
@Override
77-
public void close() {
78-
74+
SSLEngine e = sslcontext.createSSLEngine();
75+
e.setUseClientMode(false);
76+
if (sslParameters != null) {
77+
e.setSSLParameters(sslParameters);
78+
}
79+
return new SSLSocketChannel2(channel, e, exec, key);
7980
}
8081
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package org.java_websocket.server;
2+
3+
import org.java_websocket.WebSocket;
4+
import org.java_websocket.WebSocketAdapter;
5+
import org.java_websocket.WebSocketImpl;
6+
import org.java_websocket.drafts.Draft;
7+
import org.java_websocket.drafts.Draft_6455;
8+
import org.java_websocket.handshake.Handshakedata;
9+
import org.junit.Test;
10+
11+
import javax.net.ssl.SSLContext;
12+
import javax.net.ssl.SSLParameters;
13+
import java.io.IOException;
14+
import java.net.InetSocketAddress;
15+
import java.nio.ByteBuffer;
16+
import java.nio.channels.ByteChannel;
17+
import java.nio.channels.NotYetConnectedException;
18+
import java.nio.channels.SocketChannel;
19+
import java.security.NoSuchAlgorithmException;
20+
import java.util.Collections;
21+
import java.util.concurrent.Executors;
22+
23+
import static org.junit.Assert.assertNotNull;
24+
import static org.junit.Assert.fail;
25+
26+
public class SSLParametersWebSocketServerFactoryTest {
27+
28+
@Test
29+
public void testConstructor() throws NoSuchAlgorithmException {
30+
try {
31+
new SSLParametersWebSocketServerFactory(null, null);
32+
fail("IllegalArgumentException should be thrown");
33+
} catch (IllegalArgumentException e) {
34+
// Good
35+
}
36+
try {
37+
new SSLParametersWebSocketServerFactory(SSLContext.getDefault(), null);
38+
fail("IllegalArgumentException should be thrown");
39+
} catch (IllegalArgumentException e) {
40+
}
41+
try {
42+
new SSLParametersWebSocketServerFactory(SSLContext.getDefault(), new SSLParameters());
43+
} catch (IllegalArgumentException e) {
44+
fail("IllegalArgumentException should not be thrown");
45+
}
46+
try {
47+
new SSLParametersWebSocketServerFactory(SSLContext.getDefault(), Executors.newCachedThreadPool(), new SSLParameters());
48+
} catch (IllegalArgumentException e) {
49+
fail("IllegalArgumentException should not be thrown");
50+
}
51+
}
52+
@Test
53+
public void testCreateWebSocket() throws NoSuchAlgorithmException {
54+
SSLParametersWebSocketServerFactory webSocketServerFactory = new SSLParametersWebSocketServerFactory(SSLContext.getDefault(), new SSLParameters());
55+
CustomWebSocketAdapter webSocketAdapter = new CustomWebSocketAdapter();
56+
WebSocketImpl webSocketImpl = webSocketServerFactory.createWebSocket(webSocketAdapter, new Draft_6455());
57+
assertNotNull("webSocketImpl != null", webSocketImpl);
58+
webSocketImpl = webSocketServerFactory.createWebSocket(webSocketAdapter, Collections.<Draft>singletonList(new Draft_6455()));
59+
assertNotNull("webSocketImpl != null", webSocketImpl);
60+
}
61+
62+
@Test
63+
public void testWrapChannel() throws IOException, NoSuchAlgorithmException {
64+
SSLParametersWebSocketServerFactory webSocketServerFactory = new SSLParametersWebSocketServerFactory(SSLContext.getDefault(), new SSLParameters());
65+
SocketChannel channel = SocketChannel.open();
66+
try {
67+
ByteChannel result = webSocketServerFactory.wrapChannel(channel, null);
68+
} catch (NotYetConnectedException e) {
69+
//We do not really connect
70+
}
71+
channel.close();
72+
}
73+
74+
@Test
75+
public void testClose() {
76+
DefaultWebSocketServerFactory webSocketServerFactory = new DefaultWebSocketServerFactory();
77+
webSocketServerFactory.close();
78+
}
79+
80+
private static class CustomWebSocketAdapter extends WebSocketAdapter {
81+
@Override
82+
public void onWebsocketMessage(WebSocket conn, String message) {
83+
84+
}
85+
86+
@Override
87+
public void onWebsocketMessage(WebSocket conn, ByteBuffer blob) {
88+
89+
}
90+
91+
@Override
92+
public void onWebsocketOpen(WebSocket conn, Handshakedata d) {
93+
94+
}
95+
96+
@Override
97+
public void onWebsocketClose(WebSocket ws, int code, String reason, boolean remote) {
98+
99+
}
100+
101+
@Override
102+
public void onWebsocketClosing(WebSocket ws, int code, String reason, boolean remote) {
103+
104+
}
105+
106+
@Override
107+
public void onWebsocketCloseInitiated(WebSocket ws, int code, String reason) {
108+
109+
}
110+
111+
@Override
112+
public void onWebsocketError(WebSocket conn, Exception ex) {
113+
114+
}
115+
116+
@Override
117+
public void onWriteDemand(WebSocket conn) {
118+
119+
}
120+
121+
@Override
122+
public InetSocketAddress getLocalSocketAddress(WebSocket conn) {
123+
return null;
124+
}
125+
126+
@Override
127+
public InetSocketAddress getRemoteSocketAddress(WebSocket conn) {
128+
return null;
129+
}
130+
}
131+
}

0 commit comments

Comments
 (0)