2

I have this scenario where my App needs to make requests towards a secure server (NON http(s), actually it is about SIP protocol but the question should apply to any non http(s) protocol), and I need be able to tell if the server is considered trusted, based on the System Default Trusted certificates installed in my Android device's keystore.

The problem is that after checking all the APIs Android provides for certificates (like KeyStore, KeyChain, etc) I haven't been able to find a solution.

Seems that each app, even though it can gain access to the System Default keystore of the device, it can only access it's own resources, not global, even when we are talking about TrustedCertificateEntry-type entries.

Is there anything I'm missing here?

Seems like a pretty valid use case for non-https authentication

Best regards, Antonis

atsakiridis
  • 1,002
  • 5
  • 19

1 Answers1

4

Finally, managed to find a way to do this, so let me share in case this can be useful to others. Turns out Android gives access to system wide trusted certificates. The detail here (and the reason it didn't work for me previously) was the keystore 'type' identifier that I used:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");

Which I believe was trying to find actual keys, which off course shouldn't be shared. So after some digging I found that there's a separate type, AndroidCAStore, which did the trick for me. So here's a working code excerpt, that just prints out certificates:

try {
  KeyStore ks = KeyStore.getInstance("AndroidCAStore");
  ks.load(null);

  try {
    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements()) {
      Certificate cert = ks.getCertificate(aliases.nextElement());
      Log.e(TAG, "Certificate: " + cert.toString());
    }
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}
catch (IOException|NoSuchAlgorithmException|KeyStoreException|CertificateException e) {
  e.printStackTrace();
}
atsakiridis
  • 1,002
  • 5
  • 19