Implement BackupPayloadDecoder

This commit is contained in:
ameba23
2021-04-19 09:00:05 +02:00
parent 101b93b3da
commit ad3c9e101c
4 changed files with 165 additions and 3 deletions

View File

@@ -1,4 +1,16 @@
package org.briarproject.briar.socialbackup;
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 java.security.GeneralSecurityException;
@NotNullByDefault
public interface BackupPayloadDecoder {
SocialBackup decodeBackupPayload(
SecretKey secret,
BackupPayload backupPayload, byte[] nonce) throws FormatException,
GeneralSecurityException;
}

View File

@@ -0,0 +1,114 @@
package org.briarproject.briar.socialbackup;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
import org.briarproject.bramble.api.crypto.PrivateKey;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.Identity;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.plugin.TransportId;
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 java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Provider;
import static org.briarproject.briar.socialbackup.SocialBackupConstants.AUTH_TAG_BYTES;
public class BackupPayloadDecoderImpl {
private final ClientHelper clientHelper;
private final Provider<AuthenticatedCipher> cipherProvider;
private final SecureRandom secureRandom;
private final MessageParser messageParser;
@Inject
BackupPayloadDecoderImpl(ClientHelper clientHelper,
Provider<AuthenticatedCipher> cipherProvider,
SecureRandom secureRandom,
MessageParser messageParser) {
this.clientHelper = clientHelper;
this.cipherProvider = cipherProvider;
this.secureRandom = secureRandom;
this.messageParser = messageParser;
}
public SocialBackup decodeBackupPayload(
SecretKey secret,
BackupPayload backupPayload, byte[] nonce)
throws FormatException, GeneralSecurityException {
AuthenticatedCipher cipher = cipherProvider.get();
cipher.init(false, secret, nonce);
byte[] plaintext =
new byte[backupPayload.getBytes().length - AUTH_TAG_BYTES];
int decrypted = cipher.process(backupPayload.getBytes(), 0,
backupPayload.getBytes().length, plaintext, 0);
if (decrypted != plaintext.length) throw new AssertionError();
BdfList backup = clientHelper.toList(plaintext);
int version = backup.getLong(0).intValue();
BdfList bdfIdentity = backup.getList(1);
BdfList bdfContactData = backup.getList(2);
LocalAuthor localAuthor =
(LocalAuthor) clientHelper
.parseAndValidateAuthor(bdfIdentity.getList(0));
//TODO
byte[] authorPrivateKeyBytes = bdfIdentity.getRaw(1);
PublicKey handshakePublicKey =
new AgreementPublicKey(bdfIdentity.getRaw(2));
PrivateKey handShakePrivateKey =
new AgreementPrivateKey(bdfIdentity.getRaw(3));
Long created = System.currentTimeMillis();
Identity identity = new Identity(localAuthor, handshakePublicKey,
handShakePrivateKey, created);
List<ContactData> contactDataList = new ArrayList();
for (int i = 0; i < bdfContactData.size(); i++) {
BdfList bdfData = bdfContactData.getList(i);
Author author =
clientHelper.parseAndValidateAuthor(bdfData.getList(0));
String alias = bdfData.getString(1);
// 2 - public key or null
byte[] publicKeyBytes = bdfData.getRaw(2);
// 3 - properties dictionary
Map<TransportId, TransportProperties> properties = clientHelper
.parseAndValidateTransportPropertiesMap(
bdfData.getDictionary(3));
// 4 shard or null
BdfList shardList = bdfData.getList(4);
Shard shard = shardList == null ? null :
messageParser.parseShardMessage(shardList);
ContactId contactId = new ContactId(i);
Contact contact =
new Contact(contactId, author, author.getId(), alias,
handshakePublicKey, false);
ContactData contactData =
new ContactData(contact, properties, shard);
contactDataList.add(contactData);
}
return new SocialBackup(identity, contactDataList, version);
}
}

View File

@@ -1,4 +1,29 @@
package org.briarproject.briar.socialbackup;
import org.briarproject.bramble.api.identity.Identity;
import java.util.List;
public class SocialBackup {
private Identity identity;
private List<ContactData> contacts;
private int version;
SocialBackup (Identity identity, List<ContactData> contacts, int version) {
this.identity = identity;
this.contacts = contacts;
this.version = version;
}
public Identity getIdentity() {
return identity;
}
public List<ContactData> getContacts() {
return contacts;
}
public int getVersion() {
return version;
}
}

View File

@@ -4,6 +4,9 @@ import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.TestDatabaseConfigModule;
import org.briarproject.briar.api.socialbackup.BackupPayload;
import org.briarproject.briar.api.socialbackup.ReturnShardPayload;
import org.briarproject.briar.api.socialbackup.Shard;
import org.briarproject.briar.api.socialbackup.recovery.CustodianTask;
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
import org.junit.After;
@@ -13,6 +16,7 @@ import org.junit.Test;
import java.io.File;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.concurrent.Executor;
import static junit.framework.TestCase.fail;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
@@ -51,6 +55,12 @@ public class ReturnShardIntegrationTest extends BrambleTestCase {
CustodianTask custodianTask = custodian.getCustodianTask();
byte[] payload = "its nice to be important but its more important to be nice".getBytes();
Shard shard = new Shard("secretid".getBytes(), "shard".getBytes());
BackupPayload backupPayload = new BackupPayload("backup payload".getBytes());
ReturnShardPayload returnShardPayload = new ReturnShardPayload(shard, backupPayload);
// payloadBytes = clientHelper
SecretOwnerTask.Observer ownerObserver =
state -> {
if (state instanceof SecretOwnerTask.State.Listening) {
@@ -60,8 +70,8 @@ public class ReturnShardIntegrationTest extends BrambleTestCase {
System.out.println(qrPayload.length);
transferQrCode(custodianTask, qrPayload);
} else if (state instanceof SecretOwnerTask.State.Success) {
byte[] remotePayload = ((SecretOwnerTask.State.Success) state).getRemotePayload();
assertTrue(Arrays.equals(remotePayload, payload));
ReturnShardPayload remotePayload = ((SecretOwnerTask.State.Success) state).getRemotePayload();
assertTrue(remotePayload.equals(payload));
System.out.println("Success");
} else if (state instanceof SecretOwnerTask.State.Failure) {
System.out.println("Owner state: failure");
@@ -103,7 +113,8 @@ public class ReturnShardIntegrationTest extends BrambleTestCase {
// TODO how to get the test to wait for the io to finish
try {
Thread.sleep(1000);
// Thread.sleep(1000);
tearDown();
} catch (Exception e) {
fail();
}