Apache Camel Http and SSL

I am trying to get a 2-way ssl / https proxy working with Camel. I was able to configure the Jetty component using 2-way ssl, and now I'm trying to get it to work with the Http4 component to complete the proxy client.

When I redirect the berth traffic to the log component, everything is fine, and the ssl level 2 trust chain is fine. When I enter the Http4 component, it explodes with a peer incomplete exception. I am using Camel 2.7.0

That's what i still have

public static void main(String[] args) throws Exception { CamelContext context = new DefaultCamelContext(); JettyHttpComponent jetty = context.getComponent("jetty", JettyHttpComponent.class); SslSelectChannelConnector sslConnector = new SslSelectChannelConnector(); sslConnector.setPort(9443); sslConnector.setKeystore("/home/brian/jboss.keystore"); sslConnector.setKeyPassword("changeit"); sslConnector.setTruststore("/home/brian/jboss.truststore"); sslConnector.setTrustPassword("changeit"); sslConnector.setPassword("changeit"); sslConnector.setNeedClientAuth(true); Map<Integer, SslSelectChannelConnector> connectors = new HashMap<Integer, SslSelectChannelConnector>(); connectors.put(9443, sslConnector); jetty.setSslSocketConnectors(connectors); final Endpoint jettyEndpoint = jetty.createEndpoint("jetty:https://localhost:9443/service"); KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(new FileInputStream(new File("/home/brian/User2.p12")), "Password1234!".toCharArray()); X509KeyManager keyManager = new CTSKeyManager(keystore, "user2", "Password1234!".toCharArray()); KeyManager[] keyManagers = new KeyManager[] { keyManager }; X509TrustManager trustManager = new EasyTrustManager(); TrustManager[] trustManagers = new TrustManager[] { trustManager }; SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(keyManagers, trustManagers, null); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("https", 443, new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER))); HttpComponent http4 = context.getComponent("http4", HttpComponent.class); http4.setClientConnectionManager(new ThreadSafeClientConnManager(registry)); final Endpoint https4Endpoint = http4 .createEndpoint("https4://soafa-lite-staging:443/axis2/services/SigActService?bridgeEndpoint=true&throwExceptionOnFailure=false"); context.addRoutes(new RouteBuilder() { @Override public void configure() { from(jettyEndpoint).to(https4Endpoint); } }); context.start(); context.stop(); } private static class EasyTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }; private static class CTSKeyManager extends X509ExtendedKeyManager { private final KeyStore keystore; private final char[] privateKeyPassword; private final String privateKeyAlias; public CTSKeyManager(KeyStore keystore, String privateKeyAlias, char[] privateKeyPassword) { this.keystore = keystore; this.privateKeyAlias = privateKeyAlias; this.privateKeyPassword = privateKeyPassword; } @Override public String[] getServerAliases(String keyType, Principal[] issuers) { String[] serverAliases = null; try { List<String> aliasList = new ArrayList<String>(); int count = 0; Enumeration<String> aliases = keystore.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); aliasList.add(alias); count++; } serverAliases = aliasList.toArray(new String[count]); } catch (Exception e) { } return serverAliases; } @Override public PrivateKey getPrivateKey(String alias) { PrivateKey privateKey = null; try { privateKey = (PrivateKey) keystore.getKey(alias, privateKeyPassword); } catch (Exception e) { } return privateKey; } @Override public String[] getClientAliases(String keyType, Principal[] issuers) { return privateKeyAlias == null ? null : new String[] { privateKeyAlias }; } @Override public X509Certificate[] getCertificateChain(String alias) { X509Certificate[] x509 = null; try { Certificate[] certs = keystore.getCertificateChain(alias); if (certs == null || certs.length == 0) { return null; } x509 = new X509Certificate[certs.length]; for (int i = 0; i < certs.length; i++) { x509[i] = (X509Certificate) certs[i]; } } catch (Exception e) { } return x509; } @Override public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { return privateKeyAlias; } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { return privateKeyAlias; } @Override public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) { return privateKeyAlias; } @Override public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) { return privateKeyAlias; } } } 

