##### Coverage Report - com.sun.grizzly.filter.SSLReadFilter

Classes in this File | Line Coverage | Branch Coverage | Complexity
SSLReadFilter |
56 % | 107/192
46 % | 34/74
| 0.0;0

1 |  |
     /*
2 |  |
      *
3 |  |
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 |  |
      *
5 |  |
      * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
6 |  |
      *
7 |  |
      * The contents of this file are subject to the terms of either the GNU
8 |  |
      * General Public License Version 2 only ("GPL") or the Common Development
9 |  |
      * and Distribution License("CDDL") (collectively, the "License").  You
10 |  |
      * may not use this file except in compliance with the License. You can obtain
11 |  |
      * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
12 |  |
      * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
13 |  |
      * language governing permissions and limitations under the License.
14 |  |
      *
15 |  |
      * When distributing the software, include this License Header Notice in each
16 |  |
      * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
17 |  |
      * Sun designates this particular file as subject to the "Classpath" exception
18 |  |
      * as provided by Sun in the GPL Version 2 section of the License file that
19 |  |
      * accompanied this code.  If applicable, add the following below the License
20 |  |
      * Header, with the fields enclosed by brackets [] replaced by your own
21 |  |
      * identifying information: "Portions Copyrighted [year]
22 |  |
      * [name of copyright owner]"
23 |  |
      *
24 |  |
      * Contributor(s):
25 |  |
      *
26 |  |
      * If you wish your version of this file to be governed by only the CDDL or
27 |  |
      * only the GPL Version 2, indicate your decision by adding "[Contributor]
28 |  |
      * elects to include this software in this distribution under the [CDDL or GPL
29 |  |
      * Version 2] license."  If you don't indicate a single choice of license, a
30 |  |
      * recipient has the option to distribute your version of this file under
31 |  |
      * either the CDDL, the GPL Version 2 or to extend the choice of license to
32 |  |
      * its licensees as provided above.  However, if you add GPL Version 2 code
33 |  |
      * and therefore, elected the GPL Version 2 license, then the option applies
34 |  |
      * only if the new code is made subject to such option by the copyright
35 |  |
      * holder.
36 |  |
      *
37 |  |
      */
38 |  |
39 |  |
     package com.sun.grizzly.filter;
40 |  |
41 |  |
     import com.sun.grizzly.Context;
42 |  |
     import com.sun.grizzly.Controller;
43 |  |
     import com.sun.grizzly.ProtocolFilter;
44 |  |
     import com.sun.grizzly.SSLConfig;
45 |  |
     import com.sun.grizzly.util.InputReader;
46 |  |
     import com.sun.grizzly.util.SSLUtils;
47 |  |
     import com.sun.grizzly.util.ThreadAttachment;
48 |  |
     import com.sun.grizzly.util.ThreadAttachment.Mode;
49 |  |
     import com.sun.grizzly.util.WorkerThread;
50 |  |
     import java.io.EOFException;
51 |  |
     import java.io.IOException;
52 |  |
     import java.nio.ByteBuffer;
53 |  |
     import java.nio.channels.SelectionKey;
54 |  |
     import java.nio.channels.SocketChannel;
55 |  |
     import java.util.ArrayList;
56 |  |
     import java.util.logging.Level;
57 |  |
     import javax.net.ssl.SSLContext;
58 |  |
     import javax.net.ssl.SSLEngine;
59 |  |
     import javax.net.ssl.SSLEngineResult.HandshakeStatus;
60 |  |
     import javax.net.ssl.SSLException;
61 |  |
62 |  |
     /**
63 |  |
      * Simple ProtocolFilter implementation which execute an SSL handshake and
64 |  |
      * decrypt the bytes, the pass the control to the next filter.
65 |  |
      *
66 |  |
      * @author Jeanfrancois Arcand
67 |  |
      */
