mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Factor out recognition of QR code format.
This commit is contained in:
@@ -17,6 +17,7 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
import org.briarproject.bramble.mailbox.MailboxModule;
|
||||
import org.briarproject.bramble.plugin.PluginModule;
|
||||
import org.briarproject.bramble.properties.PropertiesModule;
|
||||
import org.briarproject.bramble.qrcode.QrCodeModule;
|
||||
import org.briarproject.bramble.record.RecordModule;
|
||||
import org.briarproject.bramble.reliability.ReliabilityModule;
|
||||
import org.briarproject.bramble.rendezvous.RendezvousModule;
|
||||
@@ -47,6 +48,7 @@ import dagger.Module;
|
||||
MailboxModule.class,
|
||||
PluginModule.class,
|
||||
PropertiesModule.class,
|
||||
QrCodeModule.class,
|
||||
RecordModule.class,
|
||||
ReliabilityModule.class,
|
||||
RendezvousModule.class,
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -29,6 +28,7 @@ import javax.inject.Inject;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.bramble.api.crypto.DecryptionResult.INVALID_CIPHERTEXT;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||
|
||||
@@ -99,7 +99,7 @@ class AccountManagerImpl implements AccountManager {
|
||||
}
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(f), Charset.forName("UTF-8")));
|
||||
new FileInputStream(f), UTF_8));
|
||||
String key = reader.readLine();
|
||||
reader.close();
|
||||
return key;
|
||||
@@ -151,7 +151,7 @@ class AccountManagerImpl implements AccountManager {
|
||||
@GuardedBy("stateChangeLock")
|
||||
private void writeDbKeyToFile(String key, File f) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
out.write(key.getBytes(Charset.forName("UTF-8")));
|
||||
out.write(key.getBytes(UTF_8));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.briarproject.nullsafety.NotNullByDefault;
|
||||
import org.whispersystems.curve25519.Curve25519;
|
||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
@@ -51,6 +50,7 @@ import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHE
|
||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||
import static org.briarproject.bramble.util.LogUtils.now;
|
||||
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
|
||||
|
||||
@NotNullByDefault
|
||||
class CryptoComponentImpl implements CryptoComponent {
|
||||
@@ -460,7 +460,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
@Override
|
||||
public String encodeOnion(byte[] publicKey) {
|
||||
Digest digest = new SHA3Digest(256);
|
||||
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
|
||||
byte[] label = ".onion checksum".getBytes(US_ASCII);
|
||||
digest.update(label, 0, label.length);
|
||||
digest.update(publicKey, 0, publicKey.length);
|
||||
digest.update(ONION_HS_PROTOCOL_VERSION);
|
||||
|
||||
@@ -39,12 +39,13 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class MessageEncrypter {
|
||||
@@ -228,7 +229,7 @@ public class MessageEncrypter {
|
||||
PublicKey publicKey =
|
||||
encrypter.getKeyParser().parsePublicKey(keyBytes);
|
||||
String message = readFully(System.in);
|
||||
byte[] plaintext = message.getBytes(Charset.forName("UTF-8"));
|
||||
byte[] plaintext = message.getBytes(UTF_8);
|
||||
byte[] ciphertext = encrypter.encrypt(publicKey, plaintext);
|
||||
System.out.println(AsciiArmour.wrap(ciphertext, LINE_LENGTH));
|
||||
}
|
||||
@@ -242,7 +243,7 @@ public class MessageEncrypter {
|
||||
encrypter.getKeyParser().parsePrivateKey(keyBytes);
|
||||
byte[] ciphertext = AsciiArmour.unwrap(readFully(System.in));
|
||||
byte[] plaintext = encrypter.decrypt(privateKey, ciphertext);
|
||||
System.out.println(new String(plaintext, Charset.forName("UTF-8")));
|
||||
System.out.println(new String(plaintext, UTF_8));
|
||||
}
|
||||
|
||||
private static String readFully(InputStream in) throws IOException {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||
@@ -19,13 +17,13 @@ public class KeyAgreementModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
PayloadEncoder providePayloadEncoder(BdfWriterFactory bdfWriterFactory) {
|
||||
return new PayloadEncoderImpl(bdfWriterFactory);
|
||||
PayloadEncoder providePayloadEncoder(PayloadEncoderImpl payloadEncoder) {
|
||||
return payloadEncoder;
|
||||
}
|
||||
|
||||
@Provides
|
||||
PayloadParser providePayloadParser(BdfReaderFactory bdfReaderFactory) {
|
||||
return new PayloadParserImpl(bdfReaderFactory);
|
||||
PayloadParser providePayloadParser(PayloadParserImpl payloadParser) {
|
||||
return payloadParser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -13,7 +13,8 @@ import java.io.IOException;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_ID;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
@@ -29,7 +30,8 @@ class PayloadEncoderImpl implements PayloadEncoder {
|
||||
@Override
|
||||
public byte[] encode(Payload p) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(PROTOCOL_VERSION);
|
||||
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
|
||||
out.write(formatIdAndVersion);
|
||||
BdfWriter w = bdfWriterFactory.createWriter(out);
|
||||
try {
|
||||
w.writeListStart(); // Payload start
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
@@ -11,6 +12,8 @@ import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
|
||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -21,34 +24,41 @@ import java.util.List;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class PayloadParserImpl implements PayloadParser {
|
||||
|
||||
private final BdfReaderFactory bdfReaderFactory;
|
||||
private final QrCodeClassifier qrCodeClassifier;
|
||||
|
||||
@Inject
|
||||
PayloadParserImpl(BdfReaderFactory bdfReaderFactory) {
|
||||
PayloadParserImpl(BdfReaderFactory bdfReaderFactory,
|
||||
QrCodeClassifier qrCodeClassifier) {
|
||||
this.bdfReaderFactory = bdfReaderFactory;
|
||||
this.qrCodeClassifier = qrCodeClassifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Payload parse(byte[] raw) throws IOException {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(raw);
|
||||
// First byte: the protocol version
|
||||
int protocolVersion = in.read();
|
||||
if (protocolVersion == -1) throw new FormatException();
|
||||
if (protocolVersion != PROTOCOL_VERSION) {
|
||||
boolean tooOld = protocolVersion < PROTOCOL_VERSION ||
|
||||
protocolVersion == BETA_PROTOCOL_VERSION;
|
||||
public Payload parse(String payloadString) throws IOException {
|
||||
Pair<QrCodeType, Integer> typeAndVersion =
|
||||
qrCodeClassifier.classifyQrCode(payloadString);
|
||||
if (typeAndVersion.getFirst() != BQP) throw new FormatException();
|
||||
int formatVersion = typeAndVersion.getSecond();
|
||||
if (formatVersion != QR_FORMAT_VERSION) {
|
||||
boolean tooOld = formatVersion < QR_FORMAT_VERSION;
|
||||
throw new UnsupportedVersionException(tooOld);
|
||||
}
|
||||
byte[] raw = payloadString.getBytes(ISO_8859_1);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(raw);
|
||||
// First byte: the format identifier and version (already parsed)
|
||||
if (in.read() == -1) throw new AssertionError();
|
||||
// The rest of the payload is a BDF list with one or more elements
|
||||
BdfReader r = bdfReaderFactory.createReader(in);
|
||||
BdfList payload = r.readList();
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.event.EventExecutor;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxPairingTask;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
@@ -25,6 +26,7 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
|
||||
private final MailboxApi api;
|
||||
private final MailboxSettingsManager mailboxSettingsManager;
|
||||
private final MailboxUpdateManager mailboxUpdateManager;
|
||||
private final QrCodeClassifier qrCodeClassifier;
|
||||
|
||||
@Inject
|
||||
MailboxPairingTaskFactoryImpl(
|
||||
@@ -34,7 +36,8 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
|
||||
Clock clock,
|
||||
MailboxApi api,
|
||||
MailboxSettingsManager mailboxSettingsManager,
|
||||
MailboxUpdateManager mailboxUpdateManager) {
|
||||
MailboxUpdateManager mailboxUpdateManager,
|
||||
QrCodeClassifier qrCodeClassifier) {
|
||||
this.eventExecutor = eventExecutor;
|
||||
this.db = db;
|
||||
this.crypto = crypto;
|
||||
@@ -42,12 +45,13 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory {
|
||||
this.api = api;
|
||||
this.mailboxSettingsManager = mailboxSettingsManager;
|
||||
this.mailboxUpdateManager = mailboxUpdateManager;
|
||||
this.qrCodeClassifier = qrCodeClassifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailboxPairingTask createPairingTask(String qrCodePayload) {
|
||||
return new MailboxPairingTaskImpl(qrCodePayload, eventExecutor, db,
|
||||
crypto, clock, api, mailboxSettingsManager,
|
||||
mailboxUpdateManager);
|
||||
mailboxUpdateManager, qrCodeClassifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.Consumer;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
@@ -14,13 +15,14 @@ import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.mailbox.MailboxApi.ApiException;
|
||||
import org.briarproject.bramble.mailbox.MailboxApi.MailboxAlreadyPairedException;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -32,7 +34,10 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
@ThreadSafe
|
||||
@NotNullByDefault
|
||||
@@ -40,9 +45,6 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
|
||||
private final static Logger LOG =
|
||||
getLogger(MailboxPairingTaskImpl.class.getName());
|
||||
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||
private static final int VERSION_REQUIRED = 32;
|
||||
|
||||
private final String payload;
|
||||
private final Executor eventExecutor;
|
||||
@@ -52,6 +54,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
private final MailboxApi api;
|
||||
private final MailboxSettingsManager mailboxSettingsManager;
|
||||
private final MailboxUpdateManager mailboxUpdateManager;
|
||||
private final QrCodeClassifier qrCodeClassifier;
|
||||
private final long timeStarted;
|
||||
|
||||
private final Object lock = new Object();
|
||||
@@ -69,7 +72,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
Clock clock,
|
||||
MailboxApi api,
|
||||
MailboxSettingsManager mailboxSettingsManager,
|
||||
MailboxUpdateManager mailboxUpdateManager) {
|
||||
MailboxUpdateManager mailboxUpdateManager,
|
||||
QrCodeClassifier qrCodeClassifier) {
|
||||
this.payload = payload;
|
||||
this.eventExecutor = eventExecutor;
|
||||
this.db = db;
|
||||
@@ -78,6 +82,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
this.api = api;
|
||||
this.mailboxSettingsManager = mailboxSettingsManager;
|
||||
this.mailboxUpdateManager = mailboxUpdateManager;
|
||||
this.qrCodeClassifier = qrCodeClassifier;
|
||||
timeStarted = clock.currentTimeMillis();
|
||||
state = new MailboxPairingState.QrCodeReceived(timeStarted);
|
||||
}
|
||||
@@ -101,10 +106,20 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Pair<QrCodeType, Integer> typeAndVersion =
|
||||
qrCodeClassifier.classifyQrCode(payload);
|
||||
QrCodeType qrCodeType = typeAndVersion.getFirst();
|
||||
int formatVersion = typeAndVersion.getSecond();
|
||||
if (qrCodeType != MAILBOX || formatVersion != QR_FORMAT_VERSION) {
|
||||
setState(new MailboxPairingState.InvalidQrCode(qrCodeType,
|
||||
formatVersion));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
pairMailbox();
|
||||
} catch (FormatException e) {
|
||||
onMailboxError(e, new MailboxPairingState.InvalidQrCode());
|
||||
onMailboxError(e, new MailboxPairingState.InvalidQrCode(qrCodeType,
|
||||
formatVersion));
|
||||
} catch (MailboxAlreadyPairedException e) {
|
||||
onMailboxError(e, new MailboxPairingState.MailboxAlreadyPaired());
|
||||
} catch (IOException e) {
|
||||
@@ -169,14 +184,6 @@ class MailboxPairingTaskImpl implements MailboxPairingTask {
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
int version = bytes[0] & 0xFF;
|
||||
if (version != VERSION_REQUIRED) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("QR code has not version " + VERSION_REQUIRED +
|
||||
": " + version);
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
LOG.info("QR code is valid");
|
||||
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
|
||||
String onion = crypto.encodeOnion(onionPubKey);
|
||||
|
||||
@@ -46,7 +46,6 @@ import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -100,6 +99,7 @@ import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -419,9 +419,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
append(strb, "ClientTransportPlugin meek_lite exec", obfs4Path);
|
||||
String snowflakePath = getSnowflakeExecutableFile().getAbsolutePath();
|
||||
append(strb, "ClientTransportPlugin snowflake exec", snowflakePath);
|
||||
//noinspection CharsetObjectCanBeUsed
|
||||
return new ByteArrayInputStream(
|
||||
strb.toString().getBytes(Charset.forName("UTF-8")));
|
||||
return new ByteArrayInputStream(strb.toString().getBytes(UTF_8));
|
||||
}
|
||||
|
||||
private void listFiles(File f) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import static org.briarproject.bramble.util.StringUtils.US_ASCII;
|
||||
|
||||
class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||
|
||||
@@ -31,6 +31,6 @@ class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||
EdDSAPrivateKeySpec spec = new EdDSAPrivateKeySpec(seed, CURVE_SPEC);
|
||||
byte[] hash = spec.getH();
|
||||
byte[] base64 = Base64.encode(hash);
|
||||
return "ED25519-V3:" + new String(base64, Charset.forName("US-ASCII"));
|
||||
return "ED25519-V3:" + new String(base64, US_ASCII);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.bramble.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxConstants;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.UNKNOWN;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class QrCodeClassifierImpl implements QrCodeClassifier {
|
||||
|
||||
@Inject
|
||||
QrCodeClassifierImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<QrCodeType, Integer> classifyQrCode(String payload) {
|
||||
byte[] bytes = payload.getBytes(ISO_8859_1);
|
||||
if (bytes.length == 0) return new Pair<>(UNKNOWN, 0);
|
||||
// If this is a Bramble QR code then the first byte encodes the
|
||||
// format ID (3 bits) and version (5 bits)
|
||||
int formatIdAndVersion = bytes[0] & 0xFF;
|
||||
int formatId = formatIdAndVersion >> 5;
|
||||
int formatVersion = formatIdAndVersion & 0x1F;
|
||||
if (formatId == KeyAgreementConstants.QR_FORMAT_ID) {
|
||||
return new Pair<>(BQP, formatVersion);
|
||||
}
|
||||
if (formatId == MailboxConstants.QR_FORMAT_ID) {
|
||||
return new Pair<>(MAILBOX, formatVersion);
|
||||
}
|
||||
return new Pair<>(UNKNOWN, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.bramble.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class QrCodeModule {
|
||||
|
||||
@Provides
|
||||
QrCodeClassifier provideQrCodeClassifier(
|
||||
QrCodeClassifierImpl qrCodeClassifier) {
|
||||
return qrCodeClassifier;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -34,6 +33,7 @@ import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
@@ -342,7 +342,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
private void storeDatabaseKey(File f, String hex) throws IOException {
|
||||
f.getParentFile().mkdirs();
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
out.write(hex.getBytes(Charset.forName("UTF-8")));
|
||||
out.write(hex.getBytes(UTF_8));
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
@@ -350,7 +350,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
||||
@Nullable
|
||||
private String loadDatabaseKey(File f) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(f), Charset.forName("UTF-8")));
|
||||
new FileInputStream(f), UTF_8));
|
||||
String hex = reader.readLine();
|
||||
reader.close();
|
||||
return hex;
|
||||
|
||||
@@ -2,21 +2,26 @@ package org.briarproject.bramble.keyagreement;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -26,32 +31,29 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final BdfReaderFactory bdfReaderFactory =
|
||||
context.mock(BdfReaderFactory.class);
|
||||
private final QrCodeClassifier qrCodeClassifier =
|
||||
context.mock(QrCodeClassifier.class);
|
||||
private final BdfReader bdfReader = context.mock(BdfReader.class);
|
||||
|
||||
private final String payload = getRandomString(123);
|
||||
|
||||
private final PayloadParserImpl payloadParser =
|
||||
new PayloadParserImpl(bdfReaderFactory);
|
||||
new PayloadParserImpl(bdfReaderFactory, qrCodeClassifier);
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testThrowsFormatExceptionIfPayloadIsEmpty() throws Exception {
|
||||
payloadParser.parse(new byte[0]);
|
||||
public void testThrowsFormatExceptionForWrongQrCodeType() throws Exception {
|
||||
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION);
|
||||
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThrowsUnsupportedVersionExceptionForOldVersion()
|
||||
throws Exception {
|
||||
try {
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION - 1});
|
||||
fail();
|
||||
} catch (UnsupportedVersionException e) {
|
||||
assertTrue(e.isTooOld());
|
||||
}
|
||||
}
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION - 1);
|
||||
|
||||
@Test
|
||||
public void testThrowsUnsupportedVersionExceptionForBetaVersion()
|
||||
throws Exception {
|
||||
try {
|
||||
payloadParser.parse(new byte[] {BETA_PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
fail();
|
||||
} catch (UnsupportedVersionException e) {
|
||||
assertTrue(e.isTooOld());
|
||||
@@ -61,8 +63,10 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testThrowsUnsupportedVersionExceptionForNewVersion()
|
||||
throws Exception {
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION + 1);
|
||||
|
||||
try {
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION + 1});
|
||||
payloadParser.parse(payload);
|
||||
fail();
|
||||
} catch (UnsupportedVersionException e) {
|
||||
assertFalse(e.isTooOld());
|
||||
@@ -71,6 +75,8 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testThrowsFormatExceptionForEmptyList() throws Exception {
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -79,7 +85,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(new BdfList()));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -87,6 +93,8 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -97,7 +105,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(false));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -105,6 +113,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH - 1);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -115,7 +124,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(true));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -123,6 +132,7 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH + 1);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -133,12 +143,14 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(true));
|
||||
}});
|
||||
|
||||
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
payloadParser.parse(payload);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsPayloadWithNoDescriptors() throws Exception {
|
||||
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory).createReader(
|
||||
with(any(ByteArrayInputStream.class)));
|
||||
@@ -149,8 +161,16 @@ public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(true));
|
||||
}});
|
||||
|
||||
Payload p = payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||
Payload p = payloadParser.parse(payload);
|
||||
assertArrayEquals(commitment, p.getCommitment());
|
||||
assertTrue(p.getTransportDescriptors().isEmpty());
|
||||
}
|
||||
|
||||
private void expectClassifyQrCode(String payload, QrCodeType qrCodeType,
|
||||
int formatVersion) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(qrCodeClassifier).classifyQrCode(payload);
|
||||
will(returnValue(new Pair<>(qrCodeType, formatVersion)));
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.bramble.mailbox;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
@@ -13,6 +14,8 @@ import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxUpdateManager;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.DbExpectations;
|
||||
@@ -27,6 +30,9 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.mailbox.MailboxTestUtils.getQrCodePayload;
|
||||
import static org.briarproject.bramble.test.TestUtils.getContact;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
@@ -48,9 +54,8 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
context.mock(MailboxSettingsManager.class);
|
||||
private final MailboxUpdateManager mailboxUpdateManager =
|
||||
context.mock(MailboxUpdateManager.class);
|
||||
private final MailboxPairingTaskFactory factory =
|
||||
new MailboxPairingTaskFactoryImpl(executor, db, crypto, clock, api,
|
||||
mailboxSettingsManager, mailboxUpdateManager);
|
||||
private final QrCodeClassifier qrCodeClassifier =
|
||||
context.mock(QrCodeClassifier.class);
|
||||
|
||||
private final String onion = getRandomString(56);
|
||||
private final byte[] onionBytes = getRandomBytes(32);
|
||||
@@ -75,23 +80,47 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidQrCode() {
|
||||
MailboxPairingTask task1 = createPairingTask(getRandomString(42));
|
||||
task1.run();
|
||||
task1.addObserver(state ->
|
||||
public void testInvalidQrCodeType() {
|
||||
String payload = getRandomString(65);
|
||||
MailboxPairingTask task = createPairingTask(payload);
|
||||
|
||||
expectClassifyQrCode(payload, BQP, QR_FORMAT_VERSION);
|
||||
|
||||
task.run();
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
|
||||
);
|
||||
}
|
||||
|
||||
String goodLength = "00" + getRandomString(63);
|
||||
MailboxPairingTask task2 = createPairingTask(goodLength);
|
||||
task2.run();
|
||||
task2.addObserver(state ->
|
||||
@Test
|
||||
public void testInvalidQrCodeVersion() {
|
||||
String payload = getRandomString(65);
|
||||
MailboxPairingTask task = createPairingTask(payload);
|
||||
|
||||
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION + 1);
|
||||
|
||||
task.run();
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidQrCodeLength() {
|
||||
String payload = getRandomString(42);
|
||||
MailboxPairingTask task = createPairingTask(payload);
|
||||
|
||||
expectClassifyQrCode(payload, MAILBOX, QR_FORMAT_VERSION);
|
||||
|
||||
task.run();
|
||||
task.addObserver(state ->
|
||||
assertTrue(state instanceof MailboxPairingState.InvalidQrCode)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulPairing() throws Exception {
|
||||
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).encodeOnion(onionBytes);
|
||||
will(returnValue(onion));
|
||||
@@ -156,6 +185,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
|
||||
private void testApiException(Exception e,
|
||||
Class<? extends MailboxPairingState> s) throws Exception {
|
||||
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).encodeOnion(onionBytes);
|
||||
will(returnValue(onion));
|
||||
@@ -170,6 +200,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testDbException() throws Exception {
|
||||
expectClassifyQrCode(validPayload, MAILBOX, QR_FORMAT_VERSION);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).encodeOnion(onionBytes);
|
||||
will(returnValue(onion));
|
||||
@@ -206,6 +237,16 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(time));
|
||||
}});
|
||||
|
||||
return factory.createPairingTask(qrCodePayload);
|
||||
return new MailboxPairingTaskImpl(qrCodePayload, executor, db,
|
||||
crypto, clock, api, mailboxSettingsManager,
|
||||
mailboxUpdateManager, qrCodeClassifier);
|
||||
}
|
||||
|
||||
private void expectClassifyQrCode(String payload, QrCodeType qrCodeType,
|
||||
int formatVersion) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(qrCodeClassifier).classifyQrCode(payload);
|
||||
will(returnValue(new Pair<>(qrCodeType, formatVersion)));
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.bramble.mailbox;
|
||||
import org.briarproject.bramble.api.WeakSingletonProvider;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.net.SocketFactory;
|
||||
@@ -11,20 +10,24 @@ import javax.net.SocketFactory;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_ID;
|
||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.QR_FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
|
||||
class MailboxTestUtils {
|
||||
|
||||
static String getQrCodePayload(byte[] onionBytes, byte[] setupToken) {
|
||||
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
|
||||
byte[] payloadBytes = ByteBuffer.allocate(65)
|
||||
.put((byte) 32) // 1
|
||||
.put((byte) formatIdAndVersion) // 1
|
||||
.put(onionBytes) // 32
|
||||
.put(setupToken) // 32
|
||||
.array();
|
||||
//noinspection CharsetObjectCanBeUsed
|
||||
return new String(payloadBytes, Charset.forName("ISO-8859-1"));
|
||||
return new String(payloadBytes, ISO_8859_1);
|
||||
}
|
||||
|
||||
// Used by mailbox integration tests
|
||||
static String getQrCodePayload(byte[] setupToken) {
|
||||
return getQrCodePayload(getRandomId(), setupToken);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.briarproject.bramble.qrcode;
|
||||
|
||||
import org.briarproject.bramble.api.Pair;
|
||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementConstants;
|
||||
import org.briarproject.bramble.api.mailbox.MailboxConstants;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier;
|
||||
import org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.BQP;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.MAILBOX;
|
||||
import static org.briarproject.bramble.api.qrcode.QrCodeClassifier.QrCodeType.UNKNOWN;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class QrCodeClassifierImplTest extends BrambleTestCase {
|
||||
|
||||
private final QrCodeClassifier classifier = new QrCodeClassifierImpl();
|
||||
|
||||
@Test
|
||||
public void testClassifiesEmptyStringAsUnknown() {
|
||||
Pair<QrCodeType, Integer> result = classifier.classifyQrCode("");
|
||||
assertEquals(UNKNOWN, result.getFirst());
|
||||
assertEquals(0, result.getSecond().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassifiesKeyAgreement() {
|
||||
byte[] payloadBytes = getRandomBytes(123);
|
||||
for (int version = 0; version < 32; version++) {
|
||||
int typeAndVersion =
|
||||
(KeyAgreementConstants.QR_FORMAT_ID << 5) | version;
|
||||
payloadBytes[0] = (byte) typeAndVersion;
|
||||
String payload = new String(payloadBytes, ISO_8859_1);
|
||||
Pair<QrCodeType, Integer> result =
|
||||
classifier.classifyQrCode(payload);
|
||||
assertEquals(BQP, result.getFirst());
|
||||
assertEquals(version, result.getSecond().intValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassifiesMailbox() {
|
||||
byte[] payloadBytes = getRandomBytes(123);
|
||||
for (int version = 0; version < 32; version++) {
|
||||
int typeAndVersion =
|
||||
(MailboxConstants.QR_FORMAT_ID << 5) | version;
|
||||
payloadBytes[0] = (byte) typeAndVersion;
|
||||
String payload = new String(payloadBytes, ISO_8859_1);
|
||||
Pair<QrCodeType, Integer> result =
|
||||
classifier.classifyQrCode(payload);
|
||||
assertEquals(MAILBOX, result.getFirst());
|
||||
assertEquals(version, result.getSecond().intValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassifiesUnknownFormatIdAsUnknown() {
|
||||
byte[] payloadBytes = getRandomBytes(123);
|
||||
int unknownFormatId = MailboxConstants.QR_FORMAT_ID + 1;
|
||||
int typeAndVersion = unknownFormatId << 5;
|
||||
payloadBytes[0] = (byte) typeAndVersion;
|
||||
String payload = new String(payloadBytes, ISO_8859_1);
|
||||
Pair<QrCodeType, Integer> result = classifier.classifyQrCode(payload);
|
||||
assertEquals(UNKNOWN, result.getFirst());
|
||||
assertEquals(0, result.getSecond().intValue());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user