Mario Dello Vicario
Mario Dello Vicario

Reputation: 31

Android OkHttp TLS Mutual Auth - Client doesn't send Certificate to Server

I need some help with Android OkHttp client/server application. The problem is the following: it seems like my Android client doesn't send any certificate to the server after receiving a Certificate Request. Here is my Android code:

private static SSLContext getContext(InputStream keystoreInputStream){
    SSLContext sslContext = null;
    try{
        //==========
        try {
            // The keystore contains the CA cert and the Client cert
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            try {
                keyStore.load(keystoreInputStream, "MYPASS".toCharArray());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    ksIn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            sslContext = SSLContext.getInstance("TLS");
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
            keyManagerFactory.init(keyStore, "MYPASS".toCharArray());
            sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //==========
    }catch (Exception e){

    }
    return sslContext;
}

And This is the wireshark session between Android Client (192.168.1.72) and Server (192.168.1.79):

Wireshark TLS session - CLIENT CERTIFICATE (empty)

As you can see the Server sends a Certificate Request but the client sends Certificate with lenght 0. Can you explain me how can I fix this? Thanks.

Upvotes: 1

Views: 1255

Answers (2)

Mario Dello Vicario
Mario Dello Vicario

Reputation: 31

I finally found out that the problem was in my KeyStore and TrustStore files, they just were malformed. I just tried to regenerate them using these simple passages:

  1. Create a txt file containing your client certificate and the key (just copy-paste the key after the certificate).
  2. Generate the KeyStore: openssl pkcs12 -export -in <GENERATED_TXT_FILE> -out <MY_KEY_STORE>.pkcs12 -name <ALIAS> -noiter -nomaciter
  3. Generate the TrustStore: keytool -import -file <CA_CERT_FILE> -alias <ALIAS> -keystore <MY_TRUST_STORE>

I also referred to this implementation of an SSLTrustManagerHelper : SSLTrustManagerHelper class, I leave it here as I found it clean and easily understandable.

Upvotes: 1

Yuri Schimke
Yuri Schimke

Reputation: 13498

First off try the existing setup with a URL like https://server.cryptomix.com/secure. It should print out the client certificate that you send.

Secondly, you can implement a KeyManager yourself and see what is going on, even if it just decorates the Android KeyManager and logs the calls.

https://github.com/yschimke/okhttp/blob/c2d570dcf9c989a95f49f6b97d5df3488c191f73/regression-test/src/androidTest/java/okhttp/regression/keys/ClientAuthAndroidTest.java#L56

Lastly, you can try on the JDK for comparison. In this scenario you can enable SSL logging to see what is going on, but don't expect the same behaviour between JSSE and Android's Conscrypt provider.

Upvotes: 0

Related Questions