There is already a valid cert in my keystore and handshake process with server is working. When another cert with different CN is added in the same keystore and connect with server, get the error from server "Access denied, invalid endpoint". I think when connecting with server, the second cert is used in ssl connection when there are two valid certs for client certs usage (the existing one and the newly imported one). What I want to know is which one is used if there are one than more valid certs in keystore. Is it related with certs alias? The following is code snippet for socket connection.
try {
SSLSocketFactory factory = null;
try {
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "*****".toCharArray();
ctx = SSLContext.getInstance("TLSv1.2");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("testkeys"), passphrase);
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
factory = ctx.getSocketFactory();
} catch (Exception e) {
throw new IOException(e.getMessage());
}
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
String[] cipherSuites = socket.getSupportedCipherSuites();
socket.setEnabledCipherSuites( cipherSuites );
socket.setNeedClientAuth(false);
socket.startHandshake();
Similar Which key and certificate from keystore and truststore is used when there are many? for server.
For SunX509 KeyManagerFactory:
at initialization it creates a HashMap containing all the privatekey entries from the keystore, keyed by alias;
handshake calls
chooseClientAlias
which, for each <=1.2 certificate_type or 1.3 sigalg specified/requested by the server (either called keyType in the code) checks each HashMap entry inHashIterator
order (which is determined by a variable number of low bits of a value derived from the hashcode of the alias) to see if the leaf cert has that keytype, and any cert in the chain is issued by one of the CAs specified by the server unless the server left the CA list empty in which case this part of the check is skipped.If you're getting the wrong cert-and-key selected, check if the server is specifying a correct CA-list in its CertificateRequest message. You can do this on the Java client side by running with sysprop
javax.net.debug=ssl:handshake
, or except in 1.3 a network level tool like wireshark or tcpdump.