As far as I can tell, trust should be good between all the repositories / trust repositories used on both sides of the proxy connections.

Here is my stack trace

  [qtp25584663-14] HttpProducer DEBUG Executing http POST method: https4: // soafa-lite-staging: 443 / axis2 / services / SigActService? bridgeEndpoint = true & throwExceptionOnFailure = false
 [qtp25584663-14] DefaultErrorHandler DEBUG Failed delivery for exchangeId: ID-ubuntu-46528-1303140195358-0-1.  On delivery attempt: 0 caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
 [qtp25584663-14] DefaultErrorHandler ERROR Failed delivery for exchangeId: ID-ubuntu-46528-1303140195358-0-1.  Exhausted after delivery attempt: 1 caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
     at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates (SSLSessionImpl.javahaps52)
     at org.apache.http.conn.ssl.AbstractVerifier.verify (AbstractVerifier.java:128)
     at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket (SSLSocketFactory.javahaps90)
     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection (DefaultClientConnectionOperator.java:148)
     at org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:149)
     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:121)
     at org.apache.http.impl.client.DefaultRequestDirector.tryConnect (DefaultRequestDirector.java∗61)
     at org.apache.http.impl.client.DefaultRequestDirector.execute (DefaultRequestDirector.java:415)
     at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:820)
     at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:754)
     at org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:732)
     at org.apache.camel.component.http4.HttpProducer.executeMethod (HttpProducer.java:187)
     at org.apache.camel.component.http4.HttpProducer.process (HttpProducer.java:101)
     at org.apache.camel.impl.converter.AsyncProcessorTypeConverter $ ProcessorToAsyncProcessorBridge.process (AsyncProcessorTypeConverter.java:50)
     at org.apache.camel.util.AsyncProcessorHelper.process (AsyncProcessorHelper.java:77)
     at org.apache.camel.processor.SendProcessor $ 2.doInAsyncProducer (SendProcessor.java:104)
     at org.apache.camel.impl.ProducerCache.doInAsyncProducer (ProducerCache.java:272)
     at org.apache.camel.processor.SendProcessor.process (SendProcessor.java:98)
     at org.apache.camel.util.AsyncProcessorHelper.process (AsyncProcessorHelper.java:77)
     at org.apache.camel.processor.DelegateAsyncProcessor.processNext (DelegateAsyncProcessor.java:98)
     at org.apache.camel.processor.DelegateAsyncProcessor.process (DelegateAsyncProcessor.java:89)
     at org.apache.camel.processor.interceptor.TraceInterceptor.process (TraceInterceptor.java:99)
     at org.apache.camel.util.AsyncProcessorHelper.process (AsyncProcessorHelper.java:77)
     at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler (RedeliveryErrorHandler.java:299)
     at org.apache.camel.processor.RedeliveryErrorHandler.process (RedeliveryErrorHandler.java:208)
     at org.apache.camel.processor.DefaultChannel.process (DefaultChannel.java:269)
     at org.apache.camel.processor.UnitOfWorkProcessor.process (UnitOfWorkProcessor.java:109)
     at org.apache.camel.util.AsyncProcessorHelper.process (AsyncProcessorHelper.java:77)
     at org.apache.camel.processor.DelegateAsyncProcessor.processNext (DelegateAsyncProcessor.java:98)
     at org.apache.camel.processor.DelegateAsyncProcessor.process (DelegateAsyncProcessor.java:89)
     at org.apache.camel.management.InstrumentationProcessor.process (InstrumentationProcessor.java:68)
     at org.apache.camel.component.jetty.CamelContinuationServlet.service (CamelContinuationServlet.java:109)
     at javax.servlet.http.HttpServlet.service (HttpServlet.java:820)
     at org.eclipse.jetty.servlet.ServletHolder.handle (ServletHolder.java∗34)
     at org.eclipse.jetty.servlet.ServletHandler $ CachedChain.doFilter (ServletHandler.java:1351)
     at org.eclipse.jetty.servlets.MultiPartFilter.doFilter (MultiPartFilter.java:97)
     at org.apache.camel.component.jetty.CamelMultipartFilter.doFilter (CamelMultipartFilter.java:41)
     at org.eclipse.jetty.servlet.ServletHandler $ CachedChain.doFilter (ServletHandler.java:1322)
     at org.eclipse.jetty.servlet.ServletHandler.doHandle (ServletHandler.java:473)
     at org.eclipse.jetty.server.handler.ContextHandler.doHandle (ContextHandler.java:929)
     at org.eclipse.jetty.servlet.ServletHandler.doScope (ServletHandler.java:403)
     at org.eclipse.jetty.server.handler.ContextHandler.doScope (ContextHandler.java:864)
     at org.eclipse.jetty.server.handler.ScopedHandler.handle (ScopedHandler.java:117)
     at org.eclipse.jetty.server.handler.HandlerWrapper.handle (HandlerWrapper.java:114)
     at org.eclipse.jetty.server.Server.handle (Server.javahaps52)
     at org.eclipse.jetty.server.HttpConnection.handleRequest (HttpConnection.java∗96)
     at org.eclipse.jetty.server.HttpConnection $ RequestHandler.content (HttpConnection.java:1068)
     at org.eclipse.jetty.http.HttpParser.parseNext (HttpParser.java:805)
     at org.eclipse.jetty.http.HttpParser.parseAvailable (HttpParser.java:218)
     at org.eclipse.jetty.server.HttpConnection.handle (HttpConnection.java:426)
     at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle (SelectChannelEndPoint.java:508)
     at org.eclipse.jetty.io.nio.SelectChannelEndPoint.access $ 000 (SelectChannelEndPoint.java:34)
     at org.eclipse.jetty.io.nio.SelectChannelEndPoint $ 1.run (SelectChannelEndPoint.java:40)
     at org.eclipse.jetty.util.thread.QueuedThreadPool $ 2.run (QueuedThreadPool.java:451)
     at java.lang.Thread.run (Thread.java:662) 
