mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 23:29:52 +01:00
Merge branch '2167-decode-qr-code-for-pairing-with-mailbox' into 'master'
Create initial MailboxPairViewModel that decodes QR code Closes #2167 See merge request briar/briar!1544
This commit is contained in:
@@ -3,6 +3,7 @@ package org.briarproject.bramble.plugin.tor;
|
|||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
@@ -60,6 +61,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
private final File torDirectory;
|
private final File torDirectory;
|
||||||
private int torSocksPort;
|
private int torSocksPort;
|
||||||
private int torControlPort;
|
private int torControlPort;
|
||||||
|
private final CryptoComponent crypto;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AndroidTorPluginFactory(@IoExecutor Executor ioExecutor,
|
AndroidTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||||
@@ -77,7 +79,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
Clock clock,
|
Clock clock,
|
||||||
@TorDirectory File torDirectory,
|
@TorDirectory File torDirectory,
|
||||||
@TorSocksPort int torSocksPort,
|
@TorSocksPort int torSocksPort,
|
||||||
@TorControlPort int torControlPort) {
|
@TorControlPort int torControlPort,
|
||||||
|
CryptoComponent crypto) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.wakefulIoExecutor = wakefulIoExecutor;
|
this.wakefulIoExecutor = wakefulIoExecutor;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
@@ -94,6 +97,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
this.torDirectory = torDirectory;
|
this.torDirectory = torDirectory;
|
||||||
this.torSocksPort = torSocksPort;
|
this.torSocksPort = torSocksPort;
|
||||||
this.torControlPort = torControlPort;
|
this.torControlPort = torControlPort;
|
||||||
|
this.crypto = crypto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -135,7 +139,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
TorRendezvousCrypto torRendezvousCrypto =
|
||||||
|
new TorRendezvousCryptoImpl(crypto);
|
||||||
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
|
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor,
|
||||||
wakefulIoExecutor, app, networkManager, locationUtils,
|
wakefulIoExecutor, app, networkManager, locationUtils,
|
||||||
torSocketFactory, clock, resourceProvider,
|
torSocketFactory, clock, resourceProvider,
|
||||||
|
|||||||
@@ -170,4 +170,11 @@ public interface CryptoComponent {
|
|||||||
* length. The line terminator is CRLF.
|
* length. The line terminator is CRLF.
|
||||||
*/
|
*/
|
||||||
String asciiArmour(byte[] b, int lineLength);
|
String asciiArmour(byte[] b, int lineLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the onion/hidden service address given its public key. As
|
||||||
|
* specified here: https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt?id=29245fd5#n2135
|
||||||
|
*/
|
||||||
|
String encodeOnionAddress(byte[] publicKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import net.i2p.crypto.eddsa.KeyPairGenerator;
|
|||||||
import org.bouncycastle.crypto.CryptoException;
|
import org.bouncycastle.crypto.CryptoException;
|
||||||
import org.bouncycastle.crypto.Digest;
|
import org.bouncycastle.crypto.Digest;
|
||||||
import org.bouncycastle.crypto.digests.Blake2bDigest;
|
import org.bouncycastle.crypto.digests.Blake2bDigest;
|
||||||
|
import org.bouncycastle.crypto.digests.SHA3Digest;
|
||||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
@@ -21,11 +22,13 @@ import org.briarproject.bramble.api.crypto.SignaturePrivateKey;
|
|||||||
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
|
import org.briarproject.bramble.api.crypto.SignaturePublicKey;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
||||||
|
import org.briarproject.bramble.util.Base32;
|
||||||
import org.briarproject.bramble.util.ByteUtils;
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.whispersystems.curve25519.Curve25519;
|
import org.whispersystems.curve25519.Curve25519;
|
||||||
import org.whispersystems.curve25519.Curve25519KeyPair;
|
import org.whispersystems.curve25519.Curve25519KeyPair;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
@@ -58,6 +61,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
private static final int PBKDF_SALT_BYTES = 32; // 256 bits
|
private static final int PBKDF_SALT_BYTES = 32; // 256 bits
|
||||||
private static final byte PBKDF_FORMAT_SCRYPT = 0;
|
private static final byte PBKDF_FORMAT_SCRYPT = 0;
|
||||||
private static final byte PBKDF_FORMAT_SCRYPT_STRENGTHENED = 1;
|
private static final byte PBKDF_FORMAT_SCRYPT_STRENGTHENED = 1;
|
||||||
|
private static final byte ONION_HS_PROTOCOL_VERSION = 3;
|
||||||
|
private static final int ONION_CHECKSUM_BYTES = 2;
|
||||||
|
|
||||||
private final SecureRandom secureRandom;
|
private final SecureRandom secureRandom;
|
||||||
private final PasswordBasedKdf passwordBasedKdf;
|
private final PasswordBasedKdf passwordBasedKdf;
|
||||||
@@ -442,4 +447,21 @@ class CryptoComponentImpl implements CryptoComponent {
|
|||||||
public String asciiArmour(byte[] b, int lineLength) {
|
public String asciiArmour(byte[] b, int lineLength) {
|
||||||
return AsciiArmour.wrap(b, lineLength);
|
return AsciiArmour.wrap(b, lineLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String encodeOnionAddress(byte[] publicKey) {
|
||||||
|
Digest digest = new SHA3Digest(256);
|
||||||
|
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
|
||||||
|
digest.update(label, 0, label.length);
|
||||||
|
digest.update(publicKey, 0, publicKey.length);
|
||||||
|
digest.update(ONION_HS_PROTOCOL_VERSION);
|
||||||
|
byte[] checksum = new byte[digest.getDigestSize()];
|
||||||
|
digest.doFinal(checksum, 0);
|
||||||
|
byte[] address = new byte[publicKey.length + ONION_CHECKSUM_BYTES + 1];
|
||||||
|
arraycopy(publicKey, 0, address, 0, publicKey.length);
|
||||||
|
arraycopy(checksum, 0, address, publicKey.length, ONION_CHECKSUM_BYTES);
|
||||||
|
address[address.length - 1] = ONION_HS_PROTOCOL_VERSION;
|
||||||
|
return Base32.encode(address).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,39 +4,26 @@ import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
|
|||||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
||||||
|
|
||||||
import org.bouncycastle.crypto.Digest;
|
|
||||||
import org.bouncycastle.crypto.digests.SHA3Digest;
|
|
||||||
import org.bouncycastle.util.encoders.Base64;
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
import org.briarproject.bramble.util.Base32;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
||||||
|
|
||||||
public class TorRendezvousCryptoImpl implements TorRendezvousCrypto {
|
|
||||||
|
|
||||||
private static final EdDSANamedCurveSpec CURVE_SPEC =
|
private static final EdDSANamedCurveSpec CURVE_SPEC =
|
||||||
EdDSANamedCurveTable.getByName("Ed25519");
|
EdDSANamedCurveTable.getByName("Ed25519");
|
||||||
|
|
||||||
private static final byte HS_PROTOCOL_VERSION = 3;
|
private final CryptoComponent crypto;
|
||||||
private static final int CHECKSUM_BYTES = 2;
|
|
||||||
|
TorRendezvousCryptoImpl(CryptoComponent crypto) {
|
||||||
|
this.crypto = crypto;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOnionAddress(byte[] seed) {
|
public String getOnionAddress(byte[] seed) {
|
||||||
EdDSAPrivateKeySpec spec = new EdDSAPrivateKeySpec(seed, CURVE_SPEC);
|
EdDSAPrivateKeySpec spec = new EdDSAPrivateKeySpec(seed, CURVE_SPEC);
|
||||||
byte[] publicKey = spec.getA().toByteArray();
|
return crypto.encodeOnionAddress(spec.getA().toByteArray());
|
||||||
Digest digest = new SHA3Digest(256);
|
|
||||||
byte[] label = ".onion checksum".getBytes(Charset.forName("US-ASCII"));
|
|
||||||
digest.update(label, 0, label.length);
|
|
||||||
digest.update(publicKey, 0, publicKey.length);
|
|
||||||
digest.update(HS_PROTOCOL_VERSION);
|
|
||||||
byte[] checksum = new byte[digest.getDigestSize()];
|
|
||||||
digest.doFinal(checksum, 0);
|
|
||||||
byte[] address = new byte[publicKey.length + CHECKSUM_BYTES + 1];
|
|
||||||
arraycopy(publicKey, 0, address, 0, publicKey.length);
|
|
||||||
arraycopy(checksum, 0, address, publicKey.length, CHECKSUM_BYTES);
|
|
||||||
address[address.length - 1] = HS_PROTOCOL_VERSION;
|
|
||||||
return Base32.encode(address).toLowerCase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.plugin.tor;
|
package org.briarproject.bramble.plugin.tor;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
@@ -58,6 +59,7 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
private final File torDirectory;
|
private final File torDirectory;
|
||||||
private int torSocksPort;
|
private int torSocksPort;
|
||||||
private int torControlPort;
|
private int torControlPort;
|
||||||
|
private final CryptoComponent crypto;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
UnixTorPluginFactory(@IoExecutor Executor ioExecutor,
|
UnixTorPluginFactory(@IoExecutor Executor ioExecutor,
|
||||||
@@ -73,7 +75,8 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
Clock clock,
|
Clock clock,
|
||||||
@TorDirectory File torDirectory,
|
@TorDirectory File torDirectory,
|
||||||
@TorSocksPort int torSocksPort,
|
@TorSocksPort int torSocksPort,
|
||||||
@TorControlPort int torControlPort) {
|
@TorControlPort int torControlPort,
|
||||||
|
CryptoComponent crypto) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.wakefulIoExecutor = wakefulIoExecutor;
|
this.wakefulIoExecutor = wakefulIoExecutor;
|
||||||
this.networkManager = networkManager;
|
this.networkManager = networkManager;
|
||||||
@@ -88,6 +91,7 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
this.torDirectory = torDirectory;
|
this.torDirectory = torDirectory;
|
||||||
this.torSocksPort = torSocksPort;
|
this.torSocksPort = torSocksPort;
|
||||||
this.torControlPort = torControlPort;
|
this.torControlPort = torControlPort;
|
||||||
|
this.crypto = crypto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -128,7 +132,8 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
|
||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||||
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();
|
TorRendezvousCrypto torRendezvousCrypto =
|
||||||
|
new TorRendezvousCryptoImpl(crypto);
|
||||||
UnixTorPlugin plugin = new UnixTorPlugin(ioExecutor, wakefulIoExecutor,
|
UnixTorPlugin plugin = new UnixTorPlugin(ioExecutor, wakefulIoExecutor,
|
||||||
networkManager, locationUtils, torSocketFactory, clock,
|
networkManager, locationUtils, torSocketFactory, clock,
|
||||||
resourceProvider, circumventionProvider, batteryManager,
|
resourceProvider, circumventionProvider, batteryManager,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.plugin.tor;
|
|||||||
|
|
||||||
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
|
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
@@ -88,6 +89,8 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
BackoffFactory backoffFactory;
|
BackoffFactory backoffFactory;
|
||||||
@Inject
|
@Inject
|
||||||
Clock clock;
|
Clock clock;
|
||||||
|
@Inject
|
||||||
|
CryptoComponent crypto;
|
||||||
|
|
||||||
private final File torDir = getTestDirectory();
|
private final File torDir = getTestDirectory();
|
||||||
private final String bridge;
|
private final String bridge;
|
||||||
@@ -142,7 +145,7 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
networkManager, locationUtils, eventBus, torSocketFactory,
|
networkManager, locationUtils, eventBus, torSocketFactory,
|
||||||
backoffFactory, resourceProvider, bridgeProvider,
|
backoffFactory, resourceProvider, bridgeProvider,
|
||||||
batteryManager, clock, torDir, DEFAULT_SOCKS_PORT,
|
batteryManager, clock, torDir, DEFAULT_SOCKS_PORT,
|
||||||
DEFAULT_CONTROL_PORT);
|
DEFAULT_CONTROL_PORT, crypto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import org.briarproject.briar.android.hotspot.HotspotModule;
|
|||||||
import org.briarproject.briar.android.introduction.IntroductionModule;
|
import org.briarproject.briar.android.introduction.IntroductionModule;
|
||||||
import org.briarproject.briar.android.logging.LoggingModule;
|
import org.briarproject.briar.android.logging.LoggingModule;
|
||||||
import org.briarproject.briar.android.login.LoginModule;
|
import org.briarproject.briar.android.login.LoginModule;
|
||||||
|
import org.briarproject.briar.android.mailbox.MailboxModule;
|
||||||
import org.briarproject.briar.android.navdrawer.NavDrawerModule;
|
import org.briarproject.briar.android.navdrawer.NavDrawerModule;
|
||||||
import org.briarproject.briar.android.privategroup.conversation.GroupConversationModule;
|
import org.briarproject.briar.android.privategroup.conversation.GroupConversationModule;
|
||||||
import org.briarproject.briar.android.privategroup.list.GroupListModule;
|
import org.briarproject.briar.android.privategroup.list.GroupListModule;
|
||||||
@@ -103,6 +104,7 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
|||||||
SharingModule.class,
|
SharingModule.class,
|
||||||
HotspotModule.class,
|
HotspotModule.class,
|
||||||
TransferDataModule.class,
|
TransferDataModule.class,
|
||||||
|
MailboxModule.class,
|
||||||
})
|
})
|
||||||
public class AppModule {
|
public class AppModule {
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgre
|
|||||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.QrCodeScanned;
|
import org.briarproject.briar.android.contact.add.nearby.AddContactState.QrCodeScanned;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.briar.android.qrcode.CameraException;
|
||||||
|
import org.briarproject.briar.android.qrcode.CameraView;
|
||||||
import org.briarproject.briar.android.view.QrCodeView;
|
import org.briarproject.briar.android.view.QrCodeView;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ import org.briarproject.briar.android.contact.add.nearby.AddContactState.Contact
|
|||||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementListening;
|
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementListening;
|
||||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementStarted;
|
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementStarted;
|
||||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||||
import org.briarproject.briar.android.util.QrCodeUtils;
|
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||||
|
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.briarproject.bramble.api.settings.SettingsManager;
|
|||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.hotspot.HotspotState.NetworkConfig;
|
import org.briarproject.briar.android.hotspot.HotspotState.NetworkConfig;
|
||||||
import org.briarproject.briar.android.util.QrCodeUtils;
|
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -52,7 +52,7 @@ import static java.util.Objects.requireNonNull;
|
|||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.briar.android.util.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
import static org.briarproject.briar.android.qrcode.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.handleException;
|
import static org.briarproject.briar.android.util.UiUtils.handleException;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.android.hotspot.HotspotState.WebsiteConfig;
|
import org.briarproject.briar.android.hotspot.HotspotState.WebsiteConfig;
|
||||||
import org.briarproject.briar.android.util.QrCodeUtils;
|
import org.briarproject.briar.android.qrcode.QrCodeUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
@@ -27,7 +27,7 @@ import static java.util.logging.Logger.getLogger;
|
|||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.NetworkUtils.getNetworkInterfaces;
|
import static org.briarproject.bramble.util.NetworkUtils.getNetworkInterfaces;
|
||||||
import static org.briarproject.briar.android.hotspot.WebServer.PORT;
|
import static org.briarproject.briar.android.hotspot.WebServer.PORT;
|
||||||
import static org.briarproject.briar.android.util.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
import static org.briarproject.briar.android.qrcode.QrCodeUtils.HOTSPOT_QRCODE_FACTOR;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
|
import org.briarproject.briar.android.viewmodel.ViewModelKey;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
import dagger.Binds;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.multibindings.IntoMap;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
public interface MailboxModule {
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(MailboxPairViewModel.class)
|
||||||
|
ViewModel bindMailboxViewModel(
|
||||||
|
MailboxPairViewModel mailboxPairViewModel);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||||
|
import org.briarproject.briar.android.viewmodel.DbViewModel;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
class MailboxPairViewModel extends DbViewModel
|
||||||
|
implements QrCodeDecoder.ResultCallback {
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(MailboxPairViewModel.class.getName());
|
||||||
|
|
||||||
|
private static final int VERSION_REQUIRED = 32;
|
||||||
|
|
||||||
|
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||||
|
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||||
|
|
||||||
|
private final CryptoComponent crypto;
|
||||||
|
private final QrCodeDecoder qrCodeDecoder;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private String onionAddress = null;
|
||||||
|
@Nullable
|
||||||
|
private String setupToken = null;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MailboxPairViewModel(
|
||||||
|
Application app,
|
||||||
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
|
LifecycleManager lifecycleManager,
|
||||||
|
TransactionManager db,
|
||||||
|
AndroidExecutor androidExecutor,
|
||||||
|
@IoExecutor Executor ioExecutor,
|
||||||
|
CryptoComponent crypto) {
|
||||||
|
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||||
|
this.crypto = crypto;
|
||||||
|
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onQrCodeDecoded(Result result) {
|
||||||
|
LOG.info("Got result from decoder");
|
||||||
|
byte[] bytes = result.getText().getBytes(ISO_8859_1);
|
||||||
|
|
||||||
|
if (LOG.isLoggable(INFO))
|
||||||
|
LOG.info("QR code length in bytes: " + bytes.length);
|
||||||
|
if (bytes.length != 65) {
|
||||||
|
LOG.info("QR code has wrong length");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG.isLoggable(INFO))
|
||||||
|
LOG.info("QR code version: " + bytes[0]);
|
||||||
|
if (bytes[0] != VERSION_REQUIRED) {
|
||||||
|
LOG.info("QR code has wrong version");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] onionPubKey = Arrays.copyOfRange(bytes, 1, 33);
|
||||||
|
onionAddress = crypto.encodeOnionAddress(onionPubKey);
|
||||||
|
setupToken = StringUtils.toHexString(Arrays.copyOfRange(bytes, 33, 65))
|
||||||
|
.toLowerCase();
|
||||||
|
LOG.info("QR code is valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
QrCodeDecoder getQrCodeDecoder() {
|
||||||
|
return qrCodeDecoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.briarproject.briar.android.contact.add.nearby;
|
package org.briarproject.briar.android.qrcode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
class CameraException extends IOException {
|
public class CameraException extends IOException {
|
||||||
|
|
||||||
CameraException(String message) {
|
CameraException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.contact.add.nearby;
|
package org.briarproject.briar.android.qrcode;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.contact.add.nearby;
|
package org.briarproject.briar.android.qrcode;
|
||||||
|
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
interface PreviewConsumer {
|
public interface PreviewConsumer {
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void start(Camera camera, int cameraIndex);
|
void start(Camera camera, int cameraIndex);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.contact.add.nearby;
|
package org.briarproject.briar.android.qrcode;
|
||||||
|
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.hardware.Camera.CameraInfo;
|
import android.hardware.Camera.CameraInfo;
|
||||||
@@ -32,7 +32,7 @@ import static java.util.logging.Logger.getLogger;
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(QrCodeDecoder.class.getName());
|
private static final Logger LOG = getLogger(QrCodeDecoder.class.getName());
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
|||||||
private Camera camera = null;
|
private Camera camera = null;
|
||||||
private int cameraIndex = 0;
|
private int cameraIndex = 0;
|
||||||
|
|
||||||
QrCodeDecoder(AndroidExecutor androidExecutor,
|
public QrCodeDecoder(AndroidExecutor androidExecutor,
|
||||||
@IoExecutor Executor ioExecutor, ResultCallback callback) {
|
@IoExecutor Executor ioExecutor, ResultCallback callback) {
|
||||||
this.androidExecutor = androidExecutor;
|
this.androidExecutor = androidExecutor;
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
@@ -127,7 +127,7 @@ class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
interface ResultCallback {
|
public interface ResultCallback {
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
void onQrCodeDecoded(Result result);
|
void onQrCodeDecoded(Result result);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.util;
|
package org.briarproject.briar.android.qrcode;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
@@ -23,11 +23,10 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class QrCodeUtils {
|
public class QrCodeUtils {
|
||||||
|
public static final double HOTSPOT_QRCODE_FACTOR = 0.35;
|
||||||
|
|
||||||
private static final Logger LOG = getLogger(QrCodeUtils.class.getName());
|
private static final Logger LOG = getLogger(QrCodeUtils.class.getName());
|
||||||
|
|
||||||
public static final double HOTSPOT_QRCODE_FACTOR = 0.35;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Bitmap createQrCode(DisplayMetrics dm, String input) {
|
public static Bitmap createQrCode(DisplayMetrics dm, String input) {
|
||||||
return createQrCode(Math.min(dm.widthPixels, dm.heightPixels), input);
|
return createQrCode(Math.min(dm.widthPixels, dm.heightPixels), input);
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:keepScreenOn="true">
|
android:keepScreenOn="true">
|
||||||
|
|
||||||
<org.briarproject.briar.android.contact.add.nearby.CameraView
|
<org.briarproject.briar.android.qrcode.CameraView
|
||||||
android:id="@+id/camera_view"
|
android:id="@+id/camera_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
Reference in New Issue
Block a user