68 |  |
     public class SSLReadFilter implements ProtocolFilter{
69 |  |
         /**
70 |  |
          * The {@link SSLContext} associated with the SSL implementation
71 |  |
          * we are running on.
72 |  |
          */
73 |  |
         protected SSLContext sslContext;
74 |  |
75 |  |
76 |  |
         /**
77 |  |
          * The list of cipher suite
78 |  |
          */
79 | 5 |
         private String[] enabledCipherSuites = null;
80 |  |
81 |  |
82 |  |
         /**
83 |  |
          * the list of protocols
84 |  |
          */
85 | 5 |
         private String[] enabledProtocols = null;
86 |  |
87 |  |
88 |  |
         /**
89 |  |
          * Client mode when handshaking.
90 |  |
          */
91 | 5 |
         private boolean clientMode = false;
92 |  |
93 |  |
94 |  |
         /**
95 |  |
          * Require client Authentication.
96 |  |
          */
97 | 5 |
         private boolean needClientAuth = false;
98 |  |
99 |  |
100 |  |
         /**
101 |  |
          * True when requesting authentication.
102 |  |
          */
103 | 5 |
         private boolean wantClientAuth = false;
104 |  |
105 |  |
106 |  |
         /**
107 |  |
          * Has the enabled protocol configured.
108 |  |
          */
109 | 5 |
         private boolean isProtocolConfigured = false;
110 |  |
111 |  |
112 |  |
         /**
113 |  |
          * Has the enabled Cipher configured.
114 |  |
          */
115 | 5 |
         private boolean isCipherConfigured = false;
116 |  |
117 |  |
118 |  |
         /**
119 |  |
          * Encrypted ByteBuffer default size.
120 |  |
          */
121 | 5 |
         protected int inputBBSize = 5 * 4096;
122 |  |
123 |  |
124 | 5 |
         public SSLReadFilter() {
125 | 5 |
         }
126 |  |
127 |  |
128 |  |
         public boolean execute(Context ctx) throws IOException {
129 | 53201 |
             boolean result = true;
130 | 53201 |
             int count = 0;
131 | 53201 |
             Throwable exception = null;
132 | 53201 |
             SelectionKey key = ctx.getSelectionKey();
133 |  |
             WorkerThread workerThread;
134 |  |
             try{
135 | 53201 |
                 workerThread = (WorkerThread)Thread.currentThread();
136 | 0 |
             } catch (ClassCastException ex){
137 | 0 |
                 throw new IllegalStateException(ex.getMessage());
138 | 53201 |
             }
139 |  |
140 | 53201 |
             SSLEngine sslEngine = workerThread.getSSLEngine();
141 | 53201 |
             if (sslEngine == null) {
142 | 123 |
                 sslEngine = newSSLEngine(key);
143 | 123 |
                 workerThread.setSSLEngine(sslEngine);
144 | 123 |
                 ThreadAttachment attachment = workerThread.updateAttachment(Mode.SSL_ENGINE);
145 | 123 |
                 key.attach(attachment);
146 |  |
             }
147 |  |
148 | 53201 |
             boolean hasHandshake = sslEngine.getSession().isValid();
149 |  |
             try {
150 | 53201 |
                 SSLUtils.allocateThreadBuffers(inputBBSize);
151 |  |
152 | 53201 |
                 if (hasHandshake) {
153 | 53078 |
                     count = doRead(key);
154 | 123 |
                 } else if (doHandshake(key, SSLUtils.getReadTimeout())) {
155 | 122 |
                     hasHandshake = true;
156 |  |
                     // set "no available data" for secured output buffer
157 | 122 |
                     ByteBuffer outputBB = workerThread.getOutputBB();
158 | 122 |
                     outputBB.limit(outputBB.position());
159 | 122 |
                 } else {
160 | 1 |
                     count = -1;
161 |  |
                 }
162 | 0 |
             } catch (IOException ex) {
163 | 0 |
                 exception = ex;
164 | 0 |
                 log("SSLReadFilter.execute",ex);
165 | 0 |
             } catch (Throwable ex) {
166 | 0 |
                 exception = ex;
167 | 0 |
                 log("SSLReadFilter.execute",ex);
168 |  |
             } finally {
169 | 53201 |
                 if (exception != null || count == -1){
170 | 118 |
                     ctx.setAttribute(Context.THROWABLE,exception);
171 | 118 |
                     ctx.setKeyRegistrationState(
172 |  |
                             Context.KeyRegistrationState.CANCEL);
173 | 118 |
                     result = false;
174 |  |
                 }
175 |  |
             }
176 | 53201 |
             return result;
177 |  |
         }
178 |  |
179 |  |
180 |  |
         /**
181 |  |
          * If no bytes were available, close the connection by cancelling the
182 |  |
          * SelectionKey. If bytes were available, register the SelectionKey
183 |  |
          * for new bytes.
184 |  |
          *
185 |  |
          * @return <tt>true</tt> if the previous ProtocolFilter postExecute method
186 |  |
          *         needs to be invoked.
187 |  |
          */
188 |  |
         public boolean postExecute(Context ctx) throws IOException {
189 | 53201 |
             if (ctx.getKeyRegistrationState()
190 |  |
                     == Context.KeyRegistrationState.CANCEL){
191 | 118 |
                 ctx.getSelectorHandler().getSelectionKeyHandler().
192 |  |
                         cancel(ctx.getSelectionKey());
193 | 53083 |
             } else if (ctx.getKeyRegistrationState()
194 |  |
                     == Context.KeyRegistrationState.REGISTER){
195 | 53083 |
                 saveSecuredBufferRemainders(ctx.getSelectionKey());
196 | 53083 |
                 ctx.getSelectorHandler().register(ctx.getSelectionKey(),
197 |  |
                         SelectionKey.OP_READ);
198 | 53083 |
                 ctx.setKeyRegistrationState(Context.KeyRegistrationState.NONE);
199 |  |
             }
200 | 53201 |
             return true;
201 |  |
         }
202 |  |
203 |  |
204 |  |
         /**
205 |  |
          * Execute a non blocking SSL handshake.
206 |  |
          * @param key {@link SelectionKey}
207 |  |
          * @param timeout
208 |  |
          * @return
209 |  |
          * @throws java.io.IOException
210 |  |
          */
211 |  |
         private static boolean doHandshake(SelectionKey key,int timeout) throws IOException{
212 | 123 |
             final WorkerThread workerThread =
213 |  |
                     (WorkerThread)Thread.currentThread();
214 | 123 |
             ByteBuffer byteBuffer = workerThread.getByteBuffer();
215 | 123 |
             ByteBuffer outputBB = workerThread.getOutputBB();
216 | 123 |
             ByteBuffer inputBB = workerThread.getInputBB();
217 | 123 |
             SSLEngine sslEngine = workerThread.getSSLEngine();
218 |  |
219 | 123 |
             HandshakeStatus handshakeStatus = HandshakeStatus.NEED_UNWRAP;
220 |  |
221 | 123 |
             boolean OK = true;
222 |  |
             try{
223 | 123 |
                 byteBuffer = SSLUtils.doHandshake
224 |  |
                              ((SocketChannel) key.channel(), byteBuffer, inputBB,
225 |  |
                         outputBB, sslEngine, handshakeStatus, timeout);
226 | 122 |
                 if (doRead(key) == -1){
227 | 0 |
                     throw new EOFException();
228 |  |
                 }
229 | 1 |
             } catch (IOException ex) {
230 | 1 |
                 log("doHandshake", ex);
231 | 1 |
                 OK = false;
232 | 122 |
             }
233 | 123 |
             return OK;
234 |  |
         }
235 |  |
236 |  |
237 |  |
         private static int doRead(SelectionKey key) {
238 | 53200 |
             final WorkerThread workerThread =
239 |  |
                     (WorkerThread) Thread.currentThread();
240 | 53200 |
             ByteBuffer byteBuffer = workerThread.getByteBuffer();
241 | 53200 |
             ByteBuffer outputBB = workerThread.getOutputBB();
242 | 53200 |
             ByteBuffer inputBB = workerThread.getInputBB();
243 | 53200 |
             SSLEngine sslEngine = workerThread.getSSLEngine();
244 |  |
245 | 53200 |
             int count = -1;
246 |  |
             try {
247 |  |
                 // Read first bytes to avoid continuing if the client
248 |  |
                 // closed the connection.
249 | 53200 |
                 int initialBufferPosition = byteBuffer.position();
250 |  |
251 |  |
                 try {
252 | 53200 |
                     count = ((SocketChannel) key.channel()).read(inputBB);
253 | 0 |
                 } catch(IOException e) {
254 | 0 |
                     log("Exception during SSL read.", e);
255 | 0 |
                     count = -1;
256 | 53200 |
                 }
257 |  |
258 | 53200 |
                 if (count > -1 || inputBB.position() > 0) {
259 |  |
                     // Decrypt the bytes we just read.
260 | 53083 |
                     if (Controller.logger().isLoggable(Level.FINE)) {
261 | 0 |
                         Controller.logger().log(Level.FINE,
262 |  |
                                 "SSLReadFilter. Read: " + count +
263 |  |
                                 " Calling unwrapAll. InputBB: " +
264 |  |
                                 inputBB + " byteBuffer: " + byteBuffer);
265 |  |
                     }
266 |  |
267 | 53083 |
                     int initialInputBBPosition = inputBB.position();
268 | 53083 |
                     byteBuffer =
269 |  |
                             SSLUtils.unwrapAll(byteBuffer, inputBB, sslEngine);
270 | 53083 |
                     workerThread.setInputBB(inputBB);
271 | 53083 |
                     workerThread.setOutputBB(outputBB);
272 | 53083 |
                     workerThread.setByteBuffer(byteBuffer);
273 |  |
274 | 53083 |
                     if (count == -1 && byteBuffer.position() != initialBufferPosition) {
275 | 0 |
                         return initialInputBBPosition;
276 |  |
                     }
277 |  |
                 }
278 | 53200 |
                 return count;
279 | 0 |
             } catch (IOException ex) {
280 | 0 |
                 log("Exception during SSL read.", ex);
281 | 0 |
                 return -1;
282 |  |
             } finally {
283 | 53200 |
                 if (count == -1) {
284 |  |
                     try {
285 | 117 |
                         sslEngine.closeInbound();
286 | 0 |
                     } catch (SSLException ex) {
287 | 53317 |
                     }
288 |  |
                 }
289 |  |
             }
290 |  |
         }
291 |  |
292 |  |
293 |  |
         /**
294 |  |
          * Get the peer certificate list by initiating a new handshake.
295 |  |
          * @param key {@link SelectionKey}
296 |  |
          * @param needClientAuth
297 |  |
          * @return Object[] An array of X509Certificate.
298 |  |
          * @throws java.io.IOException
299 |  |
          */
300 |  |
         public static Object[] doPeerCertificateChain(SelectionKey key,
301 |  |
                 boolean needClientAuth) throws IOException {
302 |  |
303 | 0 |
             final WorkerThread workerThread =
304 |  |
                     (WorkerThread)Thread.currentThread();
305 | 0 |
             ByteBuffer byteBuffer = workerThread.getByteBuffer();
306 | 0 |
             ByteBuffer inputBB = workerThread.getInputBB();
307 | 0 |
             ByteBuffer outputBB = workerThread.getOutputBB();
308 | 0 |
             SSLEngine sslEngine = workerThread.getSSLEngine();
309 |  |
310 | 0 |
             return SSLUtils.doPeerCertificateChain((SocketChannel) key.channel(),
311 |  |
                     byteBuffer, inputBB, outputBB, sslEngine, needClientAuth,
312 |  |
                     InputReader.getDefaultReadTimeout());
313 |  |
         }
314 |  |
315 |  |
316 |  |
         /**
317 |  |
          * Return a new configured{@link SSLEngine}
318 |  |
          * @return a new configured{@link SSLEngine}
319 |  |
          */
320 |  |
         protected SSLEngine newSSLEngine(){
321 | 123 |
             SSLEngine sslEngine = sslContext.createSSLEngine();
322 | 123 |
             if (enabledCipherSuites != null){
323 | 0 |
                 if (!isCipherConfigured){
324 | 0 |
                     enabledCipherSuites = configureEnabledCiphers(sslEngine,
325 |  |
                                                             enabledCipherSuites);
326 | 0 |
                     isCipherConfigured = true;
327 |  |
                 }
328 | 0 |
                 sslEngine.setEnabledCipherSuites(enabledCipherSuites);
329 |  |
             }
330 |  |
331 | 123 |
             if (enabledProtocols != null){
332 | 0 |
                 if (!isProtocolConfigured) {
333 | 0 |
                     enabledProtocols = configureEnabledProtocols(sslEngine,
334 |  |
                                                         enabledProtocols);
335 | 0 |
                     isProtocolConfigured = true;
336 |  |
                 }
337 | 0 |
                 sslEngine.setEnabledProtocols(enabledProtocols);
338 |  |
             }
339 | 123 |
             sslEngine.setUseClientMode(clientMode);
340 | 123 |
             return sslEngine;
341 |  |
         }
342 |  |
343 |  |
344 |  |
         /**
345 |  |
          * Configure and return an instance of SSLEngine
346 |  |
          * @param key  a {@link SelectionKey}
347 |  |
          * @return  a configured instance of{@link SSLEngine}
348 |  |
          */
349 |  |
         protected SSLEngine newSSLEngine(SelectionKey key){
350 | 123 |
             SSLEngine sslEngine = null;
351 | 123 |
             if (key.attachment() instanceof ThreadAttachment) {
352 | 1 |
                 sslEngine = ((WorkerThread) Thread.currentThread()).getSSLEngine();
353 |  |
             }
354 |  |
355 | 123 |
             if (sslEngine == null) {
356 | 123 |
                sslEngine = newSSLEngine();
357 |  |
             }
358 |  |
359 | 123 |
             sslEngine.setWantClientAuth(wantClientAuth);
360 | 123 |
             sslEngine.setNeedClientAuth(needClientAuth);
361 | 123 |
             return sslEngine;
362 |  |
         }
363 |  |
364 |  |
         /**
365 |  |
          * Configures SSL settings. <code>SSLConfig</code> contains all the parameters
366 |  |
          * required to build{@link SSLEngine}. There will be no need to call
367 |  |
          * four methods: setSSLContext, setClientMode, setWantClientAuth,
368 |  |
          * setNeedClientAuth.
369 |  |
          * @param sslConfig <code>SSLConfig</code> configuration
370 |  |
          */
371 |  |
         public void configure(SSLConfig sslConfig) {
372 | 0 |
             sslContext = sslConfig.createSSLContext();
373 | 0 |
             wantClientAuth = sslConfig.isWantClientAuth();
374 | 0 |
             needClientAuth = sslConfig.isNeedClientAuth();
375 | 0 |
             clientMode = sslConfig.isClientMode();
376 | 0 |
         }
377 |  |
378 |  |
         /**
379 |  |
          * Set the SSLContext required to support SSL over NIO.
380 |  |
          * @param sslContext {@link SSLContext}
381 |  |
          */
382 |  |
         public void setSSLContext(SSLContext sslContext){
383 | 5 |
             this.sslContext = sslContext;
384 | 5 |
         }
385 |  |
386 |  |
387 |  |
         /**
388 |  |
          * Return the SSLContext required to support SSL over NIO.
389 |  |
          * @return {@link SSLContext}
390 |  |
          */
391 |  |
         public SSLContext getSSLContext(){
392 | 0 |
             return sslContext;
393 |  |
         }
394 |  |
395 |  |
396 |  |
         /**
397 |  |
          * Returns the list of cipher suites to be enabled when {@link SSLEngine}
398 |  |
          * is initialized.
399 |  |
          *
400 |  |
          * @return <tt>null</tt> means 'use {@link SSLEngine}'s default.'
401 |  |
          */
402 |  |
         public String[] getEnabledCipherSuites() {
403 | 0 |
             return enabledCipherSuites;
404 |  |
         }
405 |  |
406 |  |
407 |  |
         /**
408 |  |
          * Sets the list of cipher suites to be enabled when {@link SSLEngine}
409 |  |
          * is initialized.
410 |  |
          * @param enabledCipherSuites
411 |  |
          */
412 |  |
         public void setEnabledCipherSuites(String[] enabledCipherSuites) {
413 | 0 |
             this.enabledCipherSuites = enabledCipherSuites;
414 | 0 |
         }
415 |  |
416 |  |
417 |  |
         /**
418 |  |
          * Returns the list of protocols to be enabled when {@link SSLEngine}
419 |  |
          * is initialized.
420 |  |
          *
421 |  |
          * @return <tt>null</tt> means 'use {@link SSLEngine}'s default.'
422 |  |
          */
423 |  |
         public String[] getEnabledProtocols() {
424 | 0 |
             return enabledProtocols;
425 |  |
         }
426 |  |
427 |  |
428 |  |
         /**
429 |  |
          * Sets the list of protocols to be enabled when {@link SSLEngine}
430 |  |
          * is initialized.
431 |  |
          *
432 |  |
          * @param enabledProtocols <tt>null</tt> means 'use {@link SSLEngine}'s default.'
433 |  |
          */
434 |  |
         public void setEnabledProtocols(String[] enabledProtocols) {
435 | 0 |
             this.enabledProtocols = enabledProtocols;
436 | 0 |
         }
437 |  |
438 |  |
439 |  |
         /**
440 |  |
          * Returns <tt>true</tt> if the SSlEngine is set to use client mode
441 |  |
          * when handshaking.
442 |  |
          * @return true / false
443 |  |
          */
444 |  |
         public boolean isClientMode() {
445 | 0 |
             return clientMode;
446 |  |
         }
447 |  |
448 |  |
449 |  |
         /**
450 |  |
          * Configures the engine to use client (or server) mode when handshaking.
451 |  |
          * @param clientMode
452 |  |
          */
453 |  |
         public void setClientMode(boolean clientMode) {
454 | 0 |
             this.clientMode = clientMode;
455 | 0 |
         }
456 |  |
457 |  |
458 |  |
         /**
459 |  |
          * Returns <tt>true</tt> if the SSLEngine will <em>require</em>
460 |  |
          * client authentication.
461 |  |
          * @return
462 |  |
          */
463 |  |
         public boolean isNeedClientAuth() {
464 | 0 |
             return needClientAuth;
465 |  |
         }
466 |  |
467 |  |
468 |  |
         /**
469 |  |
          * Configures the engine to <em>require</em> client authentication.
470 |  |
          * @param needClientAuth
471 |  |
          */
472 |  |
         public void setNeedClientAuth(boolean needClientAuth) {
473 | 0 |
             this.needClientAuth = needClientAuth;
474 | 0 |
         }
475 |  |
476 |  |
477 |  |
         /**
478 |  |
          * Returns <tt>true</tt> if the engine will <em>request</em> client
479 |  |
          * authentication.
480 |  |
          * @return
481 |  |
          */
482 |  |
         public boolean isWantClientAuth() {
483 | 0 |
             return wantClientAuth;
484 |  |
         }
485 |  |
486 |  |
487 |  |
         /**
488 |  |
          * Configures the engine to <em>request</em> client authentication.
489 |  |
          * @param wantClientAuth
490 |  |
          */
491 |  |
         public void setWantClientAuth(boolean wantClientAuth) {
492 | 0 |
             this.wantClientAuth = wantClientAuth;
493 | 0 |
         }
494 |  |
495 |  |
496 |  |
         /**
497 |  |
          * Return the list of allowed protocol.
498 |  |
          * @return String[] an array of supported protocols.
499 |  |
          */
500 |  |
         private final static String[] configureEnabledProtocols(
501 |  |
                 SSLEngine sslEngine, String[] requestedProtocols){
502 |  |
503 | 0 |
             String[] supportedProtocols = sslEngine.getSupportedProtocols();
504 | 0 |
             String[] protocols = null;
505 | 0 |
             ArrayList<String> list = null;
506 | 0 |
             for(String supportedProtocol: supportedProtocols){
507 |  |
                 /*
508 |  |
                  * Check to see if the requested protocol is among the
509 |  |
                  * supported protocols, i.e., may be enabled
510 |  |
                  */
511 | 0 |
                 for(String protocol: requestedProtocols) {
512 | 0 |
                     protocol = protocol.trim();
513 | 0 |
                     if (supportedProtocol.equals(protocol)) {
514 | 0 |
                         if (list == null) {
515 | 0 |
                             list = new ArrayList<String>();
516 |  |
                         }
517 | 0 |
                         list.add(protocol);
518 | 0 |
                         break;
519 |  |
                     }
520 |  |
                 }
521 |  |
             }
522 |  |
523 | 0 |
             if (list != null) {
524 | 0 |
                 protocols = list.toArray(new String[list.size()]);
525 |  |
             }
526 |  |
527 | 0 |
             return protocols;
528 |  |
         }
529 |  |
530 |  |
531 |  |
         /**
532 |  |
          * Determines the SSL cipher suites to be enabled.
533 |  |
          *
534 |  |
          * @return Array of SSL cipher suites to be enabled, or null if none of the
535 |  |
          * requested ciphers are supported
536 |  |
          */
537 |  |
         private final static String[] configureEnabledCiphers(SSLEngine sslEngine,
538 |  |
                 String[] requestedCiphers) {
539 |  |
540 | 0 |
             String[] supportedCiphers = sslEngine.getSupportedCipherSuites();
541 | 0 |
             String[] ciphers = null;
542 | 0 |
             ArrayList<String> list = null;
543 | 0 |
             for(String supportedCipher: supportedCiphers){
544 |  |
                 /*
545 |  |
                  * Check to see if the requested protocol is among the
546 |  |
                  * supported protocols, i.e., may be enabled
547 |  |
                  */
548 | 0 |
                 for(String cipher: requestedCiphers) {
549 | 0 |
                     cipher = cipher.trim();
550 | 0 |
                     if (supportedCipher.equals(cipher)) {
551 | 0 |
                         if (list == null) {
552 | 0 |
                             list = new ArrayList<String>();
553 |  |
                         }
554 | 0 |
                         list.add(cipher);
555 | 0 |
                         break;
556 |  |
                     }
557 |  |
                 }
558 |  |
             }
559 |  |
560 | 0 |
             if (list != null) {
561 | 0 |
                 ciphers = list.toArray(new String[list.size()]);
562 |  |
             }
563 |  |
564 | 0 |
             return ciphers;
565 |  |
         }
566 |  |
567 |  |
         private void saveSecuredBufferRemainders(SelectionKey selectionKey) {
568 | 53083 |
             ThreadAttachment attachment =
569 |  |
                     (ThreadAttachment) selectionKey.attachment();
570 |  |
571 | 53083 |
             WorkerThread workerThread = (WorkerThread) Thread.currentThread();
572 |  |
573 | 53083 |
             if (attachment == null || workerThread.getAttachment() != attachment) {
574 | 0 |
                 Controller.logger().log(Level.FINE,
575 |  |
                         "SelectionKey ThreadAttachment is NULL or doesn't " +
576 |  |
                         "correspond to the current thread, when saving buffers");
577 | 0 |
                 return;
578 |  |
             }
579 |  |
580 | 53083 |
             ByteBuffer inputBB = workerThread.getInputBB();
581 | 53083 |
             if (inputBB != null && inputBB.hasRemaining()) {
582 | 53083 |
                 workerThread.updateAttachment(attachment.getMode() | Mode.INPUT_BB);
583 |  |
             } else {
584 | 0 |
                 workerThread.updateAttachment(attachment.getMode() &
585 |  |
                         (Integer.MAX_VALUE ^ Mode.INPUT_BB));
586 |  |
             }
587 |  |
588 | 53083 |
             ByteBuffer outputBB = workerThread.getOutputBB();
589 | 53083 |
             if (outputBB != null && outputBB.hasRemaining()) {
590 | 101 |
                 workerThread.updateAttachment(attachment.getMode() | Mode.OUTPUT_BB);
591 |  |
             } else {
592 | 52982 |
                 workerThread.updateAttachment(attachment.getMode() &
593 |  |
                         (Integer.MAX_VALUE ^ Mode.OUTPUT_BB));
594 |  |
             }
595 | 53083 |
         }
596 |  |
597 |  |
         /**
598 |  |
          * Log a message/exception.
599 |  |
          * @param msg <code>String</code>
600 |  |
          * @param t <code>Throwable</code>
601 |  |
          */
602 |  |
         protected static void log(String msg, Throwable t) {
603 | 1 |
             if (Controller.logger().isLoggable(Level.FINE)) {
604 | 0 |
                 Controller.logger().log(Level.FINE, msg, t);
605 |  |
             }
606 | 1 |
         }
607 |  |
     }