use of javax.net.ssl.SSLEngineResult.Status in project webpieces by deanhiller.
the class AsyncSSLEngine2Impl method feedPlainPacketImpl.
public XFuture<Void> feedPlainPacketImpl(ByteBuffer buffer) throws SSLException {
if (mem.getConnectionState() != ConnectionState.CONNECTED)
throw new IllegalStateException(mem + " SSLEngine is not connected right now");
else if (!buffer.hasRemaining())
throw new IllegalArgumentException("your buffer has no readable data");
SSLEngine sslEngine = mem.getEngine();
if (log.isTraceEnabled())
log.trace(mem + "feedPlainPacket [in-buffer] pos=" + buffer.position() + " lim=" + buffer.limit());
XFuture<Void> future = encryptionTracker.addBytesToTrack(buffer.remaining());
while (buffer.hasRemaining()) {
ByteBuffer engineToSocketData = pool.nextBuffer(sslEngine.getSession().getPacketBufferSize());
int remainBefore = buffer.remaining();
synchronized (wrapLock) {
SSLEngineResult result = sslEngine.wrap(buffer, engineToSocketData);
int numEncrypted = remainBefore - buffer.remaining();
Status status = result.getStatus();
HandshakeStatus hsStatus = result.getHandshakeStatus();
if (status != Status.OK)
throw new RuntimeException("Bug, status=" + status + " instead of OK. hsStatus=" + hsStatus + " Something went wrong and we could not encrypt the data");
if (log.isTraceEnabled())
log.trace(mem + "SSLListener.packetEncrypted pos=" + engineToSocketData.position() + " lim=" + engineToSocketData.limit() + " hsStatus=" + hsStatus + " status=" + status);
engineToSocketData.flip();
listener.packetEncrypted(engineToSocketData).handle((v, t) -> {
if (t != null)
log.error("Exception from ssl listener", t);
encryptionTracker.ackBytes(numEncrypted);
return null;
});
}
}
pool.releaseBuffer(buffer);
return future;
}
use of javax.net.ssl.SSLEngineResult.Status in project webpieces by deanhiller.
the class AsyncSSLEngine2Impl method feedEncryptedPacketImpl.
private XFuture<Void> feedEncryptedPacketImpl(ByteBuffer encryptedInData, XFuture<Void> byteAcker) {
SSLEngine sslEngine = mem.getEngine();
HandshakeStatus hsStatus = sslEngine.getHandshakeStatus();
Status status = null;
logTrace1(encryptedInData, hsStatus);
ByteBuffer encryptedData = encryptedInData;
ByteBuffer cached = mem.getCachedToProcess();
if (cached != null) {
encryptedData = combine(cached, encryptedData);
mem.setCachedEncryptedData(null);
}
int i = 0;
// stay in loop while we
// 1. need unwrap or not_handshaking or need_task AND
// 2. have data in buffer
// 3. have enough data in buffer(ie. not underflow)
int totalToAck = 0;
while (encryptedData.hasRemaining() && status != Status.BUFFER_UNDERFLOW && status != Status.CLOSED) {
i++;
SSLEngineResult result;
ByteBuffer outBuffer = mem.getCachedOut();
int remainBeforeDecrypt = encryptedData.remaining();
try {
result = sslEngine.unwrap(encryptedData, outBuffer);
status = result.getStatus();
} catch (SSLException e) {
AsyncSSLEngineException ee = new AsyncSSLEngineException("status=" + status + " hsStatus=" + hsStatus + " b=" + encryptedData, e);
throw ee;
} finally {
int totalBytesToAck = remainBeforeDecrypt - encryptedData.remaining();
if (outBuffer.position() != 0) {
outBuffer.flip();
listener.packetUnencrypted(outBuffer).handle((v, t) -> {
if (t != null)
log.error("Exception in ssl listener", t);
decryptionTracker.ackBytes(totalBytesToAck);
return null;
});
// frequently the out buffer is not used so we only ask the pool for buffers AFTER it has been consumed/used
ByteBuffer newCachedOut = pool.nextBuffer(sslEngine.getSession().getApplicationBufferSize());
mem.setCachedOut(newCachedOut);
} else {
totalToAck += totalBytesToAck;
}
}
status = result.getStatus();
hsStatus = result.getHandshakeStatus();
if (hsStatus == HandshakeStatus.NEED_TASK || hsStatus == HandshakeStatus.NEED_WRAP) {
// handshake as well
break;
}
logAndCheck(encryptedData, result, outBuffer, status, hsStatus, i);
}
if (encryptedData.hasRemaining()) {
mem.setCachedEncryptedData(encryptedData);
}
logTrace(encryptedData, status, hsStatus);
if (!encryptedData.hasRemaining())
pool.releaseBuffer(encryptedData);
int bytesToAck = totalToAck;
return cleanAndFire(hsStatus, status).thenApply(v -> {
decryptionTracker.ackBytes(bytesToAck);
return null;
}).thenCompose(v -> byteAcker);
}
use of javax.net.ssl.SSLEngineResult.Status in project baseio by generallycloud.
the class Channel method wrap.
private ByteBuf wrap(ByteBuf src) throws IOException {
SSLEngine engine = getSSLEngine();
ByteBufAllocator alloc = alloc();
ByteBuf out = null;
try {
if (ssl_handshake_finished) {
byte sslWrapExt = this.ssl_wrap_ext;
if (sslWrapExt == 0) {
out = alloc.allocate(guess_wrap_out(src.readableBytes(), 0xff + 1));
} else {
out = alloc.allocate(guess_wrap_out(src.readableBytes(), sslWrapExt & 0xff));
}
final int SSL_PACKET_BUFFER_SIZE = SslContext.SSL_PACKET_BUFFER_SIZE;
for (; ; ) {
SSLEngineResult result = engine.wrap(src.nioReadBuffer(), out.nioWriteBuffer());
Status status = result.getStatus();
sync_buf(src, out);
if (status == Status.CLOSED) {
return out;
} else if (status == Status.BUFFER_OVERFLOW) {
out.expansion(out.capacity() + SSL_PACKET_BUFFER_SIZE);
continue;
} else {
if (src.hasReadableBytes()) {
continue;
}
if (sslWrapExt == 0) {
int srcLen = src.writeIndex();
int outLen = out.readIndex();
int y = ((srcLen + 1) / SSL_PACKET_BUFFER_SIZE) + 1;
int u = ((outLen - srcLen) / y) * 2;
this.ssl_wrap_ext = (byte) u;
}
return out;
}
}
} else {
ByteBuf dst = FastThreadLocal.get().getSslWrapBuf();
for (; ; ) {
dst.clear();
SSLEngineResult result = engine.wrap(src.nioReadBuffer(), dst.nioWriteBuffer());
Status status = result.getStatus();
HandshakeStatus handshakeStatus = result.getHandshakeStatus();
sync_buf(src, dst);
if (status == Status.CLOSED) {
return swap(alloc, dst);
}
if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
if (out != null) {
out.writeBytes(dst);
return out;
}
return swap(alloc, dst);
} else if (handshakeStatus == HandshakeStatus.NEED_WRAP) {
if (out == null) {
out = alloc.allocate(256);
}
out.writeBytes(dst);
continue;
} else if (handshakeStatus == HandshakeStatus.FINISHED) {
finish_handshake();
if (out != null) {
out.writeBytes(dst);
return out;
}
return swap(alloc, dst);
} else if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING) {
// It is shouldn't here to have "NOT_HANDSHAKING", because of the ssl is closed?
throw SSL_WRAP_CLOSED;
} else if (handshakeStatus == HandshakeStatus.NEED_TASK) {
run_delegated_tasks(engine);
continue;
}
}
}
} catch (Throwable e) {
release(out);
if (e instanceof IOException) {
throw (IOException) e;
}
throw new IOException(e);
}
}
use of javax.net.ssl.SSLEngineResult.Status in project webpieces by deanhiller.
the class AsyncSSLEngine2Impl method feedEncryptedPacketImpl.
private void feedEncryptedPacketImpl(ByteBuffer encryptedInData) {
SSLEngine sslEngine = mem.getEngine();
HandshakeStatus hsStatus = sslEngine.getHandshakeStatus();
Status status = null;
final HandshakeStatus hsStatus2 = hsStatus;
log.trace(() -> mem + "[sockToEngine] going to unwrap pos=" + encryptedInData.position() + " lim=" + encryptedInData.limit() + " hsStatus=" + hsStatus2 + " cached=" + mem.getCachedToProcess());
ByteBuffer encryptedData = encryptedInData;
ByteBuffer cached = mem.getCachedToProcess();
if (cached != null) {
encryptedData = combine(cached, encryptedData);
mem.setCachedEncryptedData(null);
}
int i = 0;
//3. have enough data in buffer(ie. not underflow)
while (encryptedData.hasRemaining() && status != Status.BUFFER_UNDERFLOW && status != Status.CLOSED) {
i++;
SSLEngineResult result;
ByteBuffer outBuffer = mem.getCachedOut();
try {
result = sslEngine.unwrap(encryptedData, outBuffer);
} catch (SSLException e) {
AsyncSSLEngineException ee = new AsyncSSLEngineException("status=" + status + " hsStatus=" + hsStatus + " b=" + encryptedData, e);
throw ee;
} finally {
if (outBuffer.position() != 0) {
outBuffer.flip();
listener.packetUnencrypted(outBuffer);
//frequently the out buffer is not used so we only ask the pool for buffers AFTER it has been consumed/used
ByteBuffer newCachedOut = pool.nextBuffer(sslEngine.getSession().getApplicationBufferSize());
mem.setCachedOut(newCachedOut);
}
}
status = result.getStatus();
hsStatus = result.getHandshakeStatus();
final ByteBuffer data = encryptedData;
final Status status2 = status;
final HandshakeStatus hsStatus3 = hsStatus;
log.trace(() -> mem + "[sockToEngine] unwrap done pos=" + data.position() + " lim=" + data.limit() + " status=" + status2 + " hs=" + hsStatus3);
if (i > 1000)
throw new RuntimeException(this + "Bug, stuck in loop, bufIn=" + encryptedData + " bufOut=" + outBuffer + " hsStatus=" + hsStatus + " status=" + status);
else if (hsStatus == HandshakeStatus.NEED_TASK) {
//messages?
break;
} else if (status == Status.BUFFER_UNDERFLOW) {
final ByteBuffer data1 = encryptedData;
log.trace(() -> "buffer underflow. data=" + data1.remaining());
}
}
if (encryptedData.hasRemaining()) {
mem.setCachedEncryptedData(encryptedData);
}
final ByteBuffer data2 = encryptedData;
final Status status2 = status;
final HandshakeStatus hsStatus3 = hsStatus;
log.trace(() -> mem + "[sockToEngine] reset pos=" + data2.position() + " lim=" + data2.limit() + " status=" + status2 + " hs=" + hsStatus3);
cleanAndFire(hsStatus, status, encryptedData);
}
use of javax.net.ssl.SSLEngineResult.Status in project nifi by apache.
the class SSLSocketChannel method write.
public void write(final byte[] data, final int offset, final int len) throws IOException {
logger.debug("{} Writing {} bytes of data", this, len);
if (!connected) {
connect();
}
int iterations = len / MAX_WRITE_SIZE;
if (len % MAX_WRITE_SIZE > 0) {
iterations++;
}
for (int i = 0; i < iterations; i++) {
streamOutManager.clear();
final int itrOffset = offset + i * MAX_WRITE_SIZE;
final int itrLen = Math.min(len - itrOffset, MAX_WRITE_SIZE);
final ByteBuffer byteBuffer = ByteBuffer.wrap(data, itrOffset, itrLen);
final BufferStateManager buffMan = new BufferStateManager(byteBuffer, Direction.READ);
final Status status = encryptAndWriteFully(buffMan);
switch(status) {
case BUFFER_OVERFLOW:
streamOutManager.ensureSize(engine.getSession().getPacketBufferSize());
appDataManager.ensureSize(engine.getSession().getApplicationBufferSize());
continue;
case OK:
continue;
case CLOSED:
throw new IOException("Channel is closed");
case BUFFER_UNDERFLOW:
throw new AssertionError("Got Buffer Underflow but should not have...");
}
}
}
Aggregations