You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Polar Humenn <ph...@iona.com> on 2007/03/07 21:26:04 UTC

HTTPConduit JSSE Trust Decider JIRA CXF-438

Greetings,

I would like to enable the HTTP Conduit with some security hooks to 
establish a client's trust in the endpoint. This is in response to JIRA 
https://issues.apache.org/jira/browse/CXF-438

The approach will only be applicable to the https protocol using the 
JSSE.  I would like to propose the following interface JSSETrustDecider, 
which will be instantiated by spring configuration based on endpoint or 
on the bus (for all potential https connections).

A call will be made to the JSSETrustDecider at the point the SSL 
handshake completes. If trust is not established, the 
SSLSocket.getOutputStream() will throw the exception from the trust 
decider, which has the desired effect, forbidding anything to be written 
to the wire.

The bean will be spring loaded per statically configured endpoint by 
using the "http-conduit.jsse-trust" suffix, like so:

     <bean name="{http://Qname}EndpointName.http-conduit.jsse-trust" 
class="...">

This work mandates changes to the SSLSocketFactoryWrapper, 
HTTPTransportFactory, HTTPUrlConnectionFactory, and requires a wrapper 
for the SSLSocket.

I have implemented this in http, I need to "translate" that to http2, 
come up with some system tests, and create the patch.

Does everybody agree with the approach?

Cheers,
-Polar

----------
package org.apache.cxf.transport.https;

import javax.net.ssl.HandshakeCompletedEvent;

import org.apache.cxf.service.model.EndpointInfo;

/**
 * This interface is used to decide trust in the TLS peer
 * within the HTTP Conduit using JSSE TLS. The method within
 * this interface is called once at the successfull completion
 * of the inital TLS handshake.
 *
 */
public interface JSSETrustDecider {
        /**
         * This method is called at the completion of the
         * initial handshake for a TLS connection, but before
         * anything else is sent to the peer.
         *
         * @param endpointInfo The CXF Endpoint associated with this 
HTTP conduit.
         * @param event        The JSSE event that contains SSL security 
information.
         *
         * @throws UntrustedTLSConnectionIOException
         *                     The trust decider throws this if
         *                     trust cannot be established.
         */
        void establishTrust(
                        EndpointInfo             endpointInfo,
                        HandshakeCompletedEvent  event
        ) throws
                UntrustedTLSConnectionIOException;
}


RE: HTTPConduit JSSE Trust Decider JIRA CXF-438

Posted by "Glynn, Eoghan" <eo...@iona.com>.

+1 to the general idea.

But I've a few suggestions on the detail ...

First, the lifetime of connection may be limited to a single
request/response MEP (e.g. HTTP without keep-alive), or may extend over
many MEPs. So I think you'll need to be explicit as to whether the
TrustDecider is called out to per-MEP, or per-connection-establishment
event.

I'd favour a per-MEP trust decision for the following reasons:

- the mapping between connection-establishment events and MEPs may be
radically different across transports (i.e 1:1 or 1:M, depending on how
the transport and ConduitInitiator are implemented)

- the application may want to apply different trust evaluation logic
depending on the current operation

Now if you do switch to a per-MEP trust evaluation, then you should
probably decouple the mechanism from the JSSE
HandshakeCompletionListener, and instead make a direct call to the
TrustDecider from the CXF code that establishes the connection (e.g. the
HttpsURLConnectionFactory). Because obviously the transport may not be
implemented to use a fresh connection for each MEP, so you wouldn't get
a HandshakeCompletedEvent each time.

You'd still have access to the main bits of SSL context (i.e. the peer
cert and ciphersuite) from the HttpsURLConnection itself as opposed to
HandshakeCompletedEvent. If establishTrust() throws
UntrustedTLSConnectionIOException, then the HttpsURLConnectionFactory
could just shut down the new connection without having written any data
on the wire, and propagate the exception upwards.

Also a per-MEP trust evaluation would imply that the TrustDecider needs
a bit more context on the current MEP. The cleanest way to achieve this
is probably just to pass in the Exchange, from which the TrustDecider
could navigate to the outbound message, pull out the EndpointInfo or
BindingOperationInfo, peek at the WS-A message properties, or whatever
it needs to do.

Another suggestion would be to use the work-in-progress policy assertion
infrastructure to get a runtime assurance that the TrustDecider is
present in the binding as expected.

Cheers,
Eoghan

> -----Original Message-----
> From: Polar Humenn [mailto:phumenn@iona.com] 
> Sent: 07 March 2007 20:26
> To: cxf-dev@incubator.apache.org
> Subject: HTTPConduit JSSE Trust Decider JIRA CXF-438
> 
> Greetings,
> 
> I would like to enable the HTTP Conduit with some security 
> hooks to establish a client's trust in the endpoint. This is 
> in response to JIRA
> https://issues.apache.org/jira/browse/CXF-438
> 
> The approach will only be applicable to the https protocol 
> using the JSSE.  I would like to propose the following 
> interface JSSETrustDecider, which will be instantiated by 
> spring configuration based on endpoint or on the bus (for all 
> potential https connections).
> 
> A call will be made to the JSSETrustDecider at the point the 
> SSL handshake completes. If trust is not established, the
> SSLSocket.getOutputStream() will throw the exception from the 
> trust decider, which has the desired effect, forbidding 
> anything to be written to the wire.
> 
> The bean will be spring loaded per statically configured 
> endpoint by using the "http-conduit.jsse-trust" suffix, like so:
> 
>      <bean name="{http://Qname}EndpointName.http-conduit.jsse-trust" 
> class="...">
> 
> This work mandates changes to the SSLSocketFactoryWrapper, 
> HTTPTransportFactory, HTTPUrlConnectionFactory, and requires 
> a wrapper for the SSLSocket.
> 
> I have implemented this in http, I need to "translate" that 
> to http2, come up with some system tests, and create the patch.
> 
> Does everybody agree with the approach?
> 
> Cheers,
> -Polar
> 
> ----------
> package org.apache.cxf.transport.https;
> 
> import javax.net.ssl.HandshakeCompletedEvent;
> 
> import org.apache.cxf.service.model.EndpointInfo;
> 
> /**
>  * This interface is used to decide trust in the TLS peer
>  * within the HTTP Conduit using JSSE TLS. The method within
>  * this interface is called once at the successfull completion
>  * of the inital TLS handshake.
>  *
>  */
> public interface JSSETrustDecider {
>         /**
>          * This method is called at the completion of the
>          * initial handshake for a TLS connection, but before
>          * anything else is sent to the peer.
>          *
>          * @param endpointInfo The CXF Endpoint associated 
> with this HTTP conduit.
>          * @param event        The JSSE event that contains 
> SSL security 
> information.
>          *
>          * @throws UntrustedTLSConnectionIOException
>          *                     The trust decider throws this if
>          *                     trust cannot be established.
>          */
>         void establishTrust(
>                         EndpointInfo             endpointInfo,
>                         HandshakeCompletedEvent  event
>         ) throws
>                 UntrustedTLSConnectionIOException;
> }
> 
>