From 7d7ecdbb01daa051472bf40e269b78c4faf7b34e Mon Sep 17 00:00:00 2001 From: Nick Hudson Date: Fri, 31 May 2013 11:55:55 +0100 Subject: Workaround for some misbehaving SSLEngine implementations Some implementations of SSLEngine (notably Apache harmony used in Android) never return the FINSHED status from calls to wrap or unwrap, causing the TLSLayer to never emit its completed signal. With this change, we treat a return of NOT_HANDSHAKING as equivalent to FINISHED. The NOT_HANDSHAKING will never happen before handshaking has finished, because the status during handshaking should always be NEED_WRAP, NEED_UNWRAP, or NEED_TASK. Test-information: Tested with OracleJDK and OpenJDK using Isode M-Link Console to ensure that the behaviour when negotiating TLS is unchanged (debugging shows that in these cases it always sees the FINISHED status). Tested on Android. Without this patch TLS handshakes don't complete; with the patch, they do. Change-Id: Ied2989cb2a3458dc6b1d2584dcc6c722d18e1355 Signed-off-by: Nick Hudson diff --git a/src/com/isode/stroke/tls/java/JSSEContext.java b/src/com/isode/stroke/tls/java/JSSEContext.java index 257a70c..8c351bb 100644 --- a/src/com/isode/stroke/tls/java/JSSEContext.java +++ b/src/com/isode/stroke/tls/java/JSSEContext.java @@ -247,13 +247,19 @@ public class JSSEContext extends TLSContext { * a status is an indication that we need to re-check whether * anything's pending to be written */ - if (handshakeStatus == HandshakeStatus.FINISHED) { + if (handshakeStatus == HandshakeStatus.FINISHED || + (!handshakeCompleted && + handshakeStatus == HandshakeStatus.NOT_HANDSHAKING)) { /* Special case will happen when the handshake completes following * an unwrap. The first time we tried wrapping some plain stuff, * it triggers the handshake but won't itself have been dealt with. * So now the handshake has finished, we have to try sending it * again - */ + * The second checking clause is necessary for certain + * SSLEngine implementations (notably Apache Harmony + * used on Android) which never return FINISHED + */ + handshakeCompleted = true; wrapAndSendData(); onConnected.emit(); @@ -410,9 +416,14 @@ public class JSSEContext extends TLSContext { plainToSend.compact(); /* FINISHED can only come back for wrap() or unwrap(); so check to - * see if we just had it + * see if we just had it. + * The second checking clause is necessary for certain + * SSLEngine implementations (notably Apache Harmony + * used on Android) which never return FINISHED */ - if (handshakeStatus == HandshakeStatus.FINISHED) { + if (handshakeStatus == HandshakeStatus.FINISHED || + (!handshakeCompleted && + handshakeStatus == HandshakeStatus.NOT_HANDSHAKING)) { handshakeFinished = true; } -- cgit v0.10.2-6-g49f6