From cedcd7e47c51b66e1aa11ac74c4835ef7d5dd22b Mon Sep 17 00:00:00 2001 From: Joe Steele Date: Tue, 3 Dec 2013 19:20:20 -0500 Subject: [PATCH] Eliminate the need to pass a context to LocalKeyStore.getInstance Instead, have K9.onCreate initialize the location of the key store file (similar to what is done with BinaryTempFileBody.setTempDirectory). Also, LocalKeyStore.getInstance has been changed so that it no longer needs to be synchronized. --- src/com/fsck/k9/Account.java | 12 +++---- src/com/fsck/k9/K9.java | 3 ++ src/com/fsck/k9/Preferences.java | 3 +- .../setup/AccountSetupCheckSettings.java | 2 +- .../activity/setup/AccountSetupIncoming.java | 2 +- .../activity/setup/AccountSetupOutgoing.java | 2 +- .../fsck/k9/net/ssl/TrustManagerFactory.java | 3 +- src/com/fsck/k9/security/LocalKeyStore.java | 34 +++++++++++-------- .../k9/net/ssl/TrustManagerFactoryTest.java | 2 +- 9 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java index c2939a4ee..67a83e7ef 100644 --- a/src/com/fsck/k9/Account.java +++ b/src/com/fsck/k9/Account.java @@ -1873,7 +1873,7 @@ public class Account implements BaseAccount { /** * Add a new certificate for the incoming or outgoing server to the local key store. */ - public void addCertificate(Context context, CheckDirection direction, + public void addCertificate(CheckDirection direction, X509Certificate certificate) throws CertificateException { Uri uri; if (direction.equals(CheckDirection.INCOMING)) { @@ -1881,7 +1881,7 @@ public class Account implements BaseAccount { } else { uri = Uri.parse(getTransportUri()); } - LocalKeyStore localKeyStore = LocalKeyStore.getInstance(context); + LocalKeyStore localKeyStore = LocalKeyStore.getInstance(); localKeyStore.addCertificate(uri.getHost(), uri.getPort(), certificate); } @@ -1890,7 +1890,7 @@ public class Account implements BaseAccount { * new host/port, then try and delete any (possibly non-existent) certificate stored for the * old host/port. */ - public void deleteCertificate(Context context, String newHost, int newPort, + public void deleteCertificate(String newHost, int newPort, CheckDirection direction) { Uri uri; if (direction.equals(CheckDirection.INCOMING)) { @@ -1905,7 +1905,7 @@ public class Account implements BaseAccount { return; } if (!newHost.equals(oldHost) || newPort != oldPort) { - LocalKeyStore localKeyStore = LocalKeyStore.getInstance(context); + LocalKeyStore localKeyStore = LocalKeyStore.getInstance(); localKeyStore.deleteCertificate(oldHost, oldPort); } } @@ -1914,8 +1914,8 @@ public class Account implements BaseAccount { * Examine the settings for the account and attempt to delete (possibly non-existent) * certificates for the incoming and outgoing servers. */ - public void deleteCertificates(Context context) { - LocalKeyStore localKeyStore = LocalKeyStore.getInstance(context); + public void deleteCertificates() { + LocalKeyStore localKeyStore = LocalKeyStore.getInstance(); Uri uri = Uri.parse(getStoreUri()); localKeyStore.deleteCertificate(uri.getHost(), uri.getPort()); diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java index a4bed493b..8ad98b96c 100644 --- a/src/com/fsck/k9/K9.java +++ b/src/com/fsck/k9/K9.java @@ -39,6 +39,7 @@ import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.internet.BinaryTempFileBody; import com.fsck.k9.mail.store.LocalStore; import com.fsck.k9.provider.UnreadWidgetProvider; +import com.fsck.k9.security.LocalKeyStore; import com.fsck.k9.service.BootReceiver; import com.fsck.k9.service.MailService; import com.fsck.k9.service.ShutdownReceiver; @@ -590,6 +591,8 @@ public class K9 extends Application { */ BinaryTempFileBody.setTempDirectory(getCacheDir()); + LocalKeyStore.setKeyStoreLocation(getDir("KeyStore", MODE_PRIVATE).toString()); + /* * Enable background sync of messages */ diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java index 604dce62d..51b83d873 100644 --- a/src/com/fsck/k9/Preferences.java +++ b/src/com/fsck/k9/Preferences.java @@ -15,7 +15,6 @@ import android.util.Log; import com.fsck.k9.mail.Store; import com.fsck.k9.preferences.Editor; import com.fsck.k9.preferences.Storage; -import com.fsck.k9.security.LocalKeyStore; public class Preferences { @@ -128,7 +127,7 @@ public class Preferences { Store.removeAccount(account); - account.deleteCertificates(mContext); + account.deleteCertificates(); account.delete(this); if (newAccount == account) { diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java index 06d13a27e..ea2d1c166 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java @@ -363,7 +363,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { try { - mAccount.addCertificate(getApplicationContext(), mDirection, chain[0]); + mAccount.addCertificate(mDirection, chain[0]); } catch (CertificateException e) { showErrorDialog( R.string.account_setup_failed_dlg_certificate_message_fmt, diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java index 5dab22924..e58fc8846 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java @@ -428,7 +428,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener mWebdavMailboxPathView.getText().toString()); } - mAccount.deleteCertificate(this, host, port, CheckDirection.INCOMING); + mAccount.deleteCertificate(host, port, CheckDirection.INCOMING); ServerSettings settings = new ServerSettings(mStoreType, host, port, connectionSecurity, authType, username, password, extra); diff --git a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java index b40cc9514..6d1af8bc0 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java @@ -312,7 +312,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener, String newHost = mServerView.getText().toString(); int newPort = Integer.parseInt(mPortView.getText().toString()); uri = new URI(smtpSchemes[securityType], userInfo, newHost, newPort, null, null, null); - mAccount.deleteCertificate(this, newHost, newPort, CheckDirection.OUTGOING); + mAccount.deleteCertificate(newHost, newPort, CheckDirection.OUTGOING); mAccount.setTransportUri(uri.toString()); AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING); } catch (UnsupportedEncodingException enc) { diff --git a/src/com/fsck/k9/net/ssl/TrustManagerFactory.java b/src/com/fsck/k9/net/ssl/TrustManagerFactory.java index 9041b2617..0292202fc 100644 --- a/src/com/fsck/k9/net/ssl/TrustManagerFactory.java +++ b/src/com/fsck/k9/net/ssl/TrustManagerFactory.java @@ -3,7 +3,6 @@ package com.fsck.k9.net.ssl; import android.util.Log; -import com.fsck.k9.K9; import com.fsck.k9.helper.DomainNameChecker; import com.fsck.k9.mail.CertificateChainException; import com.fsck.k9.security.LocalKeyStore; @@ -102,7 +101,7 @@ public final class TrustManagerFactory { static { try { - keyStore = LocalKeyStore.getInstance(K9.app); + keyStore = LocalKeyStore.getInstance(); javax.net.ssl.TrustManagerFactory tmf = javax.net.ssl.TrustManagerFactory.getInstance("X509"); tmf.init((KeyStore) null); diff --git a/src/com/fsck/k9/security/LocalKeyStore.java b/src/com/fsck/k9/security/LocalKeyStore.java index 8e88f2593..f7b34939c 100644 --- a/src/com/fsck/k9/security/LocalKeyStore.java +++ b/src/com/fsck/k9/security/LocalKeyStore.java @@ -13,7 +13,6 @@ import java.security.cert.X509Certificate; import org.apache.commons.io.IOUtils; -import android.content.Context; import android.util.Log; import com.fsck.k9.K9; @@ -21,26 +20,32 @@ import com.fsck.k9.K9; public class LocalKeyStore { private static final int KEY_STORE_FILE_VERSION = 1; - private static LocalKeyStore sInstance; + private static String sKeyStoreLocation; + public static void setKeyStoreLocation(String directory) { + sKeyStoreLocation = directory; + } - public synchronized static LocalKeyStore getInstance(Context context) { - if (sInstance == null) { - sInstance = new LocalKeyStore(context); - } - return sInstance; + private static class LocalKeyStoreHolder { + static final LocalKeyStore INSTANCE = new LocalKeyStore(); + } + + public static LocalKeyStore getInstance() { + return LocalKeyStoreHolder.INSTANCE; } - private final Context mContext; private File mKeyStoreFile; private KeyStore mKeyStore; - private LocalKeyStore(Context context) { - mContext = context.getApplicationContext(); - upgradeKeyStoreFile(); - setKeyStoreFile(null); + private LocalKeyStore() { + if (sKeyStoreLocation == null) { + Log.e(K9.LOG_TAG, "Local key store location has not been initialized"); + } else { + upgradeKeyStoreFile(); + setKeyStoreFile(null); + } } /** @@ -167,11 +172,10 @@ public class LocalKeyStore { } private String getKeyStoreFilePath(int version) { - File dir = mContext.getDir("KeyStore", Context.MODE_PRIVATE); if (version < 1) { - return dir + File.separator + "KeyStore.bks"; + return sKeyStoreLocation + File.separator + "KeyStore.bks"; } else { - return dir + File.separator + "KeyStore_v" + version + ".bks"; + return sKeyStoreLocation + File.separator + "KeyStore_v" + version + ".bks"; } } } diff --git a/tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java b/tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java index 8b12fb9c4..01c91ef93 100644 --- a/tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java +++ b/tests/src/com/fsck/k9/net/ssl/TrustManagerFactoryTest.java @@ -208,7 +208,7 @@ public class TrustManagerFactoryTest extends AndroidTestCase { @Override public void setUp() throws Exception { mKeyStoreFile = File.createTempFile("localKeyStore", null, getContext().getCacheDir()); - mKeyStore = LocalKeyStore.getInstance(getContext()); + mKeyStore = LocalKeyStore.getInstance(); mKeyStore.setKeyStoreFile(mKeyStoreFile); }