Skip to content

Commit

Permalink
Initial implementation of SSLEngine.wrap
Browse files Browse the repository at this point in the history
- SSLEngine now works for some simple cases
  • Loading branch information
peterdettman committed Apr 8, 2017
1 parent cef3119 commit 2433690
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,11 @@ public synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, in
bytesConsumed += buf.length;
}

int appDataAvailable = protocol.getAvailableInputBytes();
for (int dstIndex = 0; dstIndex < length && appDataAvailable > 0; ++dstIndex)
int inputAvailable = protocol.getAvailableInputBytes();
for (int dstIndex = 0; dstIndex < length && inputAvailable > 0; ++dstIndex)
{
ByteBuffer dst = dsts[dstIndex];
int count = Math.min(dst.remaining(), appDataAvailable);
int count = Math.min(dst.remaining(), inputAvailable);

byte[] input = new byte[count];
int numRead = protocol.readInput(input, 0, count);
Expand All @@ -348,18 +348,22 @@ public synchronized SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, in
dst.put(input);

bytesProduced += count;
appDataAvailable -= count;
inputAvailable -= count;
}

Status returnStatus = Status.OK;
if (appDataAvailable > 0)
if (inputAvailable > 0)
{
returnStatus = Status.BUFFER_OVERFLOW;
}
else if (protocol.isClosed())
{
returnStatus = Status.CLOSED;
}
else if (bytesConsumed == 0)
{
returnStatus = Status.BUFFER_UNDERFLOW;
}

determineHandshakeStatus();

Expand All @@ -376,22 +380,89 @@ else if (protocol.isClosed())
public synchronized SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst)
throws SSLException
{
throw new UnsupportedOperationException();
// TODO[jsse] Argument checks - see javadoc

if (!initialHandshakeBegun)
{
beginHandshake();
}

HandshakeStatus prevHandshakeStatus = handshakeStatus;
int bytesConsumed = 0, bytesProduced = 0;

if (!protocol.isClosed() && connection != null && handshakeStatus != HandshakeStatus.NEED_WRAP)
{
for (int srcIndex = 0; srcIndex < length; ++srcIndex)
{
ByteBuffer src = srcs[srcIndex];
int count = src.remaining();

byte[] input = new byte[count];
src.get(input);

try
{
protocol.writeApplicationData(input, 0, count);
}
catch (IOException e)
{
// TODO[jsse] Throw a subclass of SSLException?
throw new SSLException(e);
}

bytesConsumed += count;
}
}

int outputAvailable = protocol.getAvailableOutputBytes();
if (outputAvailable > 0)
{
int count = Math.min(dst.remaining(), outputAvailable);

byte[] output = new byte[count];
int numRead = protocol.readOutput(output, 0, count);
assert numRead == count;

dst.put(output);

bytesProduced += count;
outputAvailable -= count;
}

Status returnStatus = Status.OK;
if (outputAvailable > 0)
{
returnStatus = Status.BUFFER_OVERFLOW;
}
else if (protocol.isClosed())
{
returnStatus = Status.CLOSED;
}

determineHandshakeStatus();

HandshakeStatus returnHandshakeStatus = handshakeStatus;
if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING && prevHandshakeStatus != HandshakeStatus.NOT_HANDSHAKING)
{
returnHandshakeStatus = HandshakeStatus.FINISHED;
}

return new SSLEngineResult(returnStatus, returnHandshakeStatus, bytesConsumed, bytesProduced);
}

protected void determineHandshakeStatus()
{
// NOTE: We currently never delegate tasks (will never have status HandshakeStatus.NEED_TASK)

if (!initialHandshakeBegun || protocolPeer.isHandshakeComplete())
if (!initialHandshakeBegun)
{
handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
}
else if (protocol.getAvailableOutputBytes() > 0)
{
handshakeStatus = HandshakeStatus.NEED_WRAP;
}
else if (protocol.isClosed())
else if (protocol.isClosed() || protocolPeer.isHandshakeComplete())
{
handshakeStatus = HandshakeStatus.NOT_HANDSHAKING;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class ProvSSLSession

public int getApplicationBufferSize()
{
throw new UnsupportedOperationException();
// TODO[jsse] See comments for getPacketBufferSize
return 1 << 14;
}

public String getCipherSuite()
Expand Down Expand Up @@ -90,7 +91,13 @@ public Principal getLocalPrincipal()

public int getPacketBufferSize()
{
throw new UnsupportedOperationException();
/*
* TODO[jsse] This is the maximum possible per RFC (but see jsse.SSLEngine.acceptLargeFragments System property).
* It would be nice to dynamically check with the underlying RecordStream, which might know a tighter limit, e.g.
* when the max_fragment_length extension has been negotiated, or when no compression was negotiated).
*/
// Header size + Fragment length limit + Compression expansion + Cipher expansion
return 5 + (1 << 14) + 1024 + 1024;
}

public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException
Expand Down

0 comments on commit 2433690

Please sign in to comment.