title: Apache Camel Http and SSL
body: <p>I have been trying to get a 2-way ssl/https proxy working with Camel.  I have been able to set up the Jetty Component using 2-way ssl and am now attempting to get it working with the Http4 component to complete the client side of the proxy.</p>
  
  <p>When I route the jetty traffic to a log component, all is well and the 2 way ssl trust chain is fine.  When I throw in the Http4 component, it blows up with a peer not authenticated exception. I am using Camel 2.7.0</p>
  
  <p>Here is what I have so far</p>
  
  <pre><code>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&lt;Integer, SslSelectChannelConnector&gt; connectors = new HashMap&lt;Integer, SslSelectChannelConnector&gt;();
      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&amp;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&lt;String&gt; aliasList = new ArrayList&lt;String&gt;();
              int count = 0;
              Enumeration&lt;String&gt; 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 &lt; 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;
      }
  }
  
  }
  </code></pre>
  
  <p>As far as I can tell, the trust should be fine between all keystores/truststores used on both sides of the proxy connections.</p>
  
  <p>Here is my stack trace</p>
  
  <pre>
  [                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.java:352)
      at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
      at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
      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:561)
      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:534)
      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.java:352)
      at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:596)
      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)</pre>