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