Skip to content

Commit 89eaf41

Browse files
committed
suggested fix for issue 665 "data read at end of SSL handshake is discarded"
1 parent 9709433 commit 89eaf41

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/main/java/org/java_websocket/SSLSocketChannel2.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ protected void consumeDelegatedTasks() {
215215
}
216216

217217
protected void createBuffers( SSLSession session ) {
218+
saveCryptedData(); // save any remaining data in inCrypt
218219
int netBufferMax = session.getPacketBufferSize();
219220
int appBufferMax = Math.max(session.getApplicationBufferSize(), netBufferMax);
220221

@@ -269,6 +270,7 @@ public int write( ByteBuffer src ) throws IOException {
269270
* @return the number of bytes read.
270271
**/
271272
public int read(ByteBuffer dst) throws IOException {
273+
tryRestoreCryptedData();
272274
while (true) {
273275
if (!dst.hasRemaining())
274276
return 0;
@@ -329,6 +331,7 @@ private int readRemaining( ByteBuffer dst ) throws SSLException {
329331
}
330332
if( !inData.hasRemaining() )
331333
inData.clear();
334+
tryRestoreCryptedData();
332335
// test if some bytes left from last read (e.g. BUFFER_UNDERFLOW)
333336
if( inCrypt.hasRemaining() ) {
334337
unwrap();
@@ -396,7 +399,7 @@ public void writeMore() throws IOException {
396399

397400
@Override
398401
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 );
400403
}
401404

402405
@Override
@@ -430,4 +433,31 @@ public boolean isBlocking() {
430433
public SSLEngine getSSLEngine() {
431434
return sslEngine;
432435
}
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+
}
433463
}

0 commit comments

Comments
 (0)