Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge pull request #943 from da-als/master #943

Merged
merged 3 commits into from Jan 19, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/main/java/org/java_websocket/SSLSocketChannel2.java
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;
}
}
}