use of javax.net.ssl.SSLEngineResult in project jetty.project by eclipse.
the class SelectChannelEndPointSslTest method checkSslEngineBehaviour.
@Test
public void checkSslEngineBehaviour() throws Exception {
SSLEngine server = __sslCtxFactory.newSSLEngine();
SSLEngine client = __sslCtxFactory.newSSLEngine();
ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize());
ByteBuffer serverIn = ByteBuffer.allocate(server.getSession().getApplicationBufferSize());
ByteBuffer serverOut = ByteBuffer.allocate(server.getSession().getApplicationBufferSize());
ByteBuffer clientIn = ByteBuffer.allocate(client.getSession().getApplicationBufferSize());
SSLEngineResult result;
// start the client
client.setUseClientMode(true);
client.beginHandshake();
Assert.assertEquals(HandshakeStatus.NEED_WRAP, client.getHandshakeStatus());
// what if we try an unwrap?
netS2C.flip();
result = client.unwrap(netS2C, clientIn);
// unwrap is a noop
assertEquals(SSLEngineResult.Status.OK, result.getStatus());
assertEquals(0, result.bytesConsumed());
assertEquals(0, result.bytesProduced());
assertEquals(HandshakeStatus.NEED_WRAP, result.getHandshakeStatus());
netS2C.clear();
// do the needed WRAP of empty buffer
result = client.wrap(BufferUtil.EMPTY_BUFFER, netC2S);
// unwrap is a noop
assertEquals(SSLEngineResult.Status.OK, result.getStatus());
assertEquals(0, result.bytesConsumed());
assertThat(result.bytesProduced(), greaterThan(0));
assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
netC2S.flip();
assertEquals(netC2S.remaining(), result.bytesProduced());
// start the server
server.setUseClientMode(false);
server.beginHandshake();
Assert.assertEquals(HandshakeStatus.NEED_UNWRAP, server.getHandshakeStatus());
// what if we try a needless wrap?
serverOut.put(BufferUtil.toBuffer("Hello World"));
serverOut.flip();
result = server.wrap(serverOut, netS2C);
// wrap is a noop
assertEquals(SSLEngineResult.Status.OK, result.getStatus());
assertEquals(0, result.bytesConsumed());
assertEquals(0, result.bytesProduced());
assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
// Do the needed unwrap, to an empty buffer
result = server.unwrap(netC2S, BufferUtil.EMPTY_BUFFER);
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus());
assertEquals(0, result.bytesConsumed());
assertEquals(0, result.bytesProduced());
assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
// Do the needed unwrap, to a full buffer
serverIn.position(serverIn.limit());
result = server.unwrap(netC2S, serverIn);
assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus());
assertEquals(0, result.bytesConsumed());
assertEquals(0, result.bytesProduced());
assertEquals(HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus());
// Do the needed unwrap, to an empty buffer
serverIn.clear();
result = server.unwrap(netC2S, serverIn);
assertEquals(SSLEngineResult.Status.OK, result.getStatus());
assertThat(result.bytesConsumed(), greaterThan(0));
assertEquals(0, result.bytesProduced());
assertEquals(HandshakeStatus.NEED_TASK, result.getHandshakeStatus());
server.getDelegatedTask().run();
assertEquals(HandshakeStatus.NEED_WRAP, server.getHandshakeStatus());
}
use of javax.net.ssl.SSLEngineResult in project http-kit by http-kit.
the class HttpsRequest method wrapRequest.
private void wrapRequest() throws SSLException {
myNetData.clear();
SSLEngineResult res = engine.wrap(request, myNetData);
if (res.getStatus() != Status.OK) {
// TODO larger buffer, uberflow?
}
myNetData.flip();
}
use of javax.net.ssl.SSLEngineResult in project http-kit by http-kit.
the class HttpsRequest method doHandshake.
final int doHandshake(ByteBuffer peerAppData) throws IOException {
SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
while (!handshaken) {
switch(hs) {
case NEED_TASK:
Runnable runnable;
while ((runnable = engine.getDelegatedTask()) != null) {
runnable.run();
}
break;
case NEED_UNWRAP:
int read = ((SocketChannel) key.channel()).read(peerNetData);
if (read < 0) {
return -1;
} else {
peerNetData.flip();
SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
peerNetData.compact();
switch(res.getStatus()) {
case // Not possible, peerAppData is 64k
BUFFER_OVERFLOW:
break;
case CLOSED:
return -1;
case // need more data from peer
BUFFER_UNDERFLOW:
return 0;
}
// do not flip to write here, since TCP buffer is writable
}
break;
case NEED_WRAP:
SSLEngineResult res = engine.wrap(EMPTY_BUFFER, myNetData);
myNetData.flip();
((SocketChannel) key.channel()).write(myNetData);
if (myNetData.hasRemaining()) {
// TODO, make sure data get written
} else {
myNetData.clear();
if (res.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NEED_WRAP)
key.interestOps(SelectionKey.OP_READ);
}
break;
}
hs = engine.getHandshakeStatus();
handshaken = hs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING || hs == SSLEngineResult.HandshakeStatus.FINISHED;
if (handshaken) {
wrapRequest();
// TCP buffer maybe empty this time
writeWrappedRequest();
}
}
return 0;
}
use of javax.net.ssl.SSLEngineResult in project http-kit by http-kit.
the class NBlockingSSL method doHandshake.
private static void doHandshake() throws IOException {
SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
isHandshakeDone = hs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING || hs == SSLEngineResult.HandshakeStatus.FINISHED;
loop: while (!isHandshakeDone) {
switch(hs) {
case NEED_TASK:
Runnable runnable;
while ((runnable = engine.getDelegatedTask()) != null) {
logger.info("get task " + runnable);
runnable.run();
}
break;
case NEED_UNWRAP:
int read = socketChannel.read(peerNetData);
logger.info("read {} bytes", read);
if (read < 0) {
logger.info("closed");
// TODO closed
} else {
peerNetData.flip();
SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
logger.info("hs unwrap, " + res);
if (res.getStatus() != Status.OK) {
System.out.println("--------------------------");
}
peerNetData.compact();
switch(res.getStatus()) {
case OK:
break;
case BUFFER_UNDERFLOW:
// need more data from peer
logger.info("waiting for more info");
break loop;
case BUFFER_OVERFLOW:
// need larger peerAppData buffer
break;
case CLOSED:
break;
}
if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
key.interestOps(SelectionKey.OP_WRITE);
logger.info("for write");
break loop;
}
}
break;
case NEED_WRAP:
// myNetData.compact();
SSLEngineResult result = engine.wrap(ByteBuffer.allocate(0), myNetData);
logger.info("wrap: " + result);
myNetData.flip();
socketChannel.write(myNetData);
if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
}
if (!myNetData.hasRemaining()) {
// write done, so just for read
if ((key.interestOps() & SelectionKey.OP_READ) == 0) {
key.interestOps(SelectionKey.OP_READ);
logger.info("for read");
}
myNetData.clear();
// break loop;
} else {
myNetData.compact();
}
break;
}
hs = engine.getHandshakeStatus();
isHandshakeDone = hs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING || hs == SSLEngineResult.HandshakeStatus.FINISHED;
if (isHandshakeDone) {
logger.info("handshake done");
peerNetData.clear();
ByteBuffer buffer = ByteBuffer.wrap(("GET / HTTP/1.1\r\nHost: " + HOST + "\r\n\r\n").getBytes());
SSLEngineResult res = engine.wrap(buffer, myNetData);
RandomAccessFile r = new RandomAccessFile("/home/feng/workspace/http-kit/blog.access.log", "r");
MappedByteBuffer b = r.getChannel().map(MapMode.READ_ONLY, 0, r.getChannel().size());
ByteBuffer bf = ByteBuffer.allocate(256 * 1024);
// even though b is big, bf is small, the two buffer just move
// forward
SSLEngineResult t = engine.wrap(b, bf);
System.out.println(t);
if (res.getStatus() == SSLEngineResult.Status.OK) {
myNetData.flip();
socketChannel.write(myNetData);
if (myNetData.hasRemaining()) {
key.interestOps(SelectionKey.OP_WRITE);
}
}
}
}
}
use of javax.net.ssl.SSLEngineResult in project http-kit by http-kit.
the class NBlockingSSL method main.
public static void main(String[] args) throws IOException {
engine = CLIENT_CONTEXT.createSSLEngine();
engine.setUseClientMode(true);
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
key = socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress(HOST, 443));
int i = 0;
// peerNetData.clear();
while (true) {
int select = selector.select(1000);
if (select > 0) {
Set<SelectionKey> selectionKeys = selector.selectedKeys();
final Iterator<SelectionKey> ite = selectionKeys.iterator();
while (ite.hasNext()) {
final SelectionKey key = ite.next();
if (key.isConnectable()) {
if (socketChannel.finishConnect()) {
key.interestOps(SelectionKey.OP_WRITE);
engine.beginHandshake();
}
} else if (key.isReadable()) {
if (!isHandshakeDone) {
doHandshake();
} else {
int read = socketChannel.read(peerNetData);
if (read > 0) {
peerNetData.flip();
SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
if (res.getStatus() == SSLEngineResult.Status.OK) {
peerAppData.flip();
byte[] data = new byte[peerAppData.remaining()];
peerAppData.get(data);
i++;
logger.info("get data length: " + new String(data).length());
key.interestOps(SelectionKey.OP_WRITE);
peerAppData.clear();
if (i > 5) {
return;
}
// peerNetData.clear();
}
logger.info("read unwrap, " + res);
peerNetData.compact();
}
}
} else if (key.isWritable()) {
if (!isHandshakeDone) {
doHandshake();
} else {
myNetData.clear();
ByteBuffer buffer = ByteBuffer.wrap(("GET / HTTP/1.1\r\nHost: " + HOST + "\r\n\r\n").getBytes());
SSLEngineResult res = engine.wrap(buffer, myNetData);
if (res.getStatus() == Status.OK) {
myNetData.flip();
socketChannel.write(myNetData);
if (!myNetData.hasRemaining()) {
key.interestOps(SelectionKey.OP_READ);
}
}
}
}
ite.remove();
}
} else {
logger.info("waiting");
}
}
}
Aggregations