Commit b9e60774 authored by akwizgran's avatar akwizgran

Store second copy of DB key in backup file.

parent b410b8ef
Pipeline #1583 passed with stage
in 8 minutes and 6 seconds
......@@ -33,6 +33,7 @@ public class ConfigControllerImpl implements ConfigController {
private static final String DB_KEY_BACKUP_FILENAME = "db.key.bak";
private final SharedPreferences briarPrefs;
private final File dbKeyFile, dbKeyBackupFile;
protected final DatabaseConfig databaseConfig;
@Inject
......@@ -40,6 +41,9 @@ public class ConfigControllerImpl implements ConfigController {
DatabaseConfig databaseConfig) {
this.briarPrefs = briarPrefs;
this.databaseConfig = databaseConfig;
File keyDir = databaseConfig.getDatabaseKeyDirectory();
dbKeyFile = new File(keyDir, DB_KEY_FILENAME);
dbKeyBackupFile = new File(keyDir, DB_KEY_BACKUP_FILENAME);
}
@Override
......@@ -61,10 +65,10 @@ public class ConfigControllerImpl implements ConfigController {
@Nullable
private String getDatabaseKeyFromFile() {
String key = readDbKeyFromFile(getDbKeyFile());
String key = readDbKeyFromFile(dbKeyFile);
if (key == null) {
LOG.info("No database key in primary file");
key = readDbKeyFromFile(getDbKeyBackupFile());
key = readDbKeyFromFile(dbKeyBackupFile);
if (key == null) LOG.info("No database key in backup file");
else LOG.warning("Found database key in backup file");
} else {
......@@ -91,16 +95,6 @@ public class ConfigControllerImpl implements ConfigController {
}
}
private File getDbKeyFile() {
return new File(databaseConfig.getDatabaseKeyDirectory(),
DB_KEY_FILENAME);
}
private File getDbKeyBackupFile() {
return new File(databaseConfig.getDatabaseKeyDirectory(),
DB_KEY_BACKUP_FILENAME);
}
private void migrateDatabaseKeyToFile(String key) {
if (storeEncryptedDatabaseKey(key)) {
if (briarPrefs.edit().remove(PREF_DB_KEY).commit())
......@@ -114,39 +108,48 @@ public class ConfigControllerImpl implements ConfigController {
@Override
public boolean storeEncryptedDatabaseKey(String hex) {
LOG.info("Storing database key in file");
File dbKey = getDbKeyFile();
File dbKeyBackup = getDbKeyBackupFile();
// Create the directory if necessary
if (databaseConfig.getDatabaseKeyDirectory().mkdirs())
LOG.info("Created database key directory");
// If only the backup file exists, rename it so we don't overwrite it
if (dbKeyBackup.exists() && !dbKey.exists()) {
if (dbKeyBackup.renameTo(dbKey)) LOG.info("Renamed old backup");
if (dbKeyBackupFile.exists() && !dbKeyFile.exists()) {
if (dbKeyBackupFile.renameTo(dbKeyFile))
LOG.info("Renamed old backup");
else LOG.warning("Failed to rename old backup");
}
try {
// Write to the backup file
FileOutputStream out = new FileOutputStream(dbKeyBackup);
out.write(hex.getBytes("UTF-8"));
out.flush();
out.close();
writeDbKeyToFile(hex, dbKeyBackupFile);
LOG.info("Stored database key in backup file");
// Delete the old primary file, if it exists
if (dbKey.exists()) {
if (dbKey.delete()) LOG.info("Deleted primary file");
if (dbKeyFile.exists()) {
if (dbKeyFile.delete()) LOG.info("Deleted primary file");
else LOG.warning("Failed to delete primary file");
}
// The backup file becomes the new primary
boolean renamed = dbKeyBackup.renameTo(dbKey);
if (renamed) LOG.info("Renamed backup file to primary");
else LOG.warning("Failed to rename backup file to primary");
return renamed;
if (dbKeyBackupFile.renameTo(dbKeyFile)) {
LOG.info("Renamed backup file to primary");
} else {
LOG.warning("Failed to rename backup file to primary");
return false; // Don't overwrite our only copy
}
// Write a second copy to the backup file
writeDbKeyToFile(hex, dbKeyBackupFile);
LOG.info("Stored second copy of database key in backup file");
return true;
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return false;
}
}
private void writeDbKeyToFile(String key, File f) throws IOException {
FileOutputStream out = new FileOutputStream(f);
out.write(key.getBytes("UTF-8"));
out.flush();
out.close();
}
@Override
public void deleteAccount(Context ctx) {
LOG.info("Deleting account");
......
......@@ -72,8 +72,7 @@ public class PasswordControllerImpl extends ConfigControllerImpl
} else {
String hex =
encryptDatabaseKey(new SecretKey(key), newPassword);
boolean stored = storeEncryptedDatabaseKey(hex);
resultHandler.onResult(stored);
resultHandler.onResult(storeEncryptedDatabaseKey(hex));
}
});
}
......
......@@ -17,7 +17,7 @@ import static junit.framework.Assert.assertTrue;
public class TestDatabaseKeyUtils {
public static void storeDatabaseKey(File f, String hex) throws IOException {
assertTrue(f.getParentFile().mkdirs());
f.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(f);
out.write(hex.getBytes("UTF-8"));
out.flush();
......
......@@ -62,8 +62,9 @@ public class ConfigControllerImplTest extends BrambleMockTestCase {
assertEquals(encryptedKeyHex, c.getEncryptedDatabaseKey());
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
}
@Test
......@@ -165,8 +166,9 @@ public class ConfigControllerImplTest extends BrambleMockTestCase {
assertTrue(c.storeEncryptedDatabaseKey(encryptedKeyHex));
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
}
@Test
......@@ -191,8 +193,9 @@ public class ConfigControllerImplTest extends BrambleMockTestCase {
assertTrue(c.storeEncryptedDatabaseKey(encryptedKeyHex));
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
}
@After
......
......@@ -67,6 +67,7 @@ public class PasswordControllerImplTest extends BrambleMockTestCase {
assertFalse(keyBackupFile.exists());
storeDatabaseKey(keyFile, toHexString(oldEncryptedKey));
storeDatabaseKey(keyBackupFile, toHexString(oldEncryptedKey));
PasswordControllerImpl p = new PasswordControllerImpl(briarPrefs,
databaseConfig, cryptoExecutor, crypto, estimator);
......@@ -76,8 +77,10 @@ public class PasswordControllerImplTest extends BrambleMockTestCase {
assertTrue(capturedResult.get());
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(toHexString(newEncryptedKey), loadDatabaseKey(keyFile));
assertEquals(toHexString(newEncryptedKey),
loadDatabaseKey(keyBackupFile));
}
@Test
......@@ -98,6 +101,7 @@ public class PasswordControllerImplTest extends BrambleMockTestCase {
assertFalse(keyBackupFile.exists());
storeDatabaseKey(keyFile, toHexString(oldEncryptedKey));
storeDatabaseKey(keyBackupFile, toHexString(oldEncryptedKey));
PasswordControllerImpl p = new PasswordControllerImpl(briarPrefs,
databaseConfig, cryptoExecutor, crypto, estimator);
......@@ -107,8 +111,10 @@ public class PasswordControllerImplTest extends BrambleMockTestCase {
assertFalse(capturedResult.get());
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(toHexString(oldEncryptedKey), loadDatabaseKey(keyFile));
assertEquals(toHexString(oldEncryptedKey),
loadDatabaseKey(keyBackupFile));
}
@After
......
......@@ -102,8 +102,9 @@ public class SetupControllerImplTest extends BrambleMockTestCase {
assertTrue(called.get());
assertTrue(keyFile.exists());
assertFalse(keyBackupFile.exists());
assertTrue(keyBackupFile.exists());
assertEquals(toHexString(encryptedKey), loadDatabaseKey(keyFile));
assertEquals(toHexString(encryptedKey), loadDatabaseKey(keyBackupFile));
}
@After
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment