You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2015/12/11 17:38:19 UTC

svn commit: r1719472 - in /tomcat/trunk/java/org/apache/tomcat: jni/SSL.java util/net/openssl/OpenSSLEngine.java

Author: remm
Date: Fri Dec 11 16:38:19 2015
New Revision: 1719472

URL: http://svn.apache.org/viewvc?rev=1719472&view=rev
Log:
- Improve the handshake end detection using the getHandshakeCount that was modified in native. Although checking the certificate was there is a hack that worked in some cases, it was most likely incorrect.
- Ideally SSL_set_info_callback can be used for even better state tracking eventually, but it needs a lot more native work.
- Add a flag to know that an extra wrap should be done when an error occurs during handshake.

Modified:
    tomcat/trunk/java/org/apache/tomcat/jni/SSL.java
    tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java

Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSL.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSL.java?rev=1719472&r1=1719471&r2=1719472&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/SSL.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/SSL.java Fri Dec 11 16:38:19 2015
@@ -357,6 +357,11 @@ public final class SSL {
      */
     public static native boolean hasOp(int op);
 
+    /**
+     * Return the handshake completed count.
+     */
+    public static native int getHandshakeCount(long ssl);
+
     /*
      * Begin Twitter API additions
      */

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java?rev=1719472&r1=1719471&r2=1719472&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java Fri Dec 11 16:38:19 2015
@@ -151,6 +151,7 @@ public final class OpenSSLEngine extends
      */
     private int accepted;
     private boolean handshakeFinished;
+    private int currentHandshake;
     private boolean receivedShutdown;
     private volatile int destroyed;
 
@@ -167,7 +168,7 @@ public final class OpenSSLEngine extends
     private boolean isInboundDone;
     private boolean isOutboundDone;
     private boolean engineClosed;
-    private boolean needCertificate;
+    private boolean sendHandshakeError = false;
 
     private final boolean clientMode;
     private final String fallbackApplicationProtocol;
@@ -867,6 +868,7 @@ public final class OpenSSLEngine extends
     }
 
     private void handshake() throws SSLException {
+        currentHandshake = SSL.getHandshakeCount(ssl);
         int code = SSL.doHandshake(ssl);
         if (code <= 0) {
             checkLastError();
@@ -889,12 +891,10 @@ public final class OpenSSLEngine extends
         if (code <= 0) {
             checkLastError();
         }
-        if (clientAuth == ClientAuthMode.REQUIRE) {
-            needCertificate = true;
-        }
         handshakeFinished = false;
         peerCerts = null;
         x509PeerCerts = null;
+        currentHandshake = SSL.getHandshakeCount(ssl);
         int code2 = SSL.doHandshake(ssl);
         if (code2 <= 0) {
             checkLastError();
@@ -910,8 +910,8 @@ public final class OpenSSLEngine extends
             }
             // It is possible the error occurs during a rehandshake, so consider it done
             // but delay an error
-            if (needCertificate) {
-                needCertificate = false;
+            if (!handshakeFinished) {
+                sendHandshakeError = true;
             } else {
                 throw new SSLException(err);
             }
@@ -934,18 +934,21 @@ public final class OpenSSLEngine extends
 
         // Check if we are in the initial handshake phase
         if (!handshakeFinished) {
+
             // There is pending data in the network BIO -- call wrap
-            if (SSL.pendingWrittenBytesInBIO(networkBIO) != 0) {
+            if (sendHandshakeError || SSL.pendingWrittenBytesInBIO(networkBIO) != 0) {
+                if (sendHandshakeError) {
+                    // After a last wrap, consider it is going to be done
+                    sendHandshakeError = false;
+                    currentHandshake++;
+                }
                 return SSLEngineResult.HandshakeStatus.NEED_WRAP;
             }
 
-            if (needCertificate && getPeerCertificate() == null) {
-                return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
-            }
-
             // No pending data to be sent to the peer
             // Check to see if we have finished handshaking
-            if (SSL.isInInit(ssl) == 0) {
+            int handshakeCount = SSL.getHandshakeCount(ssl);
+            if (handshakeCount != currentHandshake) {
                 if (alpn) {
                     selectedProtocol = SSL.getAlpnSelected(ssl);
                     if (selectedProtocol == null) {
@@ -1078,14 +1081,6 @@ public final class OpenSSLEngine extends
         return false;
     }
 
-    private byte[] getPeerCertificate() {
-        byte[] result = SSL.getPeerCertificate(ssl);
-        if (result != null) {
-            needCertificate = false;
-        }
-        return result;
-    }
-
     @Override
     protected void finalize() throws Throwable {
         super.finalize();
@@ -1212,7 +1207,7 @@ public final class OpenSSLEngine extends
                     // We use SSL_get_peer_certificate to get it in this case and add it to our array later.
                     //
                     // See https://www.openssl.org/docs/ssl/SSL_get_peer_cert_chain.html
-                    clientCert = getPeerCertificate();
+                    clientCert = SSL.getPeerCertificate(ssl);
                 } else {
                     clientCert = null;
                 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org