+8
source share
4 answers

Now working, as it turned out, I had a fundamental misunderstanding of the endpoints and protocols in Camel. I had to register a scheme with https4 protocol and install my SSLSocketFactory / SSLContext on it. Since it registered the scheme with https, it was never used by the Http4 component.

Here is my working solution with two caveats.

  • Why can't I pass SchemeRegistry to ThreadSafeClientConnManager and is not used when constructing HttpClient? I should instead of HttpClientConfigurer

  • Jetty has a problem where Keystore and trusted storage should be installed along the path to the SslSelectChannelConnector instead of via SSLContext (error in at least berth 7.2.2 and 7.4.0 → last)

the code:

 public class CamelProxy { /** * @param args */ public static void main(String[] args) throws Exception { CamelContext context = new DefaultCamelContext(); final Endpoint jettyEndpoint = configureJetty(context); final Endpoint https4Endpoint = configureHttpClient(context); context.addRoutes(new RouteBuilder() { @Override public void configure() { from(jettyEndpoint).to("log:com.smithforge.request?showAll=true").to(https4Endpoint); } }); context.start(); context.stop(); } private static Endpoint configureHttpClient(CamelContext context) throws Exception { KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(new FileInputStream(new File("/home/brian/User2.p12")), "Password1234!".toCharArray()); KeyStore truststore = KeyStore.getInstance("JKS"); truststore.load(new FileInputStream(new File("/home/brian/jboss.truststore")), "changeit".toCharArray()); KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("SunX509"); keyFactory.init(keystore, "Password1234!".toCharArray()); TrustManagerFactory trustFactory = TrustManagerFactory.getInstance("SunX509"); trustFactory.init(truststore); SSLContext sslcontext = SSLContext.getInstance("TLSv1"); sslcontext.init(keyFactory.getKeyManagers(), trustFactory.getTrustManagers(), null); SSLSocketFactory factory = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); SchemeRegistry registry = new SchemeRegistry(); final Scheme scheme = new Scheme("https4", 443, factory); registry.register(scheme); HttpComponent http4 = context.getComponent("http4", HttpComponent.class); http4.setHttpClientConfigurer(new HttpClientConfigurer() { @Override public void configureHttpClient(HttpClient client) { client.getConnectionManager().getSchemeRegistry().register(scheme); } }); http4.setClientConnectionManager(new ThreadSafeClientConnManager()); return http4 .createEndpoint("https4://soafa-lite-staging:443/axis2/services/SigActService?bridgeEndpoint=true&throwExceptionOnFailure=false"); } private static Endpoint configureJetty(CamelContext context) throws Exception { JettyHttpComponent jetty = context.getComponent("jetty", JettyHttpComponent.class); SslSelectChannelConnector sslConnector = new SslSelectChannelConnector(); sslConnector.setPort(4443); sslConnector.setKeystore("/home/brian/jboss.keystore"); sslConnector.setKeyPassword("changeit"); sslConnector.setTruststore("/home/brian/jboss.truststore"); sslConnector.setTrustPassword("changeit"); sslConnector.setPassword("changeit"); sslConnector.setNeedClientAuth(true); sslConnector.setAllowRenegotiate(true); Map<Integer, SslSelectChannelConnector> connectors = new HashMap<Integer, SslSelectChannelConnector>(); connectors.put(4443, sslConnector); jetty.setSslSocketConnectors(connectors); return jetty.createEndpoint("jetty:https://localhost:4443/service"); } // .to("log:com.smithforge.response?showHeaders=true"); } 
