Move encrypted key, account deletion into AccountManager.

This commit is contained in:
akwizgran
2018-07-23 10:18:38 +01:00
parent cb29c9bf32
commit f9495b49d6
34 changed files with 418 additions and 462 deletions

View File

@@ -0,0 +1,158 @@
package org.briarproject.bramble.account;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.jmock.Expectations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.annotation.Nullable;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.briarproject.bramble.util.StringUtils.toHexString;
import static org.junit.Assert.assertEquals;
public class AccountManagerImplTest extends BrambleMockTestCase {
private final DatabaseConfig databaseConfig =
context.mock(DatabaseConfig.class);
private final byte[] encryptedKey = getRandomBytes(123);
private final String encryptedKeyHex = toHexString(encryptedKey);
private final String oldEncryptedKeyHex = toHexString(getRandomBytes(123));
private final File testDir = getTestDirectory();
private final File keyDir = new File(testDir, "key");
private final File keyFile = new File(keyDir, "db.key");
private final File keyBackupFile = new File(keyDir, "db.key.bak");
private AccountManagerImpl accountManager;
@Before
public void setUp() {
context.checking(new Expectations() {{
allowing(databaseConfig).getDatabaseKeyDirectory();
will(returnValue(keyDir));
}});
accountManager = new AccountManagerImpl(databaseConfig);
}
@Test
public void testDbKeyIsLoadedFromPrimaryFile() throws Exception {
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
storeDatabaseKey(keyFile, encryptedKeyHex);
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
assertEquals(encryptedKeyHex, accountManager.getEncryptedDatabaseKey());
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
}
@Test
public void testDbKeyIsLoadedFromBackupFile() throws Exception {
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
storeDatabaseKey(keyBackupFile, encryptedKeyHex);
assertFalse(keyFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
assertEquals(encryptedKeyHex, accountManager.getEncryptedDatabaseKey());
assertFalse(keyFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
}
@Test
public void testDbKeyIsNullIfNotFound() {
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertNull(accountManager.getEncryptedDatabaseKey());
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
}
@Test
public void testStoringDbKeyOverwritesPrimary() throws Exception {
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
storeDatabaseKey(keyFile, oldEncryptedKeyHex);
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertEquals(oldEncryptedKeyHex, loadDatabaseKey(keyFile));
assertTrue(accountManager.storeEncryptedDatabaseKey(encryptedKeyHex));
assertTrue(keyFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
}
@Test
public void testStoringDbKeyOverwritesBackup() throws Exception {
assertFalse(keyFile.exists());
assertFalse(keyBackupFile.exists());
storeDatabaseKey(keyBackupFile, oldEncryptedKeyHex);
assertFalse(keyFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(oldEncryptedKeyHex, loadDatabaseKey(keyBackupFile));
assertTrue(accountManager.storeEncryptedDatabaseKey(encryptedKeyHex));
assertTrue(keyFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
}
@After
public void tearDown() {
deleteTestDirectory(testDir);
}
private void storeDatabaseKey(File f, String hex) throws IOException {
f.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(f);
out.write(hex.getBytes("UTF-8"));
out.flush();
out.close();
}
@Nullable
private String loadDatabaseKey(File f) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(f), "UTF-8"));
String hex = reader.readLine();
reader.close();
return hex;
}
}

View File

@@ -89,6 +89,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
context.mock(ShutdownManager.class);
private final EventBus eventBus = context.mock(EventBus.class);
private final SecretKey key = getSecretKey();
private final Object txn = new Object();
private final ClientId clientId;
private final int majorVersion;
@@ -141,7 +142,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
int shutdownHandle = 12345;
context.checking(new Expectations() {{
// open()
oneOf(database).open(null);
oneOf(database).open(key, null);
will(returnValue(false));
oneOf(shutdown).addShutdownHook(with(any(Runnable.class)));
will(returnValue(shutdownHandle));
@@ -208,7 +209,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
assertFalse(db.open(null));
assertFalse(db.open(key, null));
Transaction transaction = db.startTransaction(false);
try {
db.addLocalAuthor(transaction, localAuthor);
@@ -1602,7 +1603,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
MessageId messageId2 = new MessageId(getRandomId());
context.checking(new Expectations() {{
// open()
oneOf(database).open(null);
oneOf(database).open(key, null);
will(returnValue(false));
oneOf(shutdown).addShutdownHook(with(any(Runnable.class)));
will(returnValue(shutdownHandle));
@@ -1646,7 +1647,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
assertFalse(db.open(null));
assertFalse(db.open(key, null));
Transaction transaction = db.startTransaction(false);
try {
db.addLocalMessage(transaction, message, metadata, true);

View File

@@ -1,5 +1,6 @@
package org.briarproject.bramble.db;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DataTooNewException;
import org.briarproject.bramble.api.db.DataTooOldException;
import org.briarproject.bramble.api.db.DatabaseConfig;
@@ -26,6 +27,7 @@ import static java.util.Collections.singletonList;
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
import static org.briarproject.bramble.db.JdbcDatabase.CODE_SCHEMA_VERSION;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -43,6 +45,7 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
protected final DatabaseConfig config =
new TestDatabaseConfig(testDir, 1024 * 1024);
protected final SecretKey key = getSecretKey();
protected final Clock clock = new SystemClock();
abstract Database<Connection> createDatabase(
@@ -62,7 +65,7 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
public void testDoesNotRunMigrationsWhenCreatingDatabase()
throws Exception {
Database<Connection> db = createDatabase(singletonList(migration));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
db.close();
}
@@ -72,14 +75,14 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
throws Exception {
// Open the DB for the first time
Database<Connection> db = createDatabase(asList(migration, migration1));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
// Override the data schema version
setDataSchemaVersion(db, -1);
db.close();
// Reopen the DB - an exception should be thrown
db = createDatabase(asList(migration, migration1));
db.open(null);
db.open(key, null);
}
@Test
@@ -87,12 +90,12 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
throws Exception {
// Open the DB for the first time
Database<Connection> db = createDatabase(asList(migration, migration1));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
db.close();
// Reopen the DB - migrations should not be run
db = createDatabase(asList(migration, migration1));
assertTrue(db.open(null));
assertTrue(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
db.close();
}
@@ -101,14 +104,14 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
public void testThrowsExceptionIfDataIsNewerThanCode() throws Exception {
// Open the DB for the first time
Database<Connection> db = createDatabase(asList(migration, migration1));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
// Override the data schema version
setDataSchemaVersion(db, CODE_SCHEMA_VERSION + 1);
db.close();
// Reopen the DB - an exception should be thrown
db = createDatabase(asList(migration, migration1));
db.open(null);
db.open(key, null);
}
@Test(expected = DataTooOldException.class)
@@ -116,13 +119,13 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
throws Exception {
// Open the DB for the first time
Database<Connection> db = createDatabase(emptyList());
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
setDataSchemaVersion(db, CODE_SCHEMA_VERSION - 1);
db.close();
// Reopen the DB - an exception should be thrown
db = createDatabase(emptyList());
db.open(null);
db.open(key, null);
}
@Test(expected = DataTooOldException.class)
@@ -141,14 +144,14 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
// Open the DB for the first time
Database<Connection> db = createDatabase(asList(migration, migration1));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
// Override the data schema version
setDataSchemaVersion(db, CODE_SCHEMA_VERSION - 3);
db.close();
// Reopen the DB - an exception should be thrown
db = createDatabase(asList(migration, migration1));
db.open(null);
db.open(key, null);
}
@Test
@@ -170,14 +173,14 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
// Open the DB for the first time
Database<Connection> db = createDatabase(asList(migration, migration1));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
// Override the data schema version
setDataSchemaVersion(db, CODE_SCHEMA_VERSION - 2);
db.close();
// Reopen the DB - the first migration should be run
db = createDatabase(asList(migration, migration1));
assertTrue(db.open(null));
assertTrue(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
db.close();
}
@@ -202,14 +205,14 @@ public abstract class DatabaseMigrationTest extends BrambleMockTestCase {
// Open the DB for the first time
Database<Connection> db = createDatabase(asList(migration, migration1));
assertFalse(db.open(null));
assertFalse(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
// Override the data schema version
setDataSchemaVersion(db, CODE_SCHEMA_VERSION - 2);
db.close();
// Reopen the DB - both migrations should be run
db = createDatabase(asList(migration, migration1));
assertTrue(db.open(null));
assertTrue(db.open(key, null));
assertEquals(CODE_SCHEMA_VERSION, getDataSchemaVersion(db));
db.close();
}

View File

@@ -15,6 +15,7 @@ import java.util.List;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getMean;
import static org.briarproject.bramble.test.TestUtils.getMedian;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getStandardDeviation;
import static org.briarproject.bramble.test.UTest.Z_CRITICAL_0_01;
@@ -71,7 +72,7 @@ public abstract class DatabasePerformanceComparisonTest
throws DbException {
Database<Connection> db = createDatabase(conditionA,
new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock());
db.open(null);
db.open(getSecretKey(), null);
return db;
}

View File

@@ -16,6 +16,7 @@ import java.sql.Connection;
import javax.annotation.Nullable;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
public abstract class DatabaseTraceTest extends DatabasePerformanceTest {
@@ -43,7 +44,7 @@ public abstract class DatabaseTraceTest extends DatabasePerformanceTest {
private Database<Connection> openDatabase() throws DbException {
Database<Connection> db = createDatabase(
new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock());
db.open(null);
db.open(getSecretKey(), null);
return db;
}

View File

@@ -9,8 +9,8 @@ import java.util.List;
public class H2MigrationTest extends DatabaseMigrationTest {
@Override
Database<Connection> createDatabase(List<Migration<Connection>> migrations)
throws Exception {
Database<Connection> createDatabase(
List<Migration<Connection>> migrations) {
return new H2Database(config, clock) {
@Override
List<Migration<Connection>> getMigrations() {

View File

@@ -64,6 +64,7 @@ import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getTransportId;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -79,7 +80,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
private static final int ONE_MEGABYTE = 1024 * 1024;
private static final int MAX_SIZE = 5 * ONE_MEGABYTE;
private final File testDir = TestUtils.getTestDirectory();
private final SecretKey key = getSecretKey();
private final File testDir = getTestDirectory();
private final GroupId groupId;
private final ClientId clientId;
private final int majorVersion;
@@ -96,7 +98,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
private final KeySetId keySetId, keySetId1;
private final Random random = new Random();
JdbcDatabaseTest() throws Exception {
JdbcDatabaseTest() {
clientId = getClientId();
majorVersion = 123;
group = getGroup(clientId, majorVersion);
@@ -1819,7 +1821,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Database<Connection> db = createDatabase(
new TestDatabaseConfig(testDir, MAX_SIZE), clock);
if (!resume) TestUtils.deleteTestDirectory(testDir);
db.open(null);
db.open(key, null);
return db;
}

View File

@@ -13,6 +13,7 @@ import java.util.List;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getMean;
import static org.briarproject.bramble.test.TestUtils.getMedian;
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.test.TestUtils.getStandardDeviation;
public abstract class SingleDatabasePerformanceTest
@@ -40,7 +41,7 @@ public abstract class SingleDatabasePerformanceTest
private Database<Connection> openDatabase() throws DbException {
Database<Connection> db = createDatabase(
new TestDatabaseConfig(testDir, MAX_SIZE), new SystemClock());
db.open(null);
db.open(getSecretKey(), null);
return db;
}

View File

@@ -1,6 +1,5 @@
package org.briarproject.bramble.test;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -11,7 +10,6 @@ public class TestDatabaseConfig implements DatabaseConfig {
private final File dbDir, keyDir;
private final long maxSize;
private volatile SecretKey key = new SecretKey(new byte[SecretKey.LENGTH]);
public TestDatabaseConfig(File testDir, long maxSize) {
dbDir = new File(testDir, "db");
@@ -36,16 +34,6 @@ public class TestDatabaseConfig implements DatabaseConfig {
return keyDir;
}
@Override
public void setEncryptionKey(SecretKey key) {
this.key = key;
}
@Override
public SecretKey getEncryptionKey() {
return key;
}
@Override
public long getMaxSize() {
return maxSize;