Basic encryption on the custodian side

This commit is contained in:
ameba23
2021-04-13 21:20:51 +02:00
parent f13cc15661
commit 9b4f5be6fe

View File

@@ -1,7 +1,12 @@
package org.briarproject.briar.socialbackup.recovery;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
import org.briarproject.bramble.api.crypto.AuthenticatedCipher;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.briar.api.socialbackup.recovery.CustodianTask;
@@ -11,6 +16,8 @@ import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import javax.inject.Inject;
@@ -21,11 +28,22 @@ public class CustodianTaskImpl implements CustodianTask {
private ClientHelper clientHelper;
private InetSocketAddress remoteSocketAddress;
private Socket socket = new Socket();
private final CryptoComponent crypto;
private final AuthenticatedCipher cipher;
private final KeyPair localKeyPair;
private final SecureRandom secureRandom;
private SecretKey sharedSecret;
private final int TIMEOUT = 120 * 1000;
private final int NONCE_LENGTH = 24; // TODO get this constant
@Inject
CustodianTaskImpl(ClientHelper clientHelper) {
CustodianTaskImpl(CryptoComponent crypto, ClientHelper clientHelper,
AuthenticatedCipher cipher) {
this.clientHelper = clientHelper;
this.crypto = crypto;
this.secureRandom = crypto.getSecureRandom();
this.cipher = cipher;
localKeyPair = crypto.generateAgreementKeyPair();
}
@Override
@@ -51,15 +69,20 @@ public class CustodianTaskImpl implements CustodianTask {
public void qrCodeDecoded(byte[] qrCodePayloadRaw) {
try {
BdfList qrCodePayload = clientHelper.toList(qrCodePayloadRaw);
AgreementPublicKey publicKey =
AgreementPublicKey remotePublicKey =
new AgreementPublicKey(qrCodePayload.getRaw(0));
byte[] addressRaw = qrCodePayload.getRaw(1);
int port = qrCodePayload.getLong(2).intValue();
remoteSocketAddress =
new InetSocketAddress(InetAddress.getByAddress(addressRaw),
port);
sharedSecret =
crypto.deriveSharedSecret("ShardReturn", remotePublicKey,
localKeyPair, addressRaw);
System.out.println(
" Qr code decoded " + publicKey.getEncoded().length + " " +
" Qr code decoded " + remotePublicKey.getEncoded().length +
" " +
remoteSocketAddress);
} catch (Exception e) {
observer.onStateChanged(new CustodianTask.State.Failure(
@@ -74,7 +97,7 @@ public class CustodianTaskImpl implements CustodianTask {
try {
socket.connect(remoteSocketAddress, TIMEOUT);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("crunchy".getBytes());
outputStream.write(createPayload());
observer.onStateChanged(new CustodianTask.State.ReceivingAck());
} catch (IOException e) {
observer.onStateChanged(new CustodianTask.State.Failure(
@@ -85,6 +108,36 @@ public class CustodianTaskImpl implements CustodianTask {
receiveAck();
}
private byte[] createPayload() throws FormatException {
BdfList payloadList = new BdfList();
payloadList.add(localKeyPair.getPublic().getEncoded());
byte[] nonce = new byte[NONCE_LENGTH];
secureRandom.nextBytes(nonce);
payloadList.add(nonce);
try {
payloadList.add(encrypt("crunchy".getBytes(), nonce));
} catch (GeneralSecurityException e) {
throw new FormatException();
}
return clientHelper.toByteArray(payloadList);
}
private byte[] encrypt(byte[] message, byte[] nonce)
throws GeneralSecurityException {
cipher.init(true, sharedSecret, nonce);
byte[] cipherText = new byte[message.length + cipher.getMacBytes()];
cipher.process(message, 0, message.length, cipherText, 0);
return cipherText;
}
private byte[] decrypt(byte[] cipherText, byte[] nonce)
throws GeneralSecurityException {
cipher.init(false, sharedSecret, nonce);
byte[] message = new byte[cipherText.length - cipher.getMacBytes()];
cipher.process(cipherText, 0, cipherText.length, message, 0);
return message;
}
private void receiveAck() {
try {
InputStream inputStream = socket.getInputStream();
@@ -100,4 +153,5 @@ public class CustodianTaskImpl implements CustodianTask {
return;
}
}
}