Move DB key management into account manager.

This commit is contained in:
akwizgran
2018-07-27 11:35:27 +01:00
parent 4a9977fa58
commit 6ca0339da2
13 changed files with 123 additions and 166 deletions

View File

@@ -11,7 +11,7 @@ public interface PasswordController {
void validatePassword(String password,
ResultHandler<Boolean> resultHandler);
void changePassword(String password, String newPassword,
void changePassword(String oldPassword, String newPassword,
ResultHandler<Boolean> resultHandler);
}

View File

@@ -1,40 +1,28 @@
package org.briarproject.briar.android.login;
import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.android.controller.handler.ResultHandler;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
public class PasswordControllerImpl implements PasswordController {
private static final Logger LOG =
Logger.getLogger(PasswordControllerImpl.class.getName());
protected final AccountManager accountManager;
protected final Executor cryptoExecutor;
protected final CryptoComponent crypto;
protected final Executor ioExecutor;
private final PasswordStrengthEstimator strengthEstimator;
@Inject
PasswordControllerImpl(AccountManager accountManager,
@CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto,
@IoExecutor Executor ioExecutor,
PasswordStrengthEstimator strengthEstimator) {
this.accountManager = accountManager;
this.cryptoExecutor = cryptoExecutor;
this.crypto = crypto;
this.ioExecutor = ioExecutor;
this.strengthEstimator = strengthEstimator;
}
@@ -46,47 +34,17 @@ public class PasswordControllerImpl implements PasswordController {
@Override
public void validatePassword(String password,
ResultHandler<Boolean> resultHandler) {
byte[] encrypted = getEncryptedKey();
cryptoExecutor.execute(() -> {
byte[] key = crypto.decryptWithPassword(encrypted, password);
if (key == null) {
resultHandler.onResult(false);
} else {
accountManager.setDatabaseKey(new SecretKey(key));
resultHandler.onResult(true);
}
});
ioExecutor.execute(() ->
resultHandler.onResult(accountManager.signIn(password)));
}
@Override
public void changePassword(String password, String newPassword,
public void changePassword(String oldPassword, String newPassword,
ResultHandler<Boolean> resultHandler) {
byte[] encrypted = getEncryptedKey();
cryptoExecutor.execute(() -> {
byte[] key = crypto.decryptWithPassword(encrypted, password);
if (key == null) {
resultHandler.onResult(false);
} else {
String hex =
encryptDatabaseKey(new SecretKey(key), newPassword);
boolean stored = accountManager.storeEncryptedDatabaseKey(hex);
resultHandler.onResult(stored);
}
ioExecutor.execute(() -> {
boolean changed =
accountManager.changePassword(oldPassword, newPassword);
resultHandler.onResult(changed);
});
}
private byte[] getEncryptedKey() {
String hex = accountManager.getEncryptedDatabaseKey();
if (hex == null)
throw new IllegalStateException("Encrypted database key is null");
return StringUtils.fromHexString(hex);
}
@CryptoExecutor
String encryptDatabaseKey(SecretKey key, String password) {
long start = now();
byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password);
logDuration(LOG, "Key derivation", start);
return StringUtils.toHexString(encrypted);
}
}

View File

@@ -3,12 +3,10 @@ package org.briarproject.briar.android.login;
import android.support.annotation.Nullable;
import org.briarproject.bramble.api.account.AccountManager;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.android.controller.handler.ResultHandler;
import org.briarproject.briar.android.controller.handler.UiResultHandler;
@@ -32,10 +30,10 @@ public class SetupControllerImpl extends PasswordControllerImpl
@Inject
SetupControllerImpl(AccountManager accountManager,
@CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto,
@IoExecutor Executor ioExecutor,
PasswordStrengthEstimator strengthEstimator,
IdentityManager identityManager) {
super(accountManager, cryptoExecutor, crypto, strengthEstimator);
super(accountManager, ioExecutor, strengthEstimator);
this.identityManager = identityManager;
}
@@ -83,10 +81,10 @@ public class SetupControllerImpl extends PasswordControllerImpl
@Override
public void createAccount() {
SetupActivity setupActivity = this.setupActivity;
UiResultHandler<Void> resultHandler =
new UiResultHandler<Void>(setupActivity) {
UiResultHandler<Boolean> resultHandler =
new UiResultHandler<Boolean>(setupActivity) {
@Override
public void onResultUi(Void result) {
public void onResultUi(Boolean result) {
if (setupActivity == null)
throw new IllegalStateException();
setupActivity.showApp();
@@ -96,23 +94,19 @@ public class SetupControllerImpl extends PasswordControllerImpl
}
// Package access for testing
void createAccount(ResultHandler<Void> resultHandler) {
void createAccount(ResultHandler<Boolean> resultHandler) {
SetupActivity setupActivity = this.setupActivity;
if (setupActivity == null) throw new IllegalStateException();
String authorName = setupActivity.getAuthorName();
if (authorName == null) throw new IllegalStateException();
String password = setupActivity.getPassword();
if (password == null) throw new IllegalStateException();
cryptoExecutor.execute(() -> {
ioExecutor.execute(() -> {
LOG.info("Creating account");
LocalAuthor localAuthor =
identityManager.createLocalAuthor(authorName);
identityManager.registerLocalAuthor(localAuthor);
SecretKey key = crypto.generateSecretKey();
String hex = encryptDatabaseKey(key, password);
accountManager.storeEncryptedDatabaseKey(hex);
accountManager.setDatabaseKey(key);
resultHandler.onResult(null);
resultHandler.onResult(accountManager.createAccount(password));
});
}
}