+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:[EMAIL PROTECTED] > Sent: 07 March 2007 20:26 > To: [email protected] > 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; > } > >
