use of javax.net.ssl.SSLEngineResult.HandshakeStatus in project voltdb by VoltDB.
the class TLSHandshaker method handshake.
public boolean handshake() throws IOException {
ByteBuffer txNetData = (ByteBuffer) ByteBuffer.allocate(m_appsz).clear();
ByteBuffer clearData = (ByteBuffer) ByteBuffer.allocate(CipherExecutor.FRAME_SIZE).clear();
SSLEngineResult result = null;
m_eng.beginHandshake();
HandshakeStatus status = m_eng.getHandshakeStatus();
boolean isBlocked = m_sc.isBlocking();
synchronized (m_sc.blockingLock()) {
isBlocked = m_sc.isBlocking();
if (isBlocked) {
m_sc.configureBlocking(false);
}
}
Selector selector = Selector.open();
m_sc.register(selector, SelectionKey.OP_READ);
try {
while (status != HandshakeStatus.FINISHED && status != HandshakeStatus.NOT_HANDSHAKING) {
switch(status) {
case NEED_UNWRAP:
if (selector.select(2) == 1 && canread(selector)) {
if (m_sc.read(m_rxNetData) < 0) {
if (m_eng.isInboundDone() && m_eng.isOutboundDone()) {
return false;
}
try {
m_eng.closeInbound();
} catch (SSLException ingnoreIt) {
}
m_eng.closeOutbound();
status = m_eng.getHandshakeStatus();
break;
}
}
m_rxNetData.flip();
try {
result = m_eng.unwrap(m_rxNetData, clearData);
m_rxNetData.compact();
status = m_eng.getHandshakeStatus();
} catch (SSLException e) {
m_eng.closeOutbound();
throw e;
}
switch(result.getStatus()) {
case OK:
break;
case BUFFER_OVERFLOW:
clearData = expand(clearData, false);
break;
case BUFFER_UNDERFLOW:
// in this state until data shows up in m_rxNetData.
break;
case CLOSED:
if (m_eng.isOutboundDone()) {
return false;
} else {
m_eng.closeOutbound();
status = m_eng.getHandshakeStatus();
}
break;
default:
throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
}
break;
case NEED_WRAP:
txNetData.clear();
try {
result = m_eng.wrap(clearData, txNetData);
status = m_eng.getHandshakeStatus();
} catch (SSLException e) {
m_eng.closeOutbound();
throw e;
}
switch(result.getStatus()) {
case OK:
txNetData.flip();
while (txNetData.hasRemaining()) {
m_sc.write(txNetData);
}
break;
case BUFFER_OVERFLOW:
clearData = expand(txNetData, false);
break;
case BUFFER_UNDERFLOW:
throw new SSLException("Buffer underflow occured after a wrap");
case CLOSED:
txNetData.flip();
while (txNetData.hasRemaining()) {
m_sc.write(txNetData);
}
m_rxNetData.clear();
status = m_eng.getHandshakeStatus();
break;
default:
throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
}
break;
case NEED_TASK:
Runnable task;
while ((task = m_eng.getDelegatedTask()) != null) {
task.run();
}
status = m_eng.getHandshakeStatus();
break;
case FINISHED:
break;
case NOT_HANDSHAKING:
break;
default:
throw new IllegalStateException("Invalid SSL handshake status" + status);
}
}
} finally {
SelectionKey sk = m_sc.keyFor(selector);
sk.cancel();
selector.close();
if (isBlocked)
synchronized (m_sc.blockingLock()) {
m_sc.configureBlocking(isBlocked);
}
}
return true;
}
use of javax.net.ssl.SSLEngineResult.HandshakeStatus in project webpieces by deanhiller.
the class AsyncSSLEngine2Impl method feedPlainPacketImpl.
@SuppressWarnings("rawtypes")
public CompletableFuture<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();
log.trace(() -> mem + "feedPlainPacket [in-buffer] pos=" + buffer.position() + " lim=" + buffer.limit());
List<CompletableFuture> futures = new ArrayList<>();
while (buffer.hasRemaining()) {
ByteBuffer engineToSocketData = pool.nextBuffer(sslEngine.getSession().getPacketBufferSize());
synchronized (wrapLock) {
SSLEngineResult result = sslEngine.wrap(buffer, engineToSocketData);
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");
log.trace(() -> mem + "SSLListener.packetEncrypted pos=" + engineToSocketData.position() + " lim=" + engineToSocketData.limit() + " hsStatus=" + hsStatus + " status=" + status);
engineToSocketData.flip();
CompletableFuture future = listener.packetEncrypted(engineToSocketData);
futures.add(future);
}
}
pool.releaseBuffer(buffer);
CompletableFuture[] array = futures.toArray(new CompletableFuture[0]);
return CompletableFuture.allOf(array);
}
use of javax.net.ssl.SSLEngineResult.HandshakeStatus in project webpieces by deanhiller.
the class AsyncSSLEngine2Impl method runnableComplete.
private void runnableComplete() {
SSLEngine sslEngine = mem.getEngine();
HandshakeStatus hsStatus = sslEngine.getHandshakeStatus();
ByteBuffer cached = mem.getCachedToProcess();
if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
//unwrap any previously incoming data...
if (cached != null) {
//wipe out the data we are now procesing
mem.setCachedEncryptedData(null);
log.trace(() -> mem + "[AfterRunnable][socketToEngine] refeeding myself pos=" + cached.position() + " lim=" + cached.limit());
feedEncryptedPacketImpl(cached);
}
} else if (hsStatus == HandshakeStatus.NEED_WRAP) {
log.trace(() -> mem + "[Runnable]continuing handshake");
sendHandshakeMessage();
} else {
throw new UnsupportedOperationException("need to support state=" + hsStatus);
}
}
use of javax.net.ssl.SSLEngineResult.HandshakeStatus in project webpieces by deanhiller.
the class AsyncSSLEngine2Impl method sendHandshakeMessageImpl.
private void sendHandshakeMessageImpl() throws SSLException {
SSLEngine sslEngine = mem.getEngine();
log.trace(() -> mem + "sending handshake message");
//HELPER.eraseBuffer(empty);
HandshakeStatus hsStatus = sslEngine.getHandshakeStatus();
if (hsStatus != HandshakeStatus.NEED_WRAP)
throw new IllegalStateException("we should only be calling this method when hsStatus=NEED_WRAP. hsStatus=" + hsStatus);
while (hsStatus == HandshakeStatus.NEED_WRAP) {
ByteBuffer engineToSocketData = pool.nextBuffer(sslEngine.getSession().getPacketBufferSize());
Status lastStatus = null;
synchronized (wrapLock) {
//KEEEEEP This very small. wrap and then listener.packetEncrypted
SSLEngineResult result = sslEngine.wrap(EMPTY, engineToSocketData);
lastStatus = result.getStatus();
hsStatus = result.getHandshakeStatus();
final Status lastStatus2 = lastStatus;
final HandshakeStatus hsStatus2 = hsStatus;
log.trace(() -> mem + "write packet pos=" + engineToSocketData.position() + " lim=" + engineToSocketData.limit() + " status=" + lastStatus2 + " hs=" + hsStatus2);
if (lastStatus == Status.BUFFER_OVERFLOW || lastStatus == Status.BUFFER_UNDERFLOW)
throw new RuntimeException("status not right, status=" + lastStatus + " even though we sized the buffer to consume all?");
engineToSocketData.flip();
listener.sendEncryptedHandshakeData(engineToSocketData);
}
if (lastStatus == Status.CLOSED && !clientInitiated) {
fireClose();
}
}
if (hsStatus == HandshakeStatus.NEED_WRAP || hsStatus == HandshakeStatus.NEED_TASK)
throw new RuntimeException(mem + "BUG, need to implement more here status=" + hsStatus);
final HandshakeStatus hsStatus2 = hsStatus;
log.trace(() -> mem + "status=" + hsStatus2 + " isConn=" + mem.getConnectionState());
if (hsStatus == HandshakeStatus.FINISHED) {
fireLinkEstablished();
}
}
use of javax.net.ssl.SSLEngineResult.HandshakeStatus in project Openfire by igniterealtime.
the class TLSWrapper method log.
private void log(String str, SSLEngineResult result) {
if (!logging) {
return;
}
if (resultOnce) {
resultOnce = false;
Log.info("The format of the SSLEngineResult is: \n" + "\t\"getStatus() / getHandshakeStatus()\" +\n" + "\t\"bytesConsumed() / bytesProduced()\"\n");
}
HandshakeStatus hsStatus = result.getHandshakeStatus();
Log.info(str + result.getStatus() + "/" + hsStatus + ", " + result.bytesConsumed() + "/" + result.bytesProduced() + " bytes");
if (hsStatus == HandshakeStatus.FINISHED) {
Log.info("\t...ready for application data");
}
}
Aggregations