I've previously asked this question, but received no help. I've made some progress but am stuck again with a new error.
I must make use of a secure device which keeps key pairs and CA certificates save. I must now use this device when the application makes a TLS connection to a server which requires mutual authentication. I have a class "KeyPair" which is able to communicate with the secure device.
My problem is that when the ssl connection is made I get an error "tlsv1 alert unknown ca" on the client and "SSL3_GET_CLIENT_CERTIFICATE:no certificate returned" on the server. My debug logs show that the SSL context does query my object as the trust manager. First my checkServerTrusted() function is called which passes. Next the chooseClientAlias() function is called followed by the getPrivateKey() function with the client alias. At this point I extract the private key from the device and return it. Next the function getCertificateChain() is called and I get and return the matching certificate and its signer CA in an array. My debug output shows the certs being returned as:
Subject DN: CN=be2576a357228b303189ab62bd2497807d2276493ddfc6fd037a0c8fc6e9ac9a,C=YY,E=a@b.com
Issuer DN: O=myCompany,E=email@mydomain.net,L=myCity,ST=myState,C=XX,CN=LJB
Serial Num = 3877882041
Subject DN = O=myCompany,E=email@mydomain.net,L=myCity,ST=myState,C=XX,CN=LJB
Issuer DN = O=myCompany,E=email@mydomain.net,L=myCity,ST=myState,C=XX,CN=LJB
Serial Num = 10069430368951295741
The SSL connection then pauses before failing with the above mentioned error.
I've extended the "KeyPair" class to act as a key and trust manager like this:
public class Keypair implements X509KeyManager, X509TrustManager
In this class I override all the functions for these managers to see what gets called when. My application will always be a client working to a server.
So during the creation of this class object and after all the tests of a key pair on the device is successful I create a SSL context which makes use of the particular key pair. For now there is only one key pair on the device. I use,...
sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(new KeyManager[] {this}, new TrustManager[] {this}, new SecureRandom());
Later a task will use this object to create a connection to the server
protected boolean Connect(String host, int port) {
SSLSocketFactory factory = getKeypair().getSecureSocketFactory();
socket = (SSLSocket) factory.createSocket(host, port);
:
}
where the getSecureSocketFactory() function simply return sslCtx.getSocketFactory() from the keypair class object.
I've search a lot and seen code which create factories etc., but none has been able to help me. I do not want to create any key stores - that is the purpose of the device.
So to which 'CA' does the error refer? The server certificate is also directly signed by the above CA. The connection works if I do not require the client to authenticate. I am testing on a phone with Android 4.1.2.
Follow up: I am sure my problem lies with my getCertificateChain() function. I simply include the public and CA certificates which I retrieve from the secure device. It should never make use of any certificate included with Android. So, can anybody give me some pointers on the rules about returning my chain? Do I understand 'chain' correct: This must be the certificate which matches the private key as well as all certificates up to the main CA (self signed)?"