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