Skip to content

Commit 85061c1

Browse files
SSLEngineWebSocketServerFactory allows for more customization on the connection
1 parent fd4d55c commit 85061c1

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
3+
/*
4+
* Copyright (c) 2010-2019 Nathan Rajlich
5+
*
6+
* Permission is hereby granted, free of charge, to any person
7+
* obtaining a copy of this software and associated documentation
8+
* files (the "Software"), to deal in the Software without
9+
* restriction, including without limitation the rights to use,
10+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the
12+
* Software is furnished to do so, subject to the following
13+
* conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be
16+
* included in all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25+
* OTHER DEALINGS IN THE SOFTWARE.
26+
*/
27+
28+
import org.java_websocket.server.SSLEngineWebSocketServerFactory;
29+
30+
import javax.net.ssl.KeyManagerFactory;
31+
import javax.net.ssl.SSLContext;
32+
import javax.net.ssl.SSLEngine;
33+
import javax.net.ssl.TrustManagerFactory;
34+
import java.io.File;
35+
import java.io.FileInputStream;
36+
import java.security.KeyStore;
37+
import java.util.ArrayList;
38+
import java.util.Arrays;
39+
import java.util.List;
40+
41+
/**
42+
* Copy of SSLServerExample except we use @link SSLEngineWebSocketServerFactory to customize clientMode/ClientAuth to force client to present a cert.
43+
* Example of Two-way ssl/MutualAuthentication/ClientAuthentication
44+
*/
45+
public class TwoWaySSLServerExample {
46+
47+
/*
48+
* Keystore with certificate created like so (in JKS format):
49+
*
50+
*keytool -genkey -keyalg RSA -validity 3650 -keystore "keystore.jks" -storepass "storepassword" -keypass "keypassword" -alias "default" -dname "CN=127.0.0.1, OU=MyOrgUnit, O=MyOrg, L=MyCity, S=MyRegion, C=MyCountry"
51+
*/
52+
public static void main( String[] args ) throws Exception {
53+
ChatServer chatserver = new ChatServer( 8887 ); // Firefox does allow multible ssl connection only via port 443 //tested on FF16
54+
55+
// load up the key store
56+
String STORETYPE = "JKS";
57+
String KEYSTORE = "keystore.jks";
58+
String STOREPASSWORD = "storepassword";
59+
String KEYPASSWORD = "keypassword";
60+
61+
KeyStore ks = KeyStore.getInstance( STORETYPE );
62+
File kf = new File( KEYSTORE );
63+
ks.load( new FileInputStream( kf ), STOREPASSWORD.toCharArray() );
64+
65+
KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
66+
kmf.init( ks, KEYPASSWORD.toCharArray() );
67+
TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );
68+
tmf.init( ks );
69+
70+
SSLContext sslContext = SSLContext.getInstance( "TLS" );
71+
sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
72+
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 ) );
80+
81+
chatserver.start();
82+
83+
}
84+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2010-2019 Nathan Rajlich
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without
7+
* restriction, including without limitation the rights to use,
8+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following
11+
* conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be
14+
* included in all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
26+
package org.java_websocket.server;
27+
28+
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;
33+
34+
import javax.net.ssl.SSLEngine;
35+
import java.io.IOException;
36+
import java.nio.channels.ByteChannel;
37+
import java.nio.channels.SelectionKey;
38+
import java.nio.channels.SocketChannel;
39+
import java.util.List;
40+
import java.util.concurrent.ExecutorService;
41+
import java.util.concurrent.Executors;
42+
43+
/**
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
46+
*/
47+
public class SSLEngineWebSocketServerFactory implements WebSocketServerFactory {
48+
49+
private final SSLEngine sslEngine;
50+
protected ExecutorService exec;
51+
52+
public SSLEngineWebSocketServerFactory(SSLEngine sslEngine) {
53+
this(sslEngine, Executors.newSingleThreadScheduledExecutor());
54+
}
55+
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 );
69+
}
70+
71+
@Override
72+
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+
79+
}
80+
}

0 commit comments

Comments
 (0)