15

I had installed a certificate programmatically.

I am able to uninstall it manually by going Settings -> Security -> Trusted Credentials -> User -> Choose the certificate and click the remove button

I want to remove the certificate programmatically.

Here is the code that I tried but it didn't work.

javax.security.cert.X509Certificate x509 = javax.security.cert.X509Certificate.getInstance(caRootCertBytes);

KeyStore ks = KeyStore.getInstance("AndroidCAStore")
if (ks != null) 
{
    ks.load(null, null);
    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements()) 
    {
        String alias = (String) aliases.nextElement();
        java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) ks.getCertificate(alias);
        String name = x509.getIssuerDN().getName();                             
        if (cert.getIssuerDN().getName().contains(name)) 
        {
            ks. deleteEntry(alias)
        }
    }
}

Ref for why I chose deleteEntry

Here is the error log that I got

05-19 18:27:40.789: W/System.err(14588): java.lang.UnsupportedOperationException
05-19 18:27:40.792: W/System.err(14588):    at com.android.org.conscrypt.TrustedCertificateKeyStoreSpi.engineDeleteEntry(TrustedCertificateKeyStoreSpi.java:82)
05-19 18:27:40.792: W/System.err(14588):    at java.security.KeyStore.deleteEntry(KeyStore.java:410)
05-19 18:27:40.792: W/System.err(14588):    at com.proj.test.MyActivity$4.onClick(MyActivity.java:336)
05-19 18:27:40.792: W/System.err(14588):    at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
05-19 18:27:40.792: W/System.err(14588):    at android.os.Handler.dispatchMessage(Handler.java:102)
05-19 18:27:40.792: W/System.err(14588):    at android.os.Looper.loop(Looper.java:135)
05-19 18:27:40.793: W/System.err(14588):    at android.app.ActivityThread.main(ActivityThread.java:5254)
05-19 18:27:40.793: W/System.err(14588):    at java.lang.reflect.Method.invoke(Native Method)
05-19 18:27:40.794: W/System.err(14588):    at java.lang.reflect.Method.invoke(Method.java:372)
05-19 18:27:40.794: W/System.err(14588):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
05-19 18:27:40.794: W/System.err(14588):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

This question is somewhat related to my other question

Any help is appreciated !

Community
  • 1
  • 1
Durai Amuthan.H
  • 31,670
  • 10
  • 160
  • 241
  • Related on AOSP Bug Reporter: [Issue 174714: No general purpose method to remove a CA certifcate that was programmatically installed](https://code.google.com/p/android/issues/detail?id=174714). – jww May 26 '15 at 08:11

2 Answers2

6

Looks like that implementation of the KeyStoreSpi interface just doesn't support removal:

@Override
public void engineDeleteEntry(String alias) {
    throw new UnsupportedOperationException();
}

https://android.googlesource.com/platform/external/conscrypt/+/master/src/platform/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java#81

Buddy
  • 10,874
  • 5
  • 41
  • 58
  • So aren't there anyways to remove the installed certificate programmatically ? – Durai Amuthan.H May 23 '15 at 19:23
  • 1
    Probably not from a normal user application. But you can take a look at how the Android Settings does it: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.4.4_r1/com/android/settings/TrustedCredentialsSettings.java#TrustedCredentialsSettings – Buddy May 23 '15 at 23:04
  • I couldn't import `IKeyChainService` and `KeyChainConnection` ..I get **Cannot resolve symbol** error. – Durai Amuthan.H May 24 '15 at 09:23
  • Yeah Android hides a lot of stuff that is for "system use only" – Buddy May 24 '15 at 14:13
  • 2
    Probably done for security reasons. That is, Android modeled a *Threat* where the bad guy programmatically deleted certs and caused a DoS on a user, site or service. The mitigation was to remove the programmatic interface. Maybe it would have been better to allow modification of the store (inserts and deletes), but require a user confirmation. – jww May 25 '15 at 21:35
  • 1
    @jww - like `installintent` of `Keychain` they could have provided some `uninstallintent` which will act upon *users discretion* – Durai Amuthan.H May 26 '15 at 04:21
5

You can do this in Android 5.x with a device owner using the uninstallCaCert() method. A device owner can be installed only before the device is provisioned though.

https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#uninstallCaCert(android.content.ComponentName, byte[])

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • 1
    Is it possible to use `TrustedCertificateStore` class and `deleteCertificateEntry`? Your [blog on ICS Trust Store](http://nelenkov.blogspot.com/2011/12/ics-trust-store-implementation.html) mentions `TrustedCertificateStore`. – jww May 26 '15 at 01:52
  • Short answer: No. Long answer: you can't mess with system files without system-level permissions. You can probably do something with root access, but usually not great idea. Not sure what the app does, but If the cert is used only by your app, don't install it in the system store at all. – Nikolay Elenkov May 26 '15 at 06:46
  • @Durai: *"To inspect SSL traffic we're doing SSL piercing..."* - I was just commenting to the folks in the TLS Working Group about this. Or more correctly, the pollution of standards due to the web/browser security model. See [TLS: prohibit <1.2 on clients (but allow servers)](https://www.ietf.org/mail-archive/web/tls/current/msg16495.html). – jww May 26 '15 at 08:02
  • @DuraiAmuthan.H And why are you inspecting traffic in the first place? I call this a MiTM attack. – Nikolay Elenkov May 26 '15 at 08:46
  • Not sure what 'VPN application' means, but a VPN certainly doesn't need to inspect SSL traffic. – Nikolay Elenkov May 26 '15 at 09:52