From a9de12520da337d47c703969b339afca0a7b824b Mon Sep 17 00:00:00 2001 From: Ernir Erlingsson <ernir@ymirmobile.com> Date: Fri, 1 Apr 2016 14:34:41 +0200 Subject: [PATCH] phase 2: helpers and app bus --- .../briarproject/android/ActivityModule.java | 25 ++-- .../android/AndroidComponent.java | 3 + .../briarproject/android/BaseActivity.java | 50 ++++---- .../android/NavDrawerActivity.java | 6 +- .../android/PasswordActivity.java | 87 +++++-------- .../briarproject/android/SetupActivity.java | 62 +++------ .../android/SplashScreenActivity.java | 12 +- .../briarproject/android/event/AppBus.java | 6 + .../briarproject/android/event/AppBusImp.java | 25 ++++ .../android/event/ErrorEvent.java | 10 ++ .../event/LocalAuthorCreatedEvent.java | 16 +++ .../android/event/PasswordValidateEvent.java | 16 +++ .../android/helper/ConfigHelper.java | 9 ++ .../android/helper/ConfigHelperImp.java | 41 ++++++ .../android/helper/PasswordHelper.java | 5 + .../android/helper/PasswordHelperImp.java | 70 +++++++++++ .../android/helper/SetupHelper.java | 6 + .../android/helper/SetupHelperImp.java | 119 ++++++++++++++++++ .../android/panic/PanicResponderActivity.java | 11 +- .../briarproject/android/sdk/BriarHelper.java | 4 - .../android/sdk/BriarHelperImp.java | 13 -- 21 files changed, 430 insertions(+), 166 deletions(-) create mode 100644 briar-android/src/org/briarproject/android/event/AppBus.java create mode 100644 briar-android/src/org/briarproject/android/event/AppBusImp.java create mode 100644 briar-android/src/org/briarproject/android/event/ErrorEvent.java create mode 100644 briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java create mode 100644 briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java create mode 100644 briar-android/src/org/briarproject/android/helper/ConfigHelper.java create mode 100644 briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java create mode 100644 briar-android/src/org/briarproject/android/helper/PasswordHelper.java create mode 100644 briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java create mode 100644 briar-android/src/org/briarproject/android/helper/SetupHelper.java create mode 100644 briar-android/src/org/briarproject/android/helper/SetupHelperImp.java delete mode 100644 briar-android/src/org/briarproject/android/sdk/BriarHelper.java delete mode 100644 briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java index 8c1989a711..3ae6e004c3 100644 --- a/briar-android/src/org/briarproject/android/ActivityModule.java +++ b/briar-android/src/org/briarproject/android/ActivityModule.java @@ -4,15 +4,16 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; -import android.support.v4.app.Fragment; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.forum.ForumListFragment; import org.briarproject.android.fragment.BaseFragment; -import org.briarproject.android.sdk.BriarHelper; -import org.briarproject.android.sdk.BriarHelperImp; - -import java.util.logging.Logger; +import org.briarproject.android.helper.PasswordHelper; +import org.briarproject.android.helper.PasswordHelperImp; +import org.briarproject.android.helper.SetupHelper; +import org.briarproject.android.helper.SetupHelperImp; +import org.briarproject.android.helper.ConfigHelper; +import org.briarproject.android.helper.ConfigHelperImp; import javax.inject.Named; @@ -36,13 +37,14 @@ public class ActivityModule { @ActivityScope @Provides - BriarHelper provideBriarHelper(BriarHelperImp briarHelperImp) { - return briarHelperImp; + SetupHelper provideSetupHelper(SetupHelperImp setupHelperImp) { + return setupHelperImp; } @ActivityScope - Logger provideLogger(Activity activity) { - return Logger.getLogger(activity.getClass().getName()); + @Provides + ConfigHelper provideConfigHelper(ConfigHelperImp configHelperImp) { + return configHelperImp; } @ActivityScope @@ -51,6 +53,11 @@ public class ActivityModule { return activity.getSharedPreferences("db", Context.MODE_PRIVATE); } + @ActivityScope + @Provides + PasswordHelper providePasswordHelper(PasswordHelperImp passwordHelperImp) { + return passwordHelperImp; + } @Provides @Named("ForumListFragment") diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java index 8766c4324e..02469114f4 100644 --- a/briar-android/src/org/briarproject/android/AndroidComponent.java +++ b/briar-android/src/org/briarproject/android/AndroidComponent.java @@ -6,6 +6,7 @@ import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.api.ReferenceManager; import org.briarproject.android.contact.ContactListFragment; import org.briarproject.android.contact.ConversationActivity; +import org.briarproject.android.event.AppBus; import org.briarproject.android.forum.AvailableForumsActivity; import org.briarproject.android.forum.ContactSelectorFragment; import org.briarproject.android.forum.CreateForumActivity; @@ -50,6 +51,7 @@ import org.briarproject.system.AndroidSystemModule; import java.util.concurrent.Executor; +import javax.inject.Named; import javax.inject.Singleton; import dagger.Component; @@ -74,6 +76,7 @@ public interface AndroidComponent extends CoreEagerSingletons { IdentityManager identityManager(); PluginManager pluginManager(); EventBus eventBus(); + AppBus appEventBus(); InvitationTaskFactory invitationTaskFactory(); AndroidNotificationManager androidNotificationManager(); ConnectionRegistry connectionRegistry(); diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java index 9e602c9e55..213088daa8 100644 --- a/briar-android/src/org/briarproject/android/BaseActivity.java +++ b/briar-android/src/org/briarproject/android/BaseActivity.java @@ -1,29 +1,30 @@ package org.briarproject.android; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; +import android.support.annotation.CallSuper; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.inputmethod.InputMethodManager; +import org.briarproject.android.event.AppBus; +import org.briarproject.android.event.ErrorEvent; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; + import javax.inject.Inject; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS; -public abstract class BaseActivity extends AppCompatActivity { - - public final static String PREFS_NAME = "db"; - public final static String PREF_DB_KEY = "key"; - public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; +public abstract class BaseActivity extends AppCompatActivity implements + EventListener { protected ActivityComponent activityComponent; - // TODO Shared prefs + @Inject + protected AppBus appBus; @Override public void onCreate(Bundle savedInstanceState) { @@ -42,27 +43,27 @@ public abstract class BaseActivity extends AppCompatActivity { injectActivity(activityComponent); } - public abstract void injectActivity(ActivityComponent component); - - private SharedPreferences getSharedPrefs() { - return getSharedPreferences(PREFS_NAME, MODE_PRIVATE); + @Override + protected void onResume() { + super.onResume(); + appBus.addListener(this); } - protected String getEncryptedDatabaseKey() { - return getSharedPrefs().getString(PREF_DB_KEY, null); + @Override + protected void onPause() { + appBus.removeListener(this); + super.onPause(); } - protected void storeEncryptedDatabaseKey(final String hex) { - SharedPreferences.Editor editor = getSharedPrefs().edit(); - editor.putString(PREF_DB_KEY, hex); - editor.apply(); + @Override + @CallSuper + public void eventOccurred(Event e) { + if (e instanceof ErrorEvent) { + finish(); + } } - protected void clearSharedPrefs() { - SharedPreferences.Editor editor = getSharedPrefs().edit(); - editor.clear(); - editor.apply(); - } + public abstract void injectActivity(ActivityComponent component); protected void showSoftKeyboard(View view) { Object o = getSystemService(INPUT_METHOD_SERVICE); @@ -74,4 +75,5 @@ public abstract class BaseActivity extends AppCompatActivity { Object o = getSystemService(INPUT_METHOD_SERVICE); ((InputMethodManager) o).hideSoftInputFromWindow(token, 0); } + } diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java index af98c88fac..c058bc1968 100644 --- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java +++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java @@ -1,5 +1,6 @@ package org.briarproject.android; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -48,6 +49,8 @@ import static java.util.logging.Level.WARNING; public class NavDrawerActivity extends BriarFragmentActivity implements BaseFragment.BaseFragmentListener, EventListener { + public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; + public static final String INTENT_CONTACTS = "intent_contacts"; public static final String INTENT_FORUMS = "intent_forums"; @@ -137,8 +140,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements } private void welcomeMessageCheck() { - SharedPreferences prefs = getSharedPreferences(PREFS_NAME, - MODE_PRIVATE); + SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE); if (!prefs.getBoolean(PREF_SEEN_WELCOME_MESSAGE, false)) { showMessageDialog(R.string.dialog_title_welcome, R.string.dialog_welcome_message); diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java index 41c2459de3..34dde0fb14 100644 --- a/briar-android/src/org/briarproject/android/PasswordActivity.java +++ b/briar-android/src/org/briarproject/android/PasswordActivity.java @@ -16,14 +16,10 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; +import org.briarproject.android.event.PasswordValidateEvent; +import org.briarproject.android.helper.PasswordHelper; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.api.crypto.CryptoComponent; -import org.briarproject.api.crypto.CryptoExecutor; -import org.briarproject.api.crypto.SecretKey; -import org.briarproject.api.db.DatabaseConfig; -import org.briarproject.util.StringUtils; - -import java.util.concurrent.Executor; +import org.briarproject.api.event.Event; import javax.inject.Inject; @@ -34,28 +30,22 @@ import static android.view.View.VISIBLE; public class PasswordActivity extends BaseActivity { - @Inject @CryptoExecutor protected Executor cryptoExecutor; private Button signInButton; private ProgressBar progress; private TextInputLayout input; private EditText password; - private byte[] encrypted; - - // Fields that are accessed from background threads must be volatile - @Inject protected volatile CryptoComponent crypto; - @Inject protected volatile DatabaseConfig databaseConfig; + @Inject + PasswordHelper passwordHelper; @Override public void onCreate(Bundle state) { super.onCreate(state); - String hex = getEncryptedDatabaseKey(); - if (hex == null || !databaseConfig.databaseExists()) { + if (!passwordHelper.initialized()) { clearSharedPrefsAndDeleteEverything(); return; } - encrypted = StringUtils.fromHexString(hex); setContentView(R.layout.activity_password); signInButton = (Button) findViewById(R.id.btn_sign_in); @@ -66,8 +56,7 @@ public class PasswordActivity extends BaseActivity { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - hideSoftKeyboard(password); - validatePassword(encrypted, password.getText()); + validatePassword(); return true; } }); @@ -103,7 +92,7 @@ public class PasswordActivity extends BaseActivity { } private void clearSharedPrefsAndDeleteEverything() { - clearSharedPrefs(); + passwordHelper.clearPrefs(); AndroidUtils.deleteAppData(this); setResult(RESULT_CANCELED); startActivity(new Intent(this, SetupActivity.class)); @@ -111,7 +100,7 @@ public class PasswordActivity extends BaseActivity { } public void onSignInClick(View v) { - validatePassword(encrypted, password.getText()); + validatePassword(); } public void onForgottenPasswordClick(View v) { @@ -132,47 +121,37 @@ public class PasswordActivity extends BaseActivity { dialog.show(); } - private void validatePassword(final byte[] encrypted, Editable e) { + private void validatePassword() { hideSoftKeyboard(password); - // Replace the button with a progress bar signInButton.setVisibility(INVISIBLE); progress.setVisibility(VISIBLE); - // Decrypt the database key in a background thread - final String password = e.toString(); - cryptoExecutor.execute(new Runnable() { - public void run() { - byte[] key = crypto.decryptWithPassword(encrypted, password); - if (key == null) { - tryAgain(); - } else { - databaseConfig.setEncryptionKey(new SecretKey(key)); - setResultAndFinish(); - } - } - }); - } - - private void tryAgain() { - runOnUiThread(new Runnable() { - public void run() { - AndroidUtils.setError(input, getString(R.string.try_again), - true); - signInButton.setVisibility(VISIBLE); - progress.setVisibility(INVISIBLE); - password.setText(""); - - // show the keyboard again - showSoftKeyboard(password); - } - }); + passwordHelper.validatePassword(password.getText().toString()); } - private void setResultAndFinish() { - runOnUiThread(new Runnable() { - public void run() { + @Override + public void eventOccurred(Event e) { + super.eventOccurred(e); + if (e instanceof PasswordValidateEvent) { + boolean validated = ((PasswordValidateEvent)e).passwordValidated(); + if (validated) { setResult(RESULT_OK); finish(); } - }); + else { + tryAgain(); + } + } } + + private void tryAgain() { + AndroidUtils.setError(input, getString(R.string.try_again), + true); + signInButton.setVisibility(VISIBLE); + progress.setVisibility(INVISIBLE); + password.setText(""); + + // show the keyboard again + showSoftKeyboard(password); + } + } diff --git a/briar-android/src/org/briarproject/android/SetupActivity.java b/briar-android/src/org/briarproject/android/SetupActivity.java index 1ddb6dd58e..8305e09d70 100644 --- a/briar-android/src/org/briarproject/android/SetupActivity.java +++ b/briar-android/src/org/briarproject/android/SetupActivity.java @@ -15,6 +15,7 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import org.briarproject.R; +import org.briarproject.android.helper.SetupHelper; import org.briarproject.android.util.AndroidUtils; import org.briarproject.android.util.StrengthMeter; import org.briarproject.android.api.ReferenceManager; @@ -45,17 +46,8 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENG public class SetupActivity extends BaseActivity implements OnClickListener, OnEditorActionListener { - private static final Logger LOG = - Logger.getLogger(SetupActivity.class.getName()); - - @Inject @CryptoExecutor protected Executor cryptoExecutor; - @Inject protected PasswordStrengthEstimator strengthEstimator; - - // Fields that are accessed from background threads must be volatile - @Inject protected volatile CryptoComponent crypto; - @Inject protected volatile DatabaseConfig databaseConfig; - @Inject protected volatile AuthorFactory authorFactory; - @Inject protected volatile ReferenceManager referenceManager; + @Inject + SetupHelper setupHelper; TextInputLayout nicknameEntryWrapper; TextInputLayout passwordEntryWrapper; @@ -123,7 +115,8 @@ public class SetupActivity extends BaseActivity implements OnClickListener, String firstPassword = passwordEntry.getText().toString(); String secondPassword = passwordConfirmation.getText().toString(); boolean passwordsMatch = firstPassword.equals(secondPassword); - float strength = strengthEstimator.estimateStrength(firstPassword); +// float strength = strengthEstimator.estimateStrength(firstPassword); + float strength = setupHelper.estimatePasswordStrength(firstPassword); strengthMeter.setStrength(strength); AndroidUtils.setError(nicknameEntryWrapper, getString(R.string.name_too_long), @@ -150,41 +143,22 @@ public class SetupActivity extends BaseActivity implements OnClickListener, progress.setVisibility(VISIBLE); final String nickname = nicknameEntry.getText().toString(); final String password = passwordEntry.getText().toString(); - // Store the DB key and create the identity in a background thread - cryptoExecutor.execute(new Runnable() { - public void run() { - SecretKey key = crypto.generateSecretKey(); - databaseConfig.setEncryptionKey(key); - String hex = encryptDatabaseKey(key, password); - storeEncryptedDatabaseKey(hex); - LocalAuthor localAuthor = createLocalAuthor(nickname); - showDashboard(referenceManager.putReference(localAuthor, - LocalAuthor.class)); - } - }); + setupHelper.createIdentity(nickname, password); +// // Store the DB key and create the identity in a background thread +// cryptoExecutor.execute(new Runnable() { +// public void run() { +// SecretKey key = crypto.generateSecretKey(); +// databaseConfig.setEncryptionKey(key); +// String hex = encryptDatabaseKey(key, password); +// storeEncryptedDatabaseKey(hex); +// LocalAuthor localAuthor = createLocalAuthor(nickname); +// showDashboard(referenceManager.putReference(localAuthor, +// LocalAuthor.class)); +// } +// }); } - private String encryptDatabaseKey(SecretKey key, String password) { - long now = System.currentTimeMillis(); - byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Key derivation took " + duration + " ms"); - return StringUtils.toHexString(encrypted); - } - private LocalAuthor createLocalAuthor(String nickname) { - long now = System.currentTimeMillis(); - KeyPair keyPair = crypto.generateSignatureKeyPair(); - byte[] publicKey = keyPair.getPublic().getEncoded(); - byte[] privateKey = keyPair.getPrivate().getEncoded(); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname, - publicKey, privateKey); - long duration = System.currentTimeMillis() - now; - if (LOG.isLoggable(INFO)) - LOG.info("Identity creation took " + duration + " ms"); - return localAuthor; - } private void showDashboard(final long handle) { runOnUiThread(new Runnable() { diff --git a/briar-android/src/org/briarproject/android/SplashScreenActivity.java b/briar-android/src/org/briarproject/android/SplashScreenActivity.java index 9a736d9163..0439159703 100644 --- a/briar-android/src/org/briarproject/android/SplashScreenActivity.java +++ b/briar-android/src/org/briarproject/android/SplashScreenActivity.java @@ -9,9 +9,8 @@ import android.os.StrictMode.VmPolicy; import android.support.v7.preference.PreferenceManager; import org.briarproject.R; -import org.briarproject.android.api.AndroidExecutor; +import org.briarproject.android.helper.ConfigHelper; import org.briarproject.android.util.AndroidUtils; -import org.briarproject.api.db.DatabaseConfig; import java.util.logging.Logger; @@ -29,9 +28,7 @@ public class SplashScreenActivity extends BaseActivity { private static final long EXPIRY_DATE = 1464735600 * 1000L; @Inject - protected DatabaseConfig dbConfig; - @Inject - protected AndroidExecutor androidExecutor; + ConfigHelper configHelper; public SplashScreenActivity() { Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL); @@ -65,11 +62,10 @@ public class SplashScreenActivity extends BaseActivity { LOG.info("Expired"); startActivity(new Intent(this, ExpiredActivity.class)); } else { - String hex = getEncryptedDatabaseKey(); - if (hex != null && dbConfig.databaseExists()) { + if (configHelper.initialized()) { startActivity(new Intent(this, NavDrawerActivity.class)); } else { - clearSharedPrefs(); + configHelper.clearPrefs(); AndroidUtils.deleteAppData(this); startActivity(new Intent(this, SetupActivity.class)); } diff --git a/briar-android/src/org/briarproject/android/event/AppBus.java b/briar-android/src/org/briarproject/android/event/AppBus.java new file mode 100644 index 0000000000..08008e28ee --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/AppBus.java @@ -0,0 +1,6 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.EventBus; + +public interface AppBus extends EventBus{ +} diff --git a/briar-android/src/org/briarproject/android/event/AppBusImp.java b/briar-android/src/org/briarproject/android/event/AppBusImp.java new file mode 100644 index 0000000000..f193e13101 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/AppBusImp.java @@ -0,0 +1,25 @@ +package org.briarproject.android.event; + + +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; + +import java.util.Collection; +import java.util.concurrent.CopyOnWriteArrayList; + +public class AppBusImp implements AppBus { + private final Collection<EventListener> listeners = + new CopyOnWriteArrayList<EventListener>(); + + public void addListener(EventListener l) { + listeners.add(l); + } + + public void removeListener(EventListener l) { + listeners.remove(l); + } + + public void broadcast(Event e) { + for (EventListener l : listeners) l.eventOccurred(e); + } +} diff --git a/briar-android/src/org/briarproject/android/event/ErrorEvent.java b/briar-android/src/org/briarproject/android/event/ErrorEvent.java new file mode 100644 index 0000000000..f326fd575d --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/ErrorEvent.java @@ -0,0 +1,10 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.Event; + +public class ErrorEvent extends Event { + + public ErrorEvent() { + + } +} diff --git a/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java b/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java new file mode 100644 index 0000000000..6a9b2e2560 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/LocalAuthorCreatedEvent.java @@ -0,0 +1,16 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.Event; + +public class LocalAuthorCreatedEvent extends Event { + + private final long handle; + + public LocalAuthorCreatedEvent(long handle) { + this.handle = handle; + } + + public long getAuthorHandle() { + return handle; + } +} diff --git a/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java b/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java new file mode 100644 index 0000000000..35a3552821 --- /dev/null +++ b/briar-android/src/org/briarproject/android/event/PasswordValidateEvent.java @@ -0,0 +1,16 @@ +package org.briarproject.android.event; + +import org.briarproject.api.event.Event; + +public class PasswordValidateEvent extends Event { + + private final boolean passwordValidated; + + public PasswordValidateEvent(boolean passwordValidated) { + this.passwordValidated = passwordValidated; + } + + public boolean passwordValidated() { + return passwordValidated; + } +} diff --git a/briar-android/src/org/briarproject/android/helper/ConfigHelper.java b/briar-android/src/org/briarproject/android/helper/ConfigHelper.java new file mode 100644 index 0000000000..0fe70579da --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/ConfigHelper.java @@ -0,0 +1,9 @@ +package org.briarproject.android.helper; + +public interface ConfigHelper { + String getEncryptedDatabaseKey(); + + void clearPrefs(); + + boolean initialized(); +} diff --git a/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java b/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java new file mode 100644 index 0000000000..ca818148a0 --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/ConfigHelperImp.java @@ -0,0 +1,41 @@ +package org.briarproject.android.helper; + +import android.content.SharedPreferences; + +import org.briarproject.api.db.DatabaseConfig; + +import javax.inject.Inject; + +public class ConfigHelperImp implements ConfigHelper { + + private final static String PREF_DB_KEY = "key"; + + @Inject + protected SharedPreferences briarPrefs; + @Inject + protected volatile DatabaseConfig databaseConfig; + + @Inject + public ConfigHelperImp() { + + } + + public String getEncryptedDatabaseKey() { + return briarPrefs.getString(PREF_DB_KEY, null); + } + + public void clearPrefs() { + SharedPreferences.Editor editor = briarPrefs.edit(); + editor.clear(); + editor.apply(); + } + + @Override + public boolean initialized() { + String hex = getEncryptedDatabaseKey(); + if (hex != null && databaseConfig.databaseExists()) { + return true; + } + return false; + } +} diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelper.java b/briar-android/src/org/briarproject/android/helper/PasswordHelper.java new file mode 100644 index 0000000000..00aeb3da6d --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/PasswordHelper.java @@ -0,0 +1,5 @@ +package org.briarproject.android.helper; + +public interface PasswordHelper extends ConfigHelper { + void validatePassword(String password); +} diff --git a/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java b/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java new file mode 100644 index 0000000000..95481bd4a0 --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/PasswordHelperImp.java @@ -0,0 +1,70 @@ +package org.briarproject.android.helper; + +import android.app.Activity; + +import org.briarproject.android.event.AppBus; +import org.briarproject.android.event.ErrorEvent; +import org.briarproject.android.event.PasswordValidateEvent; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.CryptoExecutor; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.util.StringUtils; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +public class PasswordHelperImp extends ConfigHelperImp + implements PasswordHelper { + + @Inject + @CryptoExecutor + protected Executor cryptoExecutor; + @Inject + protected CryptoComponent crypto; + @Inject + protected Activity activity; + @Inject + protected AppBus appBus; + + @Inject + public PasswordHelperImp() { + + } + + @Override + public void validatePassword(final String password) { + final byte[] encrypted = getEncryptedKey(); + if (encrypted == null) { + appBus.broadcast(new ErrorEvent()); + } + cryptoExecutor.execute(new Runnable() { + public void run() { + byte[] key = crypto.decryptWithPassword(encrypted, password); + if (key == null) { +// tryAgain();. + onPasswordValidated(false); + } else { + databaseConfig.setEncryptionKey(new SecretKey(key)); + onPasswordValidated(true); +// setResultAndFinish(); + } + } + }); + } + + private void onPasswordValidated(final boolean validated) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + appBus.broadcast(new PasswordValidateEvent(validated)); + } + }); + } + + + private byte[] getEncryptedKey() { + String hex = getEncryptedDatabaseKey(); + return hex == null? null : StringUtils.fromHexString(hex); + } +} diff --git a/briar-android/src/org/briarproject/android/helper/SetupHelper.java b/briar-android/src/org/briarproject/android/helper/SetupHelper.java new file mode 100644 index 0000000000..329b8b2106 --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/SetupHelper.java @@ -0,0 +1,6 @@ +package org.briarproject.android.helper; + +public interface SetupHelper { + float estimatePasswordStrength(String password); + void createIdentity(String nickname, String password); +} diff --git a/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java b/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java new file mode 100644 index 0000000000..9015c482f5 --- /dev/null +++ b/briar-android/src/org/briarproject/android/helper/SetupHelperImp.java @@ -0,0 +1,119 @@ +package org.briarproject.android.helper; + +import android.app.Activity; +import android.content.SharedPreferences; + +import org.briarproject.android.api.ReferenceManager; +import org.briarproject.android.event.AppBus; +import org.briarproject.android.event.LocalAuthorCreatedEvent; +import org.briarproject.api.crypto.CryptoComponent; +import org.briarproject.api.crypto.CryptoExecutor; +import org.briarproject.api.crypto.KeyPair; +import org.briarproject.api.crypto.PasswordStrengthEstimator; +import org.briarproject.api.crypto.SecretKey; +import org.briarproject.api.db.DatabaseConfig; +import org.briarproject.api.identity.AuthorFactory; +import org.briarproject.api.identity.LocalAuthor; +import org.briarproject.util.StringUtils; + +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import static java.util.logging.Level.INFO; + +public class SetupHelperImp implements SetupHelper { + + private static final Logger LOG = + Logger.getLogger(SetupHelperImp.class.getName()); + + private final static String PREF_DB_KEY = "key"; + + @Inject + @CryptoExecutor + protected Executor cryptoExecutor; + @Inject + protected PasswordStrengthEstimator strengthEstimator; + + // Fields that are accessed from background threads must be volatile + @Inject + protected volatile CryptoComponent crypto; + @Inject + protected volatile DatabaseConfig databaseConfig; + @Inject + protected volatile AuthorFactory authorFactory; + @Inject + protected volatile ReferenceManager referenceManager; + + @Inject + protected Activity activity; + @Inject + protected SharedPreferences briarPrefs; + @Inject + protected AppBus appBus; + + @Inject + public SetupHelperImp() { + + } + + private String encryptDatabaseKey(SecretKey key, String password) { + long now = System.currentTimeMillis(); + byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password); + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Key derivation took " + duration + " ms"); + return StringUtils.toHexString(encrypted); + } + + private LocalAuthor createLocalAuthor(String nickname) { + long now = System.currentTimeMillis(); + KeyPair keyPair = crypto.generateSignatureKeyPair(); + byte[] publicKey = keyPair.getPublic().getEncoded(); + byte[] privateKey = keyPair.getPrivate().getEncoded(); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname, + publicKey, privateKey); + long duration = System.currentTimeMillis() - now; + if (LOG.isLoggable(INFO)) + LOG.info("Identity creation took " + duration + " ms"); + return localAuthor; + } + + @Override + public float estimatePasswordStrength(String password) { + return strengthEstimator.estimateStrength(password); + } + + @Override + public void createIdentity(final String nickname, final String password) { + cryptoExecutor.execute(new Runnable() { + public void run() { + SecretKey key = crypto.generateSecretKey(); + databaseConfig.setEncryptionKey(key); + String hex = encryptDatabaseKey(key, password); + storeEncryptedDatabaseKey(hex); + final LocalAuthor localAuthor = createLocalAuthor(nickname); + onIdentityCreated(referenceManager.putReference(localAuthor, + LocalAuthor.class)); + + } + }); + } + + private void onIdentityCreated(final long handle) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + appBus.broadcast(new LocalAuthorCreatedEvent(handle)); + } + }); + } + + private void storeEncryptedDatabaseKey(final String hex) { + SharedPreferences.Editor editor = briarPrefs.edit(); + editor.putString(PREF_DB_KEY, hex); + editor.apply(); + } + +} diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java index c57e44d03b..03198cf482 100644 --- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java +++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java @@ -10,7 +10,7 @@ import android.support.v7.preference.PreferenceManager; import org.briarproject.android.ActivityComponent; import org.briarproject.android.AndroidComponent; import org.briarproject.android.BriarActivity; -import org.briarproject.android.api.AndroidExecutor; +import org.briarproject.android.helper.ConfigHelper; import org.briarproject.android.util.AndroidUtils; import org.briarproject.api.db.DatabaseConfig; import org.iilab.IilabEngineeringRSA2048Pin; @@ -24,7 +24,6 @@ import info.guardianproject.panic.Panic; import info.guardianproject.panic.PanicResponder; import info.guardianproject.trustedintents.TrustedIntents; -import static android.content.Intent.ACTION_DELETE; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_LOCK; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_PURGE; import static org.briarproject.android.panic.PanicPreferencesFragment.KEY_UNINSTALL; @@ -33,11 +32,7 @@ public class PanicResponderActivity extends BriarActivity { private static final Logger LOG = Logger.getLogger(PanicResponderActivity.class.getName()); - - @Inject - protected DatabaseConfig databaseConfig; - @Inject - protected AndroidExecutor androidExecutor; + @Inject protected ConfigHelper configHelper; @Override public void onCreate(Bundle savedInstanceState) { @@ -113,7 +108,7 @@ public class PanicResponderActivity extends BriarActivity { private void deleteAllData() { androidExecutor.execute(new Runnable() { public void run() { - clearSharedPrefs(); + configHelper.clearPrefs(); // TODO somehow delete/shred the database more thoroughly AndroidUtils.deleteAppData(PanicResponderActivity.this); PanicResponder.deleteAllAppData(PanicResponderActivity.this); diff --git a/briar-android/src/org/briarproject/android/sdk/BriarHelper.java b/briar-android/src/org/briarproject/android/sdk/BriarHelper.java deleted file mode 100644 index 1cb8993ae8..0000000000 --- a/briar-android/src/org/briarproject/android/sdk/BriarHelper.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.briarproject.android.sdk; - -public interface BriarHelper { -} diff --git a/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java b/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java deleted file mode 100644 index c83c33ac83..0000000000 --- a/briar-android/src/org/briarproject/android/sdk/BriarHelperImp.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.briarproject.android.sdk; - -import javax.inject.Inject; - -public class BriarHelperImp implements BriarHelper { - - - - @Inject - public BriarHelperImp() { - - } -} -- GitLab