Class SecurityEnhancedTLSSocketFactory

  • All Implemented Interfaces:
    ConnectionSocketFactory, LayeredConnectionSocketFactory

    public class SecurityEnhancedTLSSocketFactory
    extends Object
    implements LayeredConnectionSocketFactory
    An security-enhanced implementation of HttpClient's TLS-capable LayeredConnectionSocketFactory.

    This implementation wraps an existing TLS socket factory instance, decorating it with additional support for:

    • Verifying the server TLS certificate and chain via a TrustEngine<Credential> and CriteriaSet supplied by the HttpClient caller via the HttpContext.
    • Loading and clearing a thread-local instance of X509Credential used for client TLS.

    The context keys used by this component are as follows, defined in HttpClientSecurityConstants:

    • HttpClientSecurityConstants.CONTEXT_KEY_TRUST_ENGINE: The trust engine instance used. Supplied by the HttpClient caller. Must be an instance of TrustEngine<Credential>.
    • HttpClientSecurityConstants.CONTEXT_KEY_CRITERIA_SET: The criteria set instance used. Supplied by the HttpClient caller. Must be an instance of CriteriaSet.
    • HttpClientSecurityConstants.CONTEXT_KEY_SERVER_TLS_CREDENTIAL_TRUSTED: The result of the trust evaluation, if it was performed. Populated by this component. Will be a Boolean, where true means the server TLS was evaluated as trusted, false means the credential was evaluated as untrusted. A null or missing value means that trust engine evaluation was not performed.
    • HttpClientSecurityConstants.CONTEXT_KEY_CLIENT_TLS_CREDENTIAL: The client TLS credential used. Supplied by the HttpClient caller. Must be an instance of X509Credential.

    If the trust engine context attribute is not populated by the caller and isTrustEngineRequired() is true (the default), then an SSLPeerUnverifiedException is thrown.

    If the trust engine context attribute is not populated by the caller and isTrustEngineRequired() is false, then no trust evaluation is performed. This allows use of this implementation with use cases where, given a particular HttpClient instance, sometimes TLS trust engine evaluation is to be performed, and sometimes not. The caller is then responsible for ensuring they supply a trust engine or not, as appropriate.

    Since this implementation may typically be used with and wrap a "no trust" SSL socket factory, an optional instance of X509HostnameVerifier may also be supplied. If supplied, hostname verification will be performed against the new SSLSocket via X509HostnameVerifier.verify(String, SSLSocket).

    If the client TLS credential context attribute is not populated by the caller, then client TLS is not attempted.

    Client TLS support requires use of a compatible KeyManager implementation configured in the SSLContext of the wrapped LayeredConnectionSocketFactory, such as ThreadLocalX509CredentialKeyManager.

    • Constructor Detail

      • SecurityEnhancedTLSSocketFactory

        public SecurityEnhancedTLSSocketFactory​(@Nonnull
                                                LayeredConnectionSocketFactory factory,
                                                boolean trustEngineRequired)
        Constructor.

        No hostname verifier is configured in this implementation. (Does not affect whether hostname is or is not evaluated by the wrapped socket factory).

        Parameters:
        factory - the underlying HttpClient socket factory wrapped by this implementation.
        trustEngineRequired - flag indicating whether a context trust engine attribute is required for TLS server validation.
      • SecurityEnhancedTLSSocketFactory

        public SecurityEnhancedTLSSocketFactory​(@Nonnull
                                                LayeredConnectionSocketFactory factory)
        Constructor.

        No hostname verifier is configured in this implementation. (Does not affect whether hostname is or is not evaluated by the wrapped socket factory).

        Parameters:
        factory - the underlying HttpClient socket factory wrapped by this implementation.
      • SecurityEnhancedTLSSocketFactory

        public SecurityEnhancedTLSSocketFactory​(@Nonnull
                                                LayeredConnectionSocketFactory factory,
                                                @Nullable
                                                X509HostnameVerifier verifier)
        Constructor.
        Parameters:
        factory - the underlying HttpClient socket factory wrapped by this implementation.
        verifier - the hostname verifier evaluated by this implementation
      • SecurityEnhancedTLSSocketFactory

        public SecurityEnhancedTLSSocketFactory​(@Nonnull
                                                LayeredConnectionSocketFactory factory,
                                                @Nullable
                                                X509HostnameVerifier verifier,
                                                boolean trustEngineRequired)
        Constructor.
        Parameters:
        factory - the underlying HttpClient socket factory wrapped by this implementation.
        verifier - the hostname verifier evaluated by this implementation
        trustEngineRequired - flag indicating whether a context trust engine attribute is required for TLS server validation.
    • Method Detail

      • isTrustEngineRequired

        public boolean isTrustEngineRequired()
        Get the flag indicating whether a context trust engine attribute is required for TLS server validation.

        Default: true.

        Returns:
        true if trust engine is required, false if not
      • performTrustEval

        protected void performTrustEval​(@Nonnull
                                        Socket socket,
                                        @Nonnull @NotEmpty
                                        String hostname,
                                        @Nonnull
                                        org.apache.http.protocol.HttpContext context)
                                 throws IOException
        Perform trust evaluation by extracting the server TLS X509Credential from the SSLSession and evaluating it via a TrustEngine<Credential> and CriteriaSet supplied by the caller via the HttpContext.
        Parameters:
        socket - the socket instance being processed
        hostname - the hostname being processed
        context - the HttpClient context being processed
        Throws:
        IOException - if the server TLS credential is untrusted, or if there is a fatal error attempting trust evaluation.
      • extractCredential

        @Nonnull
        protected org.opensaml.security.x509.X509Credential extractCredential​(@Nonnull
                                                                              SSLSocket sslSocket)
                                                                       throws IOException
        Extract the server TLS X509Credential from the supplied SSLSocket.
        Parameters:
        sslSocket - the SSL socket instance to process
        Returns:
        an X509Credential representing the server TLS entity certificate as well as the supplied supporting intermediate certificate chain (if any)
        Throws:
        IOException - if credential data can not be extracted from the socket
      • performHostnameVerification

        protected void performHostnameVerification​(Socket socket,
                                                   String hostname,
                                                   org.apache.http.protocol.HttpContext context)
                                            throws IOException
        Perform hostname verification on the connection represented by the supplied socket.
        Parameters:
        socket - the socket instance being processed
        hostname - the hostname against which to verify
        context - the current HttpClient context instance
        Throws:
        IOException - if an I/O error occurs or the verification process fails
      • setup

        protected void setup​(@Nullable
                             org.apache.http.protocol.HttpContext context)
        Load the ThreadLocalX509CredentialContext with the client TLS credential obtained from the HttpContext.
        Parameters:
        context - the HttpContext instance
      • teardown

        protected void teardown​(@Nullable
                                org.apache.http.protocol.HttpContext context)
        Schedule the deferred clearing of the ThreadLocalX509CredentialContext of the client TLS credential obtained from the HttpContext.
        Parameters:
        context - the HttpContext instance