Skip to content

Commit

Permalink
suggested fix for issue 665 "data read at end of SSL handshake is dis…
Browse files Browse the repository at this point in the history
…carded"
  • Loading branch information
doyledavidson committed Sep 9, 2019
1 parent 9709433 commit 89eaf41
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion src/main/java/org/java_websocket/SSLSocketChannel2.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ protected void consumeDelegatedTasks() {
}

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

Expand Down Expand Up @@ -269,6 +270,7 @@ public int write( ByteBuffer src ) throws IOException {
* @return the number of bytes read.
**/
public int read(ByteBuffer dst) throws IOException {
tryRestoreCryptedData();
while (true) {
if (!dst.hasRemaining())
return 0;
Expand Down Expand Up @@ -329,6 +331,7 @@ private int readRemaining( ByteBuffer dst ) throws SSLException {
}
if( !inData.hasRemaining() )
inData.clear();
tryRestoreCryptedData();
// test if some bytes left from last read (e.g. BUFFER_UNDERFLOW)
if( inCrypt.hasRemaining() ) {
unwrap();
Expand Down Expand Up @@ -396,7 +399,7 @@ public void writeMore() throws IOException {

@Override
public boolean isNeedRead() {
return inData.hasRemaining() || ( inCrypt.hasRemaining() && readEngineResult.getStatus() != Status.BUFFER_UNDERFLOW && readEngineResult.getStatus() != Status.CLOSED );
return saveCryptData != null || inData.hasRemaining() || ( inCrypt.hasRemaining() && readEngineResult.getStatus() != Status.BUFFER_UNDERFLOW && readEngineResult.getStatus() != Status.CLOSED );
}

@Override
Expand Down Expand Up @@ -430,4 +433,31 @@ public boolean isBlocking() {
public SSLEngine getSSLEngine() {
return sslEngine;
}


// to avoid complexities with inCrypt, extra unwrapped data after SSL handshake will be saved off in a byte array
// and the inserted back on first read
private byte[] saveCryptData = null;
private void saveCryptedData()
{
// did we find any extra data?
if (inCrypt != null && inCrypt.remaining() > 0)
{
int saveCryptSize = inCrypt.remaining();
saveCryptData = new byte[saveCryptSize];
inCrypt.get(saveCryptData);
}
}

private void tryRestoreCryptedData()
{
// was there any extra data, then put into inCrypt and clean up
if ( saveCryptData != null )
{
inCrypt.clear();
inCrypt.put( saveCryptData );
inCrypt.flip();
saveCryptData = null;
}
}
}

0 comments on commit 89eaf41

Please sign in to comment.