use of javax.net.ssl.SSLEngineResult in project AndroidAsync by koush.
the class ConscryptTests method testConscryptSSLEngineNPNHandshakeBug.
public void testConscryptSSLEngineNPNHandshakeBug() throws Exception {
// Security.insertProviderAt(new OpenSSLProvider("MyNameBlah"), 1);
Context gms = getContext().createPackageContext("com.google.android.gms", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
gms.getClassLoader().loadClass("com.google.android.gms.common.security.ProviderInstallerImpl").getMethod("insertProvider", Context.class).invoke(null, getContext());
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, null, null);
SSLEngine engine = ctx.createSSLEngine();
configure(engine, "www.google.com", 443);
engine.setUseClientMode(true);
engine.beginHandshake();
Socket socket = new Socket();
socket.connect(new InetSocketAddress("www.google.com", 443));
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
byte[] buf = new byte[65536];
ByteBuffer unwrap = null;
ByteBuffer dummy = ByteBuffer.allocate(65536);
SSLEngineResult.HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED && handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
System.out.println("waiting for read... " + engine.getHandshakeStatus());
int read = is.read(buf);
System.out.println("read: " + read);
if (read <= 0)
throw new Exception("closed!");
if (unwrap != null) {
int bufLen = unwrap.remaining() + read;
ByteBuffer b = ByteBuffer.allocate(bufLen);
b.put(unwrap);
b.put(buf, 0, read);
b.flip();
unwrap = b;
} else {
unwrap = ByteBuffer.wrap(buf, 0, read);
}
if (!unwrap.hasRemaining()) {
unwrap = null;
}
dummy.clear();
SSLEngineResult res = engine.unwrap(unwrap, dummy);
System.out.println("data remaining after unwrap: " + unwrap.remaining());
handshakeStatus = res.getHandshakeStatus();
}
if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
dummy.clear();
SSLEngineResult res = engine.wrap(ByteBuffer.allocate(0), dummy);
handshakeStatus = res.getHandshakeStatus();
dummy.flip();
if (dummy.hasRemaining()) {
os.write(dummy.array(), 0, dummy.remaining());
}
} else if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) {
engine.getDelegatedTask().run();
}
}
System.out.println("Done handshaking! Thank you come again.");
long ptr = (Long) sslNativePointer.get(engine);
byte[] proto = (byte[]) nativeGetAlpnNegotiatedProtocol.invoke(null, ptr);
// byte[] proto = (byte[]) nativeGetNpnNegotiatedProtocol.invoke(null, ptr);
String protoString = new String(proto);
System.out.println("negotiated protocol was: " + protoString);
assertEquals(protoString, "spdy/3.1");
socket.close();
}
use of javax.net.ssl.SSLEngineResult in project Openfire by igniterealtime.
the class TLSStreamHandler method doHandshake.
private boolean doHandshake(SelectionKey sk) throws IOException {
SSLEngineResult result;
if (initialHSComplete) {
return initialHSComplete;
}
/*
* Flush out the outgoing buffer, if there's anything left in it.
*/
if (outgoingNetBB.hasRemaining()) {
if (!flush(outgoingNetBB)) {
return false;
}
switch(initialHSStatus) {
/*
* Is this the last buffer?
*/
case FINISHED:
initialHSComplete = true;
case NEED_UNWRAP:
if (sk != null) {
sk.interestOps(SelectionKey.OP_READ);
}
break;
}
return initialHSComplete;
}
switch(initialHSStatus) {
case NEED_UNWRAP:
if (rbc.read(incomingNetBB) == -1) {
try {
tlsEngine.closeInbound();
} catch (javax.net.ssl.SSLException ex) {
// OF-1009 Process these as a 'normal' handshake rejection - it's the peer closing the connection abruptly.
if ("Inbound closed before receiving peer's close_notify: possible truncation attack?".equals(ex.getMessage())) {
throw new SSLHandshakeException("The peer closed the connection while performing a TLS handshake.");
}
throw ex;
}
return initialHSComplete;
}
needIO: while (initialHSStatus == HandshakeStatus.NEED_UNWRAP) {
/*
* Don't need to resize requestBB, since no app data should be generated here.
*/
incomingNetBB.flip();
result = tlsEngine.unwrap(incomingNetBB, appBB);
incomingNetBB.compact();
initialHSStatus = result.getHandshakeStatus();
switch(result.getStatus()) {
case OK:
switch(initialHSStatus) {
case NOT_HANDSHAKING:
throw new IOException("Not handshaking during initial handshake");
case NEED_TASK:
initialHSStatus = doTasks();
break;
case FINISHED:
initialHSComplete = true;
break needIO;
}
break;
case BUFFER_UNDERFLOW:
/*
* Need to go reread the Channel for more data.
*/
if (sk != null) {
sk.interestOps(SelectionKey.OP_READ);
}
break needIO;
default:
// BUFFER_OVERFLOW/CLOSED:
throw new IOException("Received" + result.getStatus() + "during initial handshaking");
}
}
/*
* Just transitioned from read to write.
*/
if (initialHSStatus != HandshakeStatus.NEED_WRAP) {
break;
}
case NEED_WRAP:
/*
* The flush above guarantees the out buffer to be empty
*/
outgoingNetBB.clear();
result = tlsEngine.wrap(hsBB, outgoingNetBB);
outgoingNetBB.flip();
initialHSStatus = result.getHandshakeStatus();
switch(result.getStatus()) {
case OK:
if (initialHSStatus == HandshakeStatus.NEED_TASK) {
initialHSStatus = doTasks();
}
if (sk != null) {
sk.interestOps(SelectionKey.OP_WRITE);
}
break;
default:
// BUFFER_OVERFLOW/BUFFER_UNDERFLOW/CLOSED:
throw new IOException("Received" + result.getStatus() + "during initial handshaking");
}
break;
default:
// NOT_HANDSHAKING/NEED_TASK/FINISHED
throw new RuntimeException("Invalid Handshaking State" + initialHSStatus);
}
return initialHSComplete;
}
use of javax.net.ssl.SSLEngineResult in project jetty.project by eclipse.
the class SelectChannelEndPointSslTest method testTcpClose.
@Test
public void testTcpClose() throws Exception {
// This test replaces SSLSocket() with a very manual SSL client
// so we can close TCP underneath SSL.
SocketChannel client = SocketChannel.open(_connector.socket().getLocalSocketAddress());
client.socket().setSoTimeout(500);
SocketChannel server = _connector.accept();
server.configureBlocking(false);
_manager.accept(server);
SSLEngine engine = __sslCtxFactory.newSSLEngine();
engine.setUseClientMode(true);
engine.beginHandshake();
ByteBuffer appOut = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
ByteBuffer sslOut = ByteBuffer.allocate(engine.getSession().getPacketBufferSize() * 2);
ByteBuffer appIn = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
ByteBuffer sslIn = ByteBuffer.allocate(engine.getSession().getPacketBufferSize() * 2);
boolean debug = false;
if (debug)
System.err.println(engine.getHandshakeStatus());
int loop = 20;
while (engine.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) {
if (--loop == 0)
throw new IllegalStateException();
if (engine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
if (debug)
System.err.printf("sslOut %d-%d-%d%n", sslOut.position(), sslOut.limit(), sslOut.capacity());
if (debug)
System.err.printf("appOut %d-%d-%d%n", appOut.position(), appOut.limit(), appOut.capacity());
SSLEngineResult result = engine.wrap(appOut, sslOut);
if (debug)
System.err.println(result);
sslOut.flip();
int flushed = client.write(sslOut);
if (debug)
System.err.println("out=" + flushed);
sslOut.clear();
}
if (engine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
if (debug)
System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
if (sslIn.position() == 0) {
int filled = client.read(sslIn);
if (debug)
System.err.println("in=" + filled);
}
sslIn.flip();
if (debug)
System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
SSLEngineResult result = engine.unwrap(sslIn, appIn);
if (debug)
System.err.println(result);
if (debug)
System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
if (sslIn.hasRemaining())
sslIn.compact();
else
sslIn.clear();
if (debug)
System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
}
if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
Runnable task;
while ((task = engine.getDelegatedTask()) != null) task.run();
if (debug)
System.err.println(engine.getHandshakeStatus());
}
}
if (debug)
System.err.println("\nSay Hello");
// write a message
appOut.put("HelloWorld".getBytes(StandardCharsets.UTF_8));
appOut.flip();
SSLEngineResult result = engine.wrap(appOut, sslOut);
if (debug)
System.err.println(result);
sslOut.flip();
int flushed = client.write(sslOut);
if (debug)
System.err.println("out=" + flushed);
sslOut.clear();
appOut.clear();
// read the response
int filled = client.read(sslIn);
if (debug)
System.err.println("in=" + filled);
sslIn.flip();
result = engine.unwrap(sslIn, appIn);
if (debug)
System.err.println(result);
if (sslIn.hasRemaining())
sslIn.compact();
else
sslIn.clear();
appIn.flip();
String reply = new String(appIn.array(), appIn.arrayOffset(), appIn.remaining());
appIn.clear();
Assert.assertEquals("HelloWorld", reply);
if (debug)
System.err.println("Shutting down output");
client.socket().shutdownOutput();
filled = client.read(sslIn);
if (debug)
System.err.println("in=" + filled);
if (filled >= 0) {
// this is the old behaviour.
sslIn.flip();
try {
// Since the client closed abruptly, the server is sending a close alert with a failure
engine.unwrap(sslIn, appIn);
Assert.fail();
} catch (SSLException x) {
// Expected
}
}
sslIn.clear();
filled = client.read(sslIn);
Assert.assertEquals(-1, filled);
// TODO This should not be needed
Thread.sleep(100);
Assert.assertFalse(server.isOpen());
}
use of javax.net.ssl.SSLEngineResult in project h2o-3 by h2oai.
the class SSLSocketChannel method write.
@Override
public int write(ByteBuffer src) throws IOException {
if (closing || closed) {
throw new IOException("Cannot perform socket write, the socket is closed (or being closed).");
}
int wrote = 0;
// src can be much bigger than what our SSL session allows to send in one go
while (src.hasRemaining()) {
netOutBuffer.clear();
SSLEngineResult wrapResult = sslEngine.wrap(src, netOutBuffer);
netOutBuffer.flip();
if (wrapResult.getStatus() == SSLEngineResult.Status.OK) {
if (wrapResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK)
tasks();
}
while (netOutBuffer.hasRemaining()) {
wrote += channel.write(netOutBuffer);
}
}
return wrote;
}
use of javax.net.ssl.SSLEngineResult in project h2o-3 by h2oai.
the class SSLSocketChannel method handshakeUnwrap.
private synchronized SSLEngineResult handshakeUnwrap() throws IOException {
if (netInBuffer.position() == netInBuffer.limit()) {
netInBuffer.clear();
}
channel.read(netInBuffer);
SSLEngineResult unwrapResult;
peerAppData.clear();
do {
netInBuffer.flip();
unwrapResult = sslEngine.unwrap(netInBuffer, peerAppData);
netInBuffer.compact();
hs = unwrapResult.getHandshakeStatus();
switch(unwrapResult.getStatus()) {
case OK:
case BUFFER_UNDERFLOW:
{
if (unwrapResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
tasks();
}
break;
}
case BUFFER_OVERFLOW:
{
int applicationBufferSize = sslEngine.getSession().getApplicationBufferSize();
if (applicationBufferSize > peerAppData.capacity()) {
ByteBuffer b = ByteBuffer.allocate(applicationBufferSize + peerAppData.position());
peerAppData.flip();
b.put(peerAppData);
peerAppData = b;
} else {
peerAppData.compact();
}
break;
}
default:
throw new IOException("Failed to SSL unwrap with status " + unwrapResult.getStatus());
}
} while (unwrapResult.getStatus() == SSLEngineResult.Status.OK && hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP);
return unwrapResult;
}
Aggregations