From: Tobias Brunner Date: Fri, 30 May 2014 13:13:50 +0000 (+0200) Subject: android: Cache certificates from multiple KeyStores X-Git-Tag: 5.2.1dr1~117^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8cdce00eb1160b9f1ce5d6df4e1423ba11bf1d26;p=thirdparty%2Fstrongswan.git android: Cache certificates from multiple KeyStores Including the new local one. --- diff --git a/src/frontends/android/src/org/strongswan/android/logic/TrustedCertificateManager.java b/src/frontends/android/src/org/strongswan/android/logic/TrustedCertificateManager.java index 95fdecf14d..a5cea4499e 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/TrustedCertificateManager.java +++ b/src/frontends/android/src/org/strongswan/android/logic/TrustedCertificateManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * Hochschule fuer Technik Rapperswil @@ -21,6 +21,7 @@ import java.security.KeyStore; import java.security.KeyStoreException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -33,12 +34,28 @@ public class TrustedCertificateManager private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock(); private Hashtable mCACerts = new Hashtable(); private boolean mLoaded; + private final ArrayList mKeyStores = new ArrayList(); /** * Private constructor to prevent instantiation from other classes. */ private TrustedCertificateManager() { + for (String name : new String[] { "LocalCertificateStore", "AndroidCAStore" }) + { + KeyStore store; + try + { + store = KeyStore.getInstance(name); + store.load(null,null); + mKeyStores.add(store); + } + catch (Exception e) + { + Log.e(TAG, "Unable to load KeyStore: " + name); + e.printStackTrace(); + } + } } /** @@ -96,29 +113,23 @@ public class TrustedCertificateManager private void loadCertificates() { Log.d(TAG, "Load cached CA certificates"); - try - { - KeyStore store = KeyStore.getInstance("AndroidCAStore"); - store.load(null, null); - this.mCACerts = fetchCertificates(store); - this.mLoaded = true; - Log.d(TAG, "Cached CA certificates loaded"); - } - catch (Exception ex) + Hashtable certs = new Hashtable(); + for (KeyStore store : this.mKeyStores) { - ex.printStackTrace(); - this.mCACerts = new Hashtable(); + fetchCertificates(certs, store); } + this.mCACerts = certs; + this.mLoaded = true; + Log.d(TAG, "Cached CA certificates loaded"); } /** * Load all X.509 certificates from the given KeyStore. + * @param certs Hashtable to store certificates in * @param store KeyStore to load certificates from - * @return Hashtable mapping aliases to certificates */ - private Hashtable fetchCertificates(KeyStore store) + private void fetchCertificates(Hashtable certs, KeyStore store) { - Hashtable certs = new Hashtable(); try { Enumeration aliases = store.aliases(); @@ -137,7 +148,6 @@ public class TrustedCertificateManager { ex.printStackTrace(); } - return certs; } /** @@ -157,27 +167,28 @@ public class TrustedCertificateManager else { /* if we cannot get the lock load it directly from the KeyStore, * should be fast for a single certificate */ - try + for (KeyStore store : this.mKeyStores) { - KeyStore store = KeyStore.getInstance("AndroidCAStore"); - store.load(null, null); - Certificate cert = store.getCertificate(alias); - if (cert != null && cert instanceof X509Certificate) + try { - certificate = (X509Certificate)cert; + Certificate cert = store.getCertificate(alias); + if (cert != null && cert instanceof X509Certificate) + { + certificate = (X509Certificate)cert; + break; + } + } + catch (KeyStoreException e) + { + e.printStackTrace(); } } - catch (Exception e) - { - e.printStackTrace(); - } - } return certificate; } /** - * Get all CA certificates (from the system and user keystore). + * Get all CA certificates (from all keystores). * @return Hashtable mapping aliases to certificates */ @SuppressWarnings("unchecked") @@ -196,17 +207,7 @@ public class TrustedCertificateManager */ public Hashtable getSystemCACertificates() { - Hashtable certs = new Hashtable(); - this.mLock.readLock().lock(); - for (String alias : this.mCACerts.keySet()) - { - if (alias.startsWith("system:")) - { - certs.put(alias, this.mCACerts.get(alias)); - } - } - this.mLock.readLock().unlock(); - return certs; + return getCertificates("system:"); } /** @@ -214,12 +215,31 @@ public class TrustedCertificateManager * @return Hashtable mapping aliases to certificates */ public Hashtable getUserCACertificates() + { + return getCertificates("user:"); + } + + /** + * Get only the local CA certificates installed by the user. + * @return Hashtable mapping aliases to certificates + */ + public Hashtable getLocalCACertificates() + { + return getCertificates("local:"); + } + + /** + * Get all certificates whose aliases start with the given prefix. + * @param prefix prefix to filter certificates + * @return Hashtable mapping aliases to certificates + */ + private Hashtable getCertificates(String prefix) { Hashtable certs = new Hashtable(); this.mLock.readLock().lock(); for (String alias : this.mCACerts.keySet()) { - if (alias.startsWith("user:")) + if (alias.startsWith(prefix)) { certs.put(alias, this.mCACerts.get(alias)); }