use of javax.net.ssl.SSLEngineResult in project ignite by apache.
the class GridNioSslHandler method closeOutbound.
/**
* Writes close_notify message to the network output buffer.
*
* @throws SSLException If wrap failed or SSL engine does not get closed
* after wrap.
* @return {@code True} if <tt>close_notify</tt> message was encoded, {@code false} if outbound
* stream was already closed.
*/
boolean closeOutbound() throws SSLException {
assert isHeldByCurrentThread();
if (!sslEngine.isOutboundDone()) {
sslEngine.closeOutbound();
outNetBuf.clear();
SSLEngineResult res = sslEngine.wrap(handshakeBuf, outNetBuf);
if (res.getStatus() != CLOSED)
throw new SSLException("Incorrect SSL engine status after closeOutbound call [status=" + res.getStatus() + ", handshakeStatus=" + res.getHandshakeStatus() + ", ses=" + ses + ']');
outNetBuf.flip();
return true;
}
return false;
}
use of javax.net.ssl.SSLEngineResult in project baseio by generallycloud.
the class SslHandler method wrap.
public ByteBuf wrap(SocketChannel channel, ByteBuf src) throws IOException {
SSLEngine engine = channel.getSSLEngine();
ByteBuf dst = getTempDst(engine);
ByteBuf out = null;
try {
for (; ; ) {
dst.clear();
SSLEngineResult result = engine.wrap(src.nioBuffer(), dst.nioBuffer());
Status status = result.getStatus();
HandshakeStatus handshakeStatus = result.getHandshakeStatus();
synchByteBuf(result, src, dst);
if (status == Status.CLOSED) {
return gc(channel, dst.flip());
}
if (handshakeStatus != HandshakeStatus.NOT_HANDSHAKING) {
if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
if (out != null) {
out.read(dst.flip());
return out.flip();
}
return gc(channel, dst.flip());
} else if (handshakeStatus == HandshakeStatus.NEED_WRAP) {
if (out == null) {
out = allocate(channel, 256);
}
out.read(dst.flip());
continue;
} else if (handshakeStatus == HandshakeStatus.FINISHED) {
channel.finishHandshake(null);
out.read(dst.flip());
return out.flip();
} else if (handshakeStatus == HandshakeStatus.NEED_TASK) {
runDelegatedTasks(engine);
continue;
}
}
if (src.hasRemaining()) {
if (out == null) {
int outLength = ((src.limit() / src.position()) + 1) * (dst.position() - src.position()) + src.limit();
out = allocate(channel, outLength);
}
out.read(dst.flip());
continue;
}
if (out != null) {
out.read(dst.flip());
return out.flip();
}
return gc(channel, dst.flip());
}
} catch (Throwable e) {
ReleaseUtil.release(out);
if (e instanceof IOException) {
throw (IOException) e;
}
throw new IOException(e);
}
}
use of javax.net.ssl.SSLEngineResult in project baseio by generallycloud.
the class SslHandler method unwrap.
public ByteBuf unwrap(SocketChannel channel, ByteBuf src) throws IOException {
SSLEngine sslEngine = channel.getSSLEngine();
ByteBuf dst = getTempDst(sslEngine);
for (; ; ) {
dst.clear();
SSLEngineResult result = sslEngine.unwrap(src.nioBuffer(), dst.nioBuffer());
HandshakeStatus handshakeStatus = result.getHandshakeStatus();
synchByteBuf(result, src, dst);
if (handshakeStatus != HandshakeStatus.NOT_HANDSHAKING) {
if (handshakeStatus == HandshakeStatus.NEED_WRAP) {
channel.doFlush(forgeFuture.duplicate());
return null;
} else if (handshakeStatus == HandshakeStatus.NEED_TASK) {
runDelegatedTasks(sslEngine);
continue;
} else if (handshakeStatus == HandshakeStatus.FINISHED) {
channel.finishHandshake(null);
return null;
} else if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
return null;
}
}
return dst.flip();
}
}
use of javax.net.ssl.SSLEngineResult in project jersey by jersey.
the class SslFilter method doHandshakeStep.
private boolean doHandshakeStep(ByteBuffer networkData) {
/* Buffer used to store application data read during this handshake step.
Application data can be interleaved with handshake messages only during re-handshake.
We don't use applicationInputBuffer, because we might want to store more than one packet */
LazyBuffer inputBuffer = new LazyBuffer();
boolean handshakeFinished = false;
synchronized (this) {
if (SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING.equals(sslEngine.getHandshakeStatus())) {
// we stopped handshaking while waiting for the lock
return true;
}
try {
/* we don't use networkOutputBuffer, because there might be a write operation still in progress ->
we don't want to corrupt the buffer it is using */
LazyBuffer outputBuffer = new LazyBuffer();
boolean stepFinished = false;
while (!stepFinished) {
SSLEngineResult.HandshakeStatus hs = sslEngine.getHandshakeStatus();
switch(hs) {
case NOT_HANDSHAKING:
{
throw new IllegalStateException("Trying to handshake, but SSL engine not in HANDSHAKING state." + "SSL filter state: \n" + getDebugState());
}
case FINISHED:
{
/* According to SSLEngine javadoc FINISHED status can be returned only in SSLEngineResult,
but just to make sure we don't end up in an infinite loop when presented with an SSLEngine
implementation that does not respect this:*/
stepFinished = true;
handshakeFinished = true;
break;
}
// needs to write data to the network
case NEED_WRAP:
{
ByteBuffer byteBuffer = outputBuffer.get();
SSLEngineResult result = sslEngine.wrap(emptyBuffer, byteBuffer);
if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
stepFinished = true;
handshakeFinished = true;
}
switch(result.getStatus()) {
case BUFFER_OVERFLOW:
{
outputBuffer.resize();
break;
}
case BUFFER_UNDERFLOW:
{
/* This basically says that there is not enough data to create an SSL packet. Javadoc suggests
that BUFFER_UNDERFLOW can occur only after unwrap(), but to be 100% sure we handle all
possible error states: */
throw new IllegalStateException("SSL engine underflow with the following SSL filter " + "state: \n" + getDebugState());
}
case CLOSED:
{
stepFinished = true;
state = State.CLOSED;
break;
}
}
break;
}
case NEED_UNWRAP:
{
SSLEngineResult result = sslEngine.unwrap(networkData, applicationInputBuffer);
applicationInputBuffer.flip();
if (applicationInputBuffer.hasRemaining()) {
// data can flow during re-handshake
inputBuffer.append(applicationInputBuffer);
}
applicationInputBuffer.compact();
if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
stepFinished = true;
handshakeFinished = true;
}
switch(result.getStatus()) {
case BUFFER_OVERFLOW:
{
/* This means that the content of the ssl packet (max 16kB) did not fit into
applicationInputBuffer, but we make sure to set applicationInputBuffer > max 16kB
when initializing this filter. This indicates a bug. */
throw new IllegalStateException("SSL packet does not fit into the network buffer: " + getDebugState());
}
case BUFFER_UNDERFLOW:
{
// indicate that we won't get more from this buffer
stepFinished = true;
break;
}
case CLOSED:
{
stepFinished = true;
state = State.CLOSED;
break;
}
}
break;
}
// needs to execute long running task (for instance validating certificates)
case NEED_TASK:
{
Runnable delegatedTask;
while ((delegatedTask = sslEngine.getDelegatedTask()) != null) {
delegatedTask.run();
}
break;
}
}
}
// now write the stored wrap() results
if (outputBuffer.isAllocated()) {
ByteBuffer buffer = outputBuffer.get();
buffer.flip();
writeQueue.write(buffer, null);
}
} catch (Exception e) {
handleSslError(e);
}
}
/* Handle any read data.
We have to execute upstreamFilter.onRead after releasing the lock. See the synchronization note on top.
Only one read operation can be in progress at a time, so even though we have released the lock, no other
SSlEngine#unwrap can be performed until this method returns. So there is no chance of the read data
being mixed up */
if (inputBuffer.isAllocated()) {
ByteBuffer buffer = inputBuffer.get();
upstreamFilter.onRead(buffer);
}
if (handshakeFinished) {
handleHandshakeFinished();
// indicate that there still might be usable data in the input buffer
return true;
}
/* if we are here, it means that we are waiting for more data -> indicate that there is nothing usable in the
input buffer left */
return false;
}
use of javax.net.ssl.SSLEngineResult in project jersey by jersey.
the class SslFilter method handleRead.
private boolean handleRead(ByteBuffer networkData) {
try {
applicationInputBuffer.clear();
SSLEngineResult result = sslEngine.unwrap(networkData, applicationInputBuffer);
switch(result.getStatus()) {
case BUFFER_OVERFLOW:
{
/* This means that the content of the ssl packet (max 16kB) did not fit into
applicationInputBuffer, but we make sure to set applicationInputBuffer > max 16kB
when initializing this filter. This indicates a bug.*/
throw new IllegalStateException("Contents of a SSL packet did not fit into buffer: " + applicationInputBuffer + "\n" + getDebugState());
}
case BUFFER_UNDERFLOW:
{
// the ssl packet is not full, return and indicate that we won't get more from this buffer
return false;
}
case CLOSED:
case OK:
{
if (result.bytesProduced() > 0) {
applicationInputBuffer.flip();
upstreamFilter.onRead(applicationInputBuffer);
applicationInputBuffer.compact();
}
if (sslEngine.isInboundDone()) {
// signal that there is nothing useful left in this buffer
return false;
}
// we started re-handshaking
if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING && // make sure we don't confuse re-handshake with closing handshake
!sslEngine.isOutboundDone()) {
state = State.REHANDSHAKING;
return doHandshakeStep(networkData);
}
break;
}
}
} catch (SSLException e) {
handleSslError(e);
}
return true;
}
Aggregations