• Brian Carlstrom's avatar
    OpenSSLSocket handshake overhaul · bcfb325d
    Brian Carlstrom authored
    Summary:
    - SSLSocket.startHandshake now generalized to handle both client and
      server handshaking as well as client/server role reversal
    - handshake_cutthrough.patch is properly integrated with support
      delayed handshake completion now integrated with delayed updates to
      session cache and callbacks to HandshakeCompletedListeners
    - Many fixes to SSLSession, which is the end product of the handshake
    - Generally more RI and SSLEngine compliant behavior.
    - More native code deletion through unification of client/server
      handshake, unification of client/server certificate chain
      verification, etc. More native code moved from various OpenSSL
      classes to cleaner NativeCrypto interfaces that more directly mirror
      the OpenSSL interfaces.
    
    Details:
    
    Delay SSL_new call until handshake time when we know for sure whether
    the OpenSSLSocket will be used in client or server mode and we can
    allocate the SSL_new from the apppriate client or server SSL_CTX used
    for session caching.
    
        Now that no SSL is allocated for an OpenSSLServerSocketImpl,
        store enabledProtocols and enabledCipherSuites in instance String
        arrays. Use new NativeCrypto.checkEnabled* methdods for argument
        validation. OpenSSLServerSocketImpl passes these enabled arrays to
        a new OpenSSLSocket constructor during accept(). Removed finalizer
        from OpenSSLServerSocketImpl since it no longer has any native
        storage and socket is already closed by PlainSocketImpl finalizer.
    
    	X-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
    
        OpenSSLSocket major overhaul to properly implement handshaking
        including switching client and server roles and session ID caching
        with handshake_cutthrough.patch.
        - now implements NativeCrypto.HandshakeCompletedListeners for
          properly timed callback when handshake_cutthrough.patch delays
          handshake completion until first SSLSocket.getInputStream()
          read.
        - similar enabledProtocols/enabledCipherSuites changes as
          OpenSSLServerSocketImpl since we need to store the state
          somewhere other than an openssl SSL struct until we are sure if
          we are doing a client or server handshake.
        - added handshake completed field so that startHandshake can tell
          if handshake was completed during SSL_do_handshake or will be
          completed later by a call to HandshakeCompletedCallback.handshakeCompleted.
        - removed nativegetsession as the equivalent value is now returned by SSL_do_handshake
        - removed nativecipherauthenticationmethod as the value is now passed to verifyCertificateChain
        - startHandshake is now a wrapper that forces a fully synchronous handshake
        - startHandshake(boolean) is the the most changed method in this
          changelist, combinding both the old startHandshake logic, but
          also the OpenSSLSocketImpl.accept code as well. Notable
          differences from the old code:
          * now responsible for SSL_new
          * single code path for client/server handshaking dealing with SSLSession caching
          * now handles server certificate requests previously in
            OpenSSLServerSocketImpl, since a client can request to act
            like a server and therefore need to be able to make suck
            demands on its peer.
          * supports turning off handshake_cutthrough at a callers request
            via explicit call to startHandshake()
          * certificate verification happens during an upcall from openssl
            during SSL_do_handshake to verifyCertificateChain for both
            client and server cases. previously there was not quite right
            upcall support on the server side and post-handshake checking
            on the client, which did not allow for a proper alert to be
            sent to the peer informing them of the issue, which the RI and
            SSLEngine code do.
          * Similarly, setEnableSessionCreation(false) did not send an
            alert to the peer as the RI and SSLEngine code in the client
            case. In the server case, nothing was previously done.
          * The use of local certificates was not determined from
            introspecting the SSL struct post-handshake. This is now
            partially implemented and will be completed in a later change.
        - SSLSocket.{shutdownInput,shutdownOutput} are now restored to the
          proper behavior of throwing UnsupportedOperationException.
        - Gutted OpenSSLSocketImpl finalizer. The comment explains in
          detail the trouble of having the finalizer do anything more than
          touch its the instances own state due to unpredictable order of
          finalization and the future possability of parallel
          finalization.
    
            x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
    
        SSLSession fixes
        - Made OpenSSLSessionImpl.sessionContext non-final so it could be
          nulled by SSLSession.invalidate to match RI behavior.
        - As noted in AbstractSessionContext discussion, removed
          OpenSSLSessionImpl constructor that took SSLParameters, instead
          we take the possibly null localCertificates
          directly. OpenSSLSessionImpl.getLocalCertificates now simply
          returns the localCertificates member variable instead of
          incorrectly trying to query the KeyManager for certificates that
          may not have been used.
        - OpenSSLSessionImpl now caches its native ID to avoid numerious
          native calls but also now provides as resetId which will update
          the cache when a delayed handshake happens due to the
          handshake_cutthrough.patch
        - Fixed bug in getPeerPrincipal that it wasn't calling
          getPeerCertificates to initialize peerCertificates field.
        - freeImpl is now 'public static' in preparation for move to NativeCrypto.
    
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
    
        The old SSLSessionImpl class that is still used for representing
        the invalid session now returns
           isValid => false
        and
           getProtocol => "NONE"
        to match the RI.
    
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionImpl.java
    
        NativeCrypto improvements
        - Adding NativeCrypto.SSL_{get,set,clear}_mode similar to
          NativeCrypto.SSL_{get,set,clear}_options along with
          SSL_MODE_HANDSHAKE_CUTTHROUGH constant which is used to
          explicitly disable/enable the Android handshake_cutthrough.patch
          behavior.
        - Added missing NativeCrypto.SSL_clear_options and used to properly
          implement NativeCrypto.setEnabledProtocols.
        - Added NativeCrypto.checkEnabledProtocols and
          NativeCrypto.checkEnabledCipherSuites helpers to implement
          exception compatability with the RI. While some of this code is
          refactored from existing NativeCrypto code, it is now also used
          by OpenSSLServerSocketImpl and OpenSSLSocketImpl which maintain
          their own String[]s of what is enabled until startHandshake time. (see below)
        - Changed NativeCrypto.findSuite to use foreach style loop for clarity.
        - Moved OpenSSLServerSocketImpl nativesetclientauth and
          SSL_VERIFY_* constants to NativeCrypto.SSL_set_verify
        - Added NativeCrypto.SSL_set_session based on part of old OpenSSLSocketImpl.nativeconnect
        - Added NativeCrypto.SSL_set_session_creation_enabled to properly implement
          SSLSocket.setEnableSessionCreation(false) which uses new
          external/openssl/patches/jsse.patch functionality.
        - New NativeCrypto.SSL_do_handshake consolidates
          OpenSSLSocketImpl.{nativeconnect, nativeaccept} while properly
          implementing SSLSocket.setUseClientMode(false) for clients and
          SSLSocket.setUseClientMode(true) for servers.
        - New NativeCrypto.SSL_get_certificate is determine if local
          certificate requested by peer. While functional, currently
          NativeCrypto.SSL_new always sets a value via SSL_use_certificate
          instead of relying on a callback set via SSL_CTX_set_client_cert_cb.
        - Changed NativeCrypto.CertificateChainVerifier.verifyCertificateChain
          to throw a checked CertificateException to match TrustManager.{checkServerTrusted,
          checkClientTrusted}. It also takes an authMethod so avoid the need to call
          the old OpenSSLSocketImpl.nativecipherauthenticationmethod.
        - Added NativeCrypto.HandshakeCompletedCallback which has its
          handshakeCompleted method called from OpenSSL when the now
          delayed handshake_cutthrough.patch handshake is completed so
          SSLSession caching can be delayed until a session ID is available
          and to provide a better time for HandshakeCompletedListeners to
          be notified.
    
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
    	x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
    
        Some other changes specific to the naitve side of the code
        - Added JNITRACE calls (enabled at compile time with JNI_TRACE)
          for future debugging.
        - throw SSLException subclass of IOException instead IOException
          itself for better RI compatability
    	x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
        - changed from old struct app_data to new class AppData at enh's request
    
        Remove dubious usage of SSLParameters within AbstractSessionContext
        to pass through to OpenSSLSessionImpl constructor for use in
        calling getLocalCertificates for sessions created from a byte array
        with AbstractSessionContext.toSession. Our
        AbstractSessionContext.toBytes doesn't currently include the local
        certificates in its output, so it cannot be expected to have in toSession.
    
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
    	x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
    
    Test maintenance
    
        openssl 1.0.0 adds support for RFC 4507 session tickets which
        remove the need for server side session state. These tests needed
        to be updated for this new behavior. If IS_RI is true, they still
        follow the old behavior.
    
    	luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
    	luni/src/test/java/javax/net/ssl/SSLSessionTest.java
    	luni/src/test/java/javax/net/ssl/SSLSocketTest.java
    
        Update KnownFailures and add specific comments at point of failure
        about what remains to be fixed.
    
    	luni/src/test/java/javax/net/ssl/SSLSessionTest.java
    
        Added tests to cover the use of standard cipher suite
        names. Historically Android has used OpenSSL string constants for
        cipher suite names, but JSSE actually specifies supported and
        expected names.
    
    	luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
    	luni/src/test/java/javax/net/ssl/SSLSocketTest.java
    
        Create new support/src/test/java/javax/net/ssl with old Helper
        support code pulled from javax.net.ssl tests:
          SSLContextTest.Helper -> TestSSLContext
          SSLSocketTest.Helper -> TestSSLSocketPair
          SSLSessionTest.Helper -> TestSSLSessions
        Also added new StandardNames here, which contains a collection of
        expected constants for test validation.
    
    	luni/src/test/java/javax/net/ssl/SSLContextTest.java
    	luni/src/test/java/javax/net/ssl/SSLSocketTest.java
    	luni/src/test/java/javax/net/ssl/SSLSessionTest.java
    	support/src/test/java/javax/net/ssl/TestSSLContext.java
    	support/src/test/java/javax/net/ssl/TestSSLSocketPair.java
    	support/src/test/java/javax/net/ssl/TestSSLSessions.java
    	support/src/test/java/javax/net/ssl/StandardNames.java
    
        Removed some now fixed KnownFailures and unneeded !IS_RI
        code. Marked some [Un]KnownFailures where exceptions are thrown
        and visible in the output but aren't correctly causing the test to
        fail. Fixed assertNonNull to assertTrue in
        test_SSLSocketTest_Test_create. Added
        stress_test_SSLSocketTest_Test_create to track down test
        flakiness, leading to rewrite of SSLSocket finalization.
    
    	luni/src/test/java/javax/net/ssl/SSLSocketTest.java
    
        Reenable javax.net.ssl.AllTests now that it is does not hang
    
    	luni/src/test/java/tests/AllTests.java
    
        Improve error messages while debugging overflow problem.
        Added new assert when debugging new RFC 4507 behavior.
        Removed KnownFailure annotation for now working test case.
    	x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
    
    Client code changes
    
       Now that startHandshake implies synchronous vs Android's default async handshake, remove unneeded explict calls to SSLSocket.startHandshake
    
    	luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
    
       Removed IBM 1.4.x codepath that involved startHandshake
    
    	x-net/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
    
    Unrelated
    
       Remove unneed SSLSocket.setUseClientMode while removing unneeded SSLSocket.startHandshake
    
    	luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
    
       Removed warnings due to now missing modules in classpath
    
    	run-core-tests
    
    Change-Id: I6e149ae259b3feccdfb0673209c85cfeb60befc8
    bcfb325d
run-core-tests 1.4 KB