mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
phase 2: helpers and app bus
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,28 +43,28 @@ public abstract class BaseActivity extends AppCompatActivity {
|
||||
injectActivity(activityComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
appBus.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
appBus.removeListener(this);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ErrorEvent) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void injectActivity(ActivityComponent component);
|
||||
|
||||
private SharedPreferences getSharedPrefs() {
|
||||
return getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||
}
|
||||
|
||||
protected String getEncryptedDatabaseKey() {
|
||||
return getSharedPrefs().getString(PREF_DB_KEY, null);
|
||||
}
|
||||
|
||||
protected void storeEncryptedDatabaseKey(final String hex) {
|
||||
SharedPreferences.Editor editor = getSharedPrefs().edit();
|
||||
editor.putString(PREF_DB_KEY, hex);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
protected void clearSharedPrefs() {
|
||||
SharedPreferences.Editor editor = getSharedPrefs().edit();
|
||||
editor.clear();
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
protected void showSoftKeyboard(View view) {
|
||||
Object o = getSystemService(INPUT_METHOD_SERVICE);
|
||||
((InputMethodManager) o).showSoftInput(view, SHOW_IMPLICIT);
|
||||
@@ -74,4 +75,5 @@ public abstract class BaseActivity extends AppCompatActivity {
|
||||
Object o = getSystemService(INPUT_METHOD_SERVICE);
|
||||
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
passwordHelper.validatePassword(password.getText().toString());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.briarproject.android.event;
|
||||
|
||||
import org.briarproject.api.event.EventBus;
|
||||
|
||||
public interface AppBus extends EventBus{
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.briarproject.android.event;
|
||||
|
||||
import org.briarproject.api.event.Event;
|
||||
|
||||
public class ErrorEvent extends Event {
|
||||
|
||||
public ErrorEvent() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.android.helper;
|
||||
|
||||
public interface ConfigHelper {
|
||||
String getEncryptedDatabaseKey();
|
||||
|
||||
void clearPrefs();
|
||||
|
||||
boolean initialized();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.briarproject.android.helper;
|
||||
|
||||
public interface PasswordHelper extends ConfigHelper {
|
||||
void validatePassword(String password);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.briarproject.android.helper;
|
||||
|
||||
public interface SetupHelper {
|
||||
float estimatePasswordStrength(String password);
|
||||
void createIdentity(String nickname, String password);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package org.briarproject.android.sdk;
|
||||
|
||||
public interface BriarHelper {
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.briarproject.android.sdk;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BriarHelperImp implements BriarHelper {
|
||||
|
||||
|
||||
|
||||
@Inject
|
||||
public BriarHelperImp() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user