Hello, I am facing an issue where broker has multiple certificates in its keystore and different clients trust stores have different but always a subset of certificates present in broker's keystore. The clients are NOT able to connect to broker when the FIRST certificate in its trust store does NOT the match the FIRST certificate in the broker's key store. The order I am refering to is the order in which keytool lists the certificates. I am wondering whether there is any such restriction? I really appreciate if someone can comment on this or whether I am missing any steps in the code snippet below. I did not find any information about such restriction. Hence, this posting.
eg : Broker Key Store Cert Order --- Client Trust Store Cert Order ----- Result C1 C1 Works C1,C2 C1 Works C1,C2 C1,C2 WOrks C1,C2 C2 Does NOT work C1,C2 C2,C1 Does NOT work The detailed info follows. I apologize for long info; but want to provide as much info as possible. I followed the steps mentioned in this setup page (http://activemq.apache.org/how-do-i-use-ssl.html) to setup a ssl broker keystore and client trust store. It is embedded broker env. I am not using "needClientAuth" setting. ActiveMQ version 5.13.1 and JDK 8 Exception in failure case noted above (#4 and #5) Caused by: javax.jms.JMSException: Could not connect to broker URL: ssl://10.1.1.10:61617. Reason: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36) at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:373) at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:303) at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:243) at org.apache.activemq.jms.pool.PooledConnectionFactory.createConnection(PooledConnectionFactory.java:283) at org.apache.activemq.jms.pool.PooledConnectionFactory$1.makeObject(PooledConnectionFactory.java:96) at org.apache.activemq.jms.pool.PooledConnectionFactory$1.makeObject(PooledConnectionFactory.java:93) at org.apache.commons.pool2.impl.GenericKeyedObjectPool.create(GenericKeyedObjectPool.java:1041) at org.apache.commons.pool2.impl.GenericKeyedObjectPool.addObject(GenericKeyedObjectPool.java:1221) at org.apache.activemq.jms.pool.PooledConnectionFactory.createConnection(PooledConnectionFactory.java:229) ... 32 more Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:928) at sun.security.ssl.AppInputStream.read(AppInputStream.java:105) at org.apache.activemq.transport.tcp.TcpBufferedInputStream.fill(TcpBufferedInputStream.java:50) at org.apache.activemq.transport.tcp.TcpTransport$2.fill(TcpTransport.java:629) at org.apache.activemq.transport.tcp.TcpBufferedInputStream.read(TcpBufferedInputStream.java:59) at org.apache.activemq.transport.tcp.TcpTransport$2.read(TcpTransport.java:614) at java.io.DataInputStream.readInt(DataInputStream.java:387) at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:267) at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:240) at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:232) at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215) The Broker Start up code snippet: broker = new SslBrokerService(); .... try { KeyManager[] km = getKeyManager(); TrustManager[] tm = getTrustManager(); broker.addSslConnector("ssl://10.1.1.10:61617", km, tm, null); } catch (Exception e) { logger.error("Exception:", (Exception)e); } broker.start(); broker.waitUntilStarted(); .... private KeyManager[] getKeyManager() throws Exception { KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); //SunX509 KeyStore ks = KeyStore.getInstance("JKS"); KeyManager[] keystoreManagers = null; byte[] sslCert = loadClientCredential(sslServerKeyStore); if (sslCert != null && sslCert.length > 0) { ByteArrayInputStream bin = new ByteArrayInputStream(sslCert); ks.load(bin, sslKeyStorePassword.toCharArray()); kmf.init(ks, sslKeyStorePassword.toCharArray()); keystoreManagers = kmf.getKeyManagers(); } return keystoreManagers; ## There is one entry in the array here and ## the credentialsMap in that entry contains the N number of certs which match the order in ks. } private TrustManager[] getTrustManager() throws Exception { TrustManager[] trustStoreManagers = null; KeyStore trustedCertStore = KeyStore.getInstance(sslKeyStoreType); trustedCertStore.load(new FileInputStream(sslTrustKeyStore), null); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustedCertStore); trustStoreManagers = tmf.getTrustManagers(); return trustStoreManagers; } private byte[] loadClientCredential(String fileName) throws IOException { if (fileName == null) { return null; } FileInputStream in = new FileInputStream(fileName); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[512]; int i = in.read(buf); while (i > 0) { out.write(buf, 0, i); i = in.read(buf); } in.close(); return out.toByteArray(); } Client Code snippets: ActiveMQSslConnectionFactory activeConnFact = new ActiveMQSslConnectionFactory(brokerurl); activeConnFact.setKeyStore(clientKeyStoreFile); activeConnFact.setTrustStore(clientTrustStoreFile); activeConnFact.setKeyStorePassword(clientKeyStorePassword); activeConnFact.setTrustStorePassword(clientTrustStorePassword); activeConnFact.setTrustAllPackages(true); PooledConnectionFactory pf = new PooledConnectionFactory(); pf.setConnectionFactory(activeConnFact); pf.setMaxConnections(num); Connection c = pf.createConnection(); c.start(); Session s = c.createSession(false, Session.CLIENT_ACKNOWLEDGE); ... MessageProducer p = s.createProducer(topic); p.send(m, DeliveryMode.PERSISTENT, Message.DEFAULT_PRIORITY, msgTTL); ... AllCloseCalls.... Thanks again. Regards, Chandra -- View this message in context: http://activemq.2283324.n4.nabble.com/Order-of-certificates-in-broker-key-store-and-client-trust-store-problem-tp4718495.html Sent from the ActiveMQ - User mailing list archive at Nabble.com.