+11
source

I need to work out ssl proxy with the following code

Route

 public class MyRouteBuilder extends RouteBuilder { public void configure() { configureSslForJetty(); configureSslForHttp4(); from("jetty:https://0.0.0.0:4443/topython/?matchOnUriPrefix=true") .to("https4://backend.fake.com:4444/?q=ssl&bridgeEndpoint=true&throwExceptionOnFailure=false"); } ... 

Configuration for the berth (provide a certificate when we act as a server)

 private void configureSslForJetty() { KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("c:\\Projects\\blah\\fakefilter.jks"); ksp.setPassword("123456"); KeyManagersParameters kmp = new KeyManagersParameters(); kmp.setKeyStore(ksp); kmp.setKeyPassword("export-password"); SSLContextParameters scp = new SSLContextParameters(); scp.setKeyManagers(kmp); JettyHttpComponent jettyComponent = getContext().getComponent("jetty", JettyHttpComponent.class); jettyComponent.setSslContextParameters(scp); } 

Configuration for https4 (which certificate signers trust us, acting as a client)

 private void configureSslForHttp4() { KeyStoreParameters trust_ksp = new KeyStoreParameters(); trust_ksp.setResource("c:\\Projects\\blah\\fakeca.jks"); trust_ksp.setPassword("123456"); TrustManagersParameters trustp = new TrustManagersParameters(); trustp.setKeyStore(trust_ksp); SSLContextParameters scp = new SSLContextParameters(); scp.setTrustManagers(trustp); HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class); httpComponent.setSslContextParameters(scp); } 

}

Things worth noting

  • you need to configure component https4 not http4
  • -Djavax.net.debug=ssl many useful logs provided on the command line
+3
source

It looks like you have problems with ' unsafe ssl renegotiation '. Make sure you are using the latest version of JDK / JRE (at least 1.6.0_24).

0
source

Could you provide the above implementation for Spring DSL

0
source

All Articles