From afc0bc3f3c555f46a8d5ba01863999371bd62655 Mon Sep 17 00:00:00 2001 From: ameba23 Date: Wed, 21 Apr 2021 16:34:28 +0200 Subject: [PATCH] Refactor and create a RestoreAccount class which does the combining --- .../briar/api}/socialbackup/ContactData.java | 0 .../briar/api}/socialbackup/SocialBackup.java | 6 +- .../socialbackup/recovery/RestoreAccount.java | 4 + .../socialbackup/BackupPayloadDecoder.java | 1 + .../BackupPayloadDecoderImpl.java | 9 ++- .../socialbackup/BackupPayloadEncoder.java | 2 +- .../BackupPayloadEncoderImpl.java | 4 +- .../socialbackup/SocialBackupManagerImpl.java | 20 ++--- .../socialbackup/SocialBackupModule.java | 7 ++ .../recovery/RestoreAccountImpl.java | 73 +++++++++++++++++++ 10 files changed, 106 insertions(+), 20 deletions(-) rename {briar-core/src/main/java/org/briarproject/briar => briar-api/src/main/java/org/briarproject/briar/api}/socialbackup/ContactData.java (100%) rename {briar-core/src/main/java/org/briarproject/briar => briar-api/src/main/java/org/briarproject/briar/api}/socialbackup/SocialBackup.java (60%) create mode 100644 briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java create mode 100644 briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/ContactData.java b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/ContactData.java similarity index 100% rename from briar-core/src/main/java/org/briarproject/briar/socialbackup/ContactData.java rename to briar-api/src/main/java/org/briarproject/briar/api/socialbackup/ContactData.java diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackup.java b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/SocialBackup.java similarity index 60% rename from briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackup.java rename to briar-api/src/main/java/org/briarproject/briar/api/socialbackup/SocialBackup.java index 341d04816..a2173f8ef 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackup.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/SocialBackup.java @@ -6,10 +6,10 @@ import java.util.List; public class SocialBackup { private Identity identity; - private List contacts; + private List contacts; private int version; - SocialBackup (Identity identity, List contacts, int version) { + SocialBackup (Identity identity, List contacts, int version) { this.identity = identity; this.contacts = contacts; this.version = version; @@ -19,7 +19,7 @@ public class SocialBackup { return identity; } - public List getContacts() { + public List getContacts() { return contacts; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java new file mode 100644 index 000000000..32a25936a --- /dev/null +++ b/briar-api/src/main/java/org/briarproject/briar/api/socialbackup/recovery/RestoreAccount.java @@ -0,0 +1,4 @@ +package org.briarproject.briar.api.socialbackup.recovery; + +public interface RestoreAccount { +} diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoder.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoder.java index 835869dac..640aac4a9 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoder.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoder.java @@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.socialbackup.BackupPayload; +import org.briarproject.briar.api.socialbackup.SocialBackup; import java.security.GeneralSecurityException; diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoderImpl.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoderImpl.java index a2672016b..4171d8154 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadDecoderImpl.java @@ -20,6 +20,7 @@ import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.briar.api.socialbackup.BackupPayload; import org.briarproject.briar.api.socialbackup.MessageParser; import org.briarproject.briar.api.socialbackup.Shard; +import org.briarproject.briar.api.socialbackup.SocialBackup; import java.security.GeneralSecurityException; import java.security.SecureRandom; @@ -54,7 +55,7 @@ public class BackupPayloadDecoderImpl implements BackupPayloadDecoder { this.messageParser = messageParser; } - public SocialBackup decodeBackupPayload( + public org.briarproject.briar.api.socialbackup.SocialBackup decodeBackupPayload( SecretKey secret, BackupPayload backupPayload) throws FormatException, GeneralSecurityException { @@ -103,7 +104,7 @@ public class BackupPayloadDecoderImpl implements BackupPayloadDecoder { handShakePrivateKey, created); LOG.info("New identity created"); - List contactDataList = new ArrayList(); + List contactDataList = new ArrayList(); for (int i = 0; i < bdfContactData.size(); i++) { BdfList bdfData = bdfContactData.getList(i); @@ -139,8 +140,8 @@ public class BackupPayloadDecoderImpl implements BackupPayloadDecoder { Contact contact = new Contact(contactId, author, author.getId(), alias, contactHandshakePublicKey, false); - ContactData contactData = - new ContactData(contact, properties, shard); + org.briarproject.briar.api.socialbackup.ContactData contactData = + new org.briarproject.briar.api.socialbackup.ContactData(contact, properties, shard); contactDataList.add(contactData); LOG.info("Contact added"); } diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoder.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoder.java index b65f027da..7019661c9 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoder.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoder.java @@ -10,5 +10,5 @@ import java.util.List; interface BackupPayloadEncoder { org.briarproject.briar.api.socialbackup.BackupPayload encodeBackupPayload(SecretKey secret, Identity identity, - List contactData, int version); + List contactData, int version); } diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoderImpl.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoderImpl.java index f813c4efd..7e867f697 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/BackupPayloadEncoderImpl.java @@ -46,7 +46,7 @@ class BackupPayloadEncoderImpl implements BackupPayloadEncoder { @Override public org.briarproject.briar.api.socialbackup.BackupPayload encodeBackupPayload(SecretKey secret, - Identity identity, List contactData, int version) { + Identity identity, List contactData, int version) { // Encode the local identity BdfList bdfIdentity = new BdfList(); LocalAuthor localAuthor = identity.getLocalAuthor(); @@ -56,7 +56,7 @@ class BackupPayloadEncoderImpl implements BackupPayloadEncoder { bdfIdentity.add(identity.getHandshakePrivateKey().getEncoded()); // Encode the contact data BdfList bdfContactData = new BdfList(); - for (ContactData cd : contactData) { + for (org.briarproject.briar.api.socialbackup.ContactData cd : contactData) { BdfList bdfData = new BdfList(); Contact contact = cd.getContact(); bdfData.add(clientHelper.toList(contact.getAuthor())); diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java index b7a58e7d5..3ebc187f9 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupManagerImpl.java @@ -193,12 +193,12 @@ class SocialBackupManagerImpl extends ConversationClientImpl // Add the shard to our backup, if any if (localBackupExists(txn)) { Shard shard = messageParser.parseShardMessage(body); - List contactData = loadContactData(txn); - ListIterator it = contactData.listIterator(); + List contactData = loadContactData(txn); + ListIterator it = contactData.listIterator(); while (it.hasNext()) { - ContactData cd = it.next(); + org.briarproject.briar.api.socialbackup.ContactData cd = it.next(); if (cd.getContact().getId().equals(contactId)) { - it.set(new ContactData(cd.getContact(), + it.set(new org.briarproject.briar.api.socialbackup.ContactData(cd.getContact(), cd.getProperties(), shard)); updateBackup(txn, contactData); break; @@ -278,7 +278,7 @@ class SocialBackupManagerImpl extends ConversationClientImpl } // Create the encrypted backup payload SecretKey secret = crypto.generateSecretKey(); - List contactData = loadContactData(txn); + List contactData = loadContactData(txn); BackupPayload payload = createBackupPayload(txn, secret, contactData, 0); // Create the shards @@ -415,17 +415,17 @@ class SocialBackupManagerImpl extends ConversationClientImpl } private BackupPayload createBackupPayload(Transaction txn, - SecretKey secret, List contactData, int version) + SecretKey secret, List contactData, int version) throws DbException { Identity identity = identityManager.getIdentity(txn); return backupPayloadEncoder.encodeBackupPayload(secret, identity, contactData, version); } - private List loadContactData(Transaction txn) + private List loadContactData(Transaction txn) throws DbException { Collection contacts = contactManager.getContacts(txn); - List contactData = new ArrayList<>(); + List contactData = new ArrayList<>(); for (Contact c : contacts) { // Skip contacts that are in the process of being removed Group contactGroup = getContactGroup(c); @@ -433,7 +433,7 @@ class SocialBackupManagerImpl extends ConversationClientImpl Map props = getTransportProperties(txn, c.getId()); Shard shard = getRemoteShard(txn, contactGroup.getId()); - contactData.add(new ContactData(c, props, shard)); + contactData.add(new org.briarproject.briar.api.socialbackup.ContactData(c, props, shard)); } return contactData; } @@ -513,7 +513,7 @@ class SocialBackupManagerImpl extends ConversationClientImpl throw new DbException(e); } } - private void updateBackup(Transaction txn, List contactData) + private void updateBackup(Transaction txn, List contactData) throws DbException { BackupMetadata backupMetadata = requireNonNull(getBackupMetadata(txn)); int newVersion = backupMetadata.getVersion() + 1; diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java index 0a5530e8f..9a9c3adf8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/SocialBackupModule.java @@ -11,8 +11,10 @@ import org.briarproject.briar.api.conversation.ConversationManager; import org.briarproject.briar.api.socialbackup.SocialBackupExchangeManager; import org.briarproject.briar.api.socialbackup.SocialBackupManager; import org.briarproject.briar.api.socialbackup.recovery.CustodianTask; +import org.briarproject.briar.api.socialbackup.recovery.RestoreAccount; import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask; import org.briarproject.briar.socialbackup.recovery.CustodianTaskImpl; +import org.briarproject.briar.socialbackup.recovery.RestoreAccountImpl; import org.briarproject.briar.socialbackup.recovery.SecretOwnerTaskImpl; import javax.inject.Inject; @@ -119,4 +121,9 @@ public class SocialBackupModule { CustodianTask custodianTask(CustodianTaskImpl custodianTask) { return custodianTask; } + + @Provides + RestoreAccount restoreAccount(RestoreAccountImpl restoreAccount) { + return restoreAccount; + } } diff --git a/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java b/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java new file mode 100644 index 000000000..b6a918649 --- /dev/null +++ b/briar-core/src/main/java/org/briarproject/briar/socialbackup/recovery/RestoreAccountImpl.java @@ -0,0 +1,73 @@ +package org.briarproject.briar.socialbackup.recovery; + +import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.briar.api.socialbackup.BackupPayload; +import org.briarproject.briar.api.socialbackup.DarkCrystal; +import org.briarproject.briar.api.socialbackup.ReturnShardPayload; +import org.briarproject.briar.api.socialbackup.Shard; +import org.briarproject.briar.api.socialbackup.recovery.RestoreAccount; +import org.briarproject.briar.socialbackup.BackupPayloadDecoder; +import org.briarproject.briar.api.socialbackup.SocialBackup; + +import java.security.GeneralSecurityException; +import java.util.ArrayList; + +import javax.inject.Inject; + +public class RestoreAccountImpl implements RestoreAccount { + private ArrayList recoveredShards = new ArrayList<>(); + private final DarkCrystal darkCrystal; + private SecretKey secretKey; + private final BackupPayloadDecoder backupPayloadDecoder; + private SocialBackup socialBackup; + + @Inject + RestoreAccountImpl(DarkCrystal darkCrystal, BackupPayloadDecoder backupPayloadDecoder) { + this.darkCrystal = darkCrystal; + this.backupPayloadDecoder = backupPayloadDecoder; + } + + public int getNumberOfShards() { return recoveredShards.size(); } + + // TODO figure out how to actually use a hash set for these objects + public boolean addReturnShardPayload(ReturnShardPayload toAdd) { + boolean found = false; + for (ReturnShardPayload returnShardPayload : recoveredShards) { + if (toAdd.equals(returnShardPayload)) { + found = true; + break; + } + } + if (!found) recoveredShards.add(toAdd); + return !found; + } + + public boolean canRecover() { + ArrayList shards = new ArrayList(); + for (ReturnShardPayload returnShardPayload : recoveredShards) { + // TODO check shards all have same secret id + shards.add(returnShardPayload.getShard()); + } + try { + secretKey = darkCrystal.combineShards(shards); + } catch (GeneralSecurityException e) { + // TODO handle error message + return false; + } + return true; + } + + public int recover() throws FormatException, GeneralSecurityException { + if (secretKey == null) throw new GeneralSecurityException(); + // TODO find backup with highest version number + BackupPayload backupPayload = recoveredShards.get(0).getBackupPayload(); + socialBackup = backupPayloadDecoder.decodeBackupPayload(secretKey, backupPayload); + int version = socialBackup.getVersion(); + return version; + } + + public SocialBackup getSocialBackup() { + return socialBackup; + } +}