mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Basic encryption on the custodian side
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user