1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.jboss.netty.handler.ssl;
18
19 import org.eclipse.jetty.npn.NextProtoNego;
20 import org.eclipse.jetty.npn.NextProtoNego.ClientProvider;
21 import org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
22
23 import javax.net.ssl.SSLEngine;
24 import javax.net.ssl.SSLEngineResult;
25 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
26 import javax.net.ssl.SSLException;
27 import javax.net.ssl.SSLParameters;
28 import javax.net.ssl.SSLSession;
29 import java.nio.ByteBuffer;
30 import java.util.List;
31
32 final class JettyNpnSslEngine extends SSLEngine {
33
34 private static boolean available;
35
36 static boolean isAvailable() {
37 updateAvailability();
38 return available;
39 }
40
41 private static void updateAvailability() {
42 if (available) {
43 return;
44 }
45 try {
46
47 ClassLoader bootloader = ClassLoader.getSystemClassLoader().getParent();
48 if (bootloader == null) {
49
50
51 bootloader = ClassLoader.getSystemClassLoader();
52 }
53 Class.forName("sun.security.ssl.NextProtoNegoExtension", true, bootloader);
54 available = true;
55 } catch (Exception ignore) {
56
57 }
58 }
59
60 private final SSLEngine engine;
61 private final JettyNpnSslSession session;
62
63 JettyNpnSslEngine(SSLEngine engine, final List<String> nextProtocols, boolean server) {
64 assert !nextProtocols.isEmpty();
65
66 this.engine = engine;
67 session = new JettyNpnSslSession(engine);
68
69 if (server) {
70 NextProtoNego.put(engine, new ServerProvider() {
71 public void unsupported() {
72 getSession().setApplicationProtocol(nextProtocols.get(nextProtocols.size() - 1));
73 }
74
75 public List<String> protocols() {
76 return nextProtocols;
77 }
78
79 public void protocolSelected(String protocol) {
80 getSession().setApplicationProtocol(protocol);
81 }
82 });
83 } else {
84 final String[] list = nextProtocols.toArray(new String[nextProtocols.size()]);
85 final String fallback = list[list.length - 1];
86
87 NextProtoNego.put(engine, new ClientProvider() {
88 public boolean supports() {
89 return true;
90 }
91
92 public void unsupported() {
93 session.setApplicationProtocol(null);
94 }
95
96 public String selectProtocol(List<String> protocols) {
97 for (String p: list) {
98 if (protocols.contains(p)) {
99 return p;
100 }
101 }
102 return fallback;
103 }
104 });
105 }
106 }
107
108 @Override
109 public JettyNpnSslSession getSession() {
110 return session;
111 }
112
113 @Override
114 public void closeInbound() throws SSLException {
115 NextProtoNego.remove(engine);
116 engine.closeInbound();
117 }
118
119 @Override
120 public void closeOutbound() {
121 NextProtoNego.remove(engine);
122 engine.closeOutbound();
123 }
124
125 @Override
126 public String getPeerHost() {
127 return engine.getPeerHost();
128 }
129
130 @Override
131 public int getPeerPort() {
132 return engine.getPeerPort();
133 }
134
135 @Override
136 public SSLEngineResult wrap(ByteBuffer byteBuffer, ByteBuffer byteBuffer2) throws SSLException {
137 return engine.wrap(byteBuffer, byteBuffer2);
138 }
139
140 @Override
141 public SSLEngineResult wrap(ByteBuffer[] byteBuffers, ByteBuffer byteBuffer) throws SSLException {
142 return engine.wrap(byteBuffers, byteBuffer);
143 }
144
145 @Override
146 public SSLEngineResult wrap(ByteBuffer[] byteBuffers, int i, int i2, ByteBuffer byteBuffer) throws SSLException {
147 return engine.wrap(byteBuffers, i, i2, byteBuffer);
148 }
149
150 @Override
151 public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer byteBuffer2) throws SSLException {
152 return engine.unwrap(byteBuffer, byteBuffer2);
153 }
154
155 @Override
156 public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers) throws SSLException {
157 return engine.unwrap(byteBuffer, byteBuffers);
158 }
159
160 @Override
161 public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers, int i, int i2) throws SSLException {
162 return engine.unwrap(byteBuffer, byteBuffers, i, i2);
163 }
164
165 @Override
166 public Runnable getDelegatedTask() {
167 return engine.getDelegatedTask();
168 }
169
170 @Override
171 public boolean isInboundDone() {
172 return engine.isInboundDone();
173 }
174
175 @Override
176 public boolean isOutboundDone() {
177 return engine.isOutboundDone();
178 }
179
180 @Override
181 public String[] getSupportedCipherSuites() {
182 return engine.getSupportedCipherSuites();
183 }
184
185 @Override
186 public String[] getEnabledCipherSuites() {
187 return engine.getEnabledCipherSuites();
188 }
189
190 @Override
191 public void setEnabledCipherSuites(String[] strings) {
192 engine.setEnabledCipherSuites(strings);
193 }
194
195 @Override
196 public String[] getSupportedProtocols() {
197 return engine.getSupportedProtocols();
198 }
199
200 @Override
201 public String[] getEnabledProtocols() {
202 return engine.getEnabledProtocols();
203 }
204
205 @Override
206 public void setEnabledProtocols(String[] strings) {
207 engine.setEnabledProtocols(strings);
208 }
209
210 @Override
211 public SSLSession getHandshakeSession() {
212 return engine.getHandshakeSession();
213 }
214
215 @Override
216 public void beginHandshake() throws SSLException {
217 engine.beginHandshake();
218 }
219
220 @Override
221 public HandshakeStatus getHandshakeStatus() {
222 return engine.getHandshakeStatus();
223 }
224
225 @Override
226 public void setUseClientMode(boolean b) {
227 engine.setUseClientMode(b);
228 }
229
230 @Override
231 public boolean getUseClientMode() {
232 return engine.getUseClientMode();
233 }
234
235 @Override
236 public void setNeedClientAuth(boolean b) {
237 engine.setNeedClientAuth(b);
238 }
239
240 @Override
241 public boolean getNeedClientAuth() {
242 return engine.getNeedClientAuth();
243 }
244
245 @Override
246 public void setWantClientAuth(boolean b) {
247 engine.setWantClientAuth(b);
248 }
249
250 @Override
251 public boolean getWantClientAuth() {
252 return engine.getWantClientAuth();
253 }
254
255 @Override
256 public void setEnableSessionCreation(boolean b) {
257 engine.setEnableSessionCreation(b);
258 }
259
260 @Override
261 public boolean getEnableSessionCreation() {
262 return engine.getEnableSessionCreation();
263 }
264
265 @Override
266 public SSLParameters getSSLParameters() {
267 return engine.getSSLParameters();
268 }
269
270 @Override
271 public void setSSLParameters(SSLParameters sslParameters) {
272 engine.setSSLParameters(sslParameters);
273 }
274 }