@@ -215,6 +215,7 @@ protected void consumeDelegatedTasks() {
215
215
}
216
216
217
217
protected void createBuffers ( SSLSession session ) {
218
+ saveCryptedData (); // save any remaining data in inCrypt
218
219
int netBufferMax = session .getPacketBufferSize ();
219
220
int appBufferMax = Math .max (session .getApplicationBufferSize (), netBufferMax );
220
221
@@ -269,6 +270,7 @@ public int write( ByteBuffer src ) throws IOException {
269
270
* @return the number of bytes read.
270
271
**/
271
272
public int read (ByteBuffer dst ) throws IOException {
273
+ tryRestoreCryptedData ();
272
274
while (true ) {
273
275
if (!dst .hasRemaining ())
274
276
return 0 ;
@@ -329,6 +331,7 @@ private int readRemaining( ByteBuffer dst ) throws SSLException {
329
331
}
330
332
if ( !inData .hasRemaining () )
331
333
inData .clear ();
334
+ tryRestoreCryptedData ();
332
335
// test if some bytes left from last read (e.g. BUFFER_UNDERFLOW)
333
336
if ( inCrypt .hasRemaining () ) {
334
337
unwrap ();
@@ -396,7 +399,7 @@ public void writeMore() throws IOException {
396
399
397
400
@ Override
398
401
public boolean isNeedRead () {
399
- return inData .hasRemaining () || ( inCrypt .hasRemaining () && readEngineResult .getStatus () != Status .BUFFER_UNDERFLOW && readEngineResult .getStatus () != Status .CLOSED );
402
+ return saveCryptData != null || inData .hasRemaining () || ( inCrypt .hasRemaining () && readEngineResult .getStatus () != Status .BUFFER_UNDERFLOW && readEngineResult .getStatus () != Status .CLOSED );
400
403
}
401
404
402
405
@ Override
@@ -430,4 +433,31 @@ public boolean isBlocking() {
430
433
public SSLEngine getSSLEngine () {
431
434
return sslEngine ;
432
435
}
436
+
437
+
438
+ // to avoid complexities with inCrypt, extra unwrapped data after SSL handshake will be saved off in a byte array
439
+ // and the inserted back on first read
440
+ private byte [] saveCryptData = null ;
441
+ private void saveCryptedData ()
442
+ {
443
+ // did we find any extra data?
444
+ if (inCrypt != null && inCrypt .remaining () > 0 )
445
+ {
446
+ int saveCryptSize = inCrypt .remaining ();
447
+ saveCryptData = new byte [saveCryptSize ];
448
+ inCrypt .get (saveCryptData );
449
+ }
450
+ }
451
+
452
+ private void tryRestoreCryptedData ()
453
+ {
454
+ // was there any extra data, then put into inCrypt and clean up
455
+ if ( saveCryptData != null )
456
+ {
457
+ inCrypt .clear ();
458
+ inCrypt .put ( saveCryptData );
459
+ inCrypt .flip ();
460
+ saveCryptData = null ;
461
+ }
462
+ }
433
463
}
0 commit comments