mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 21:29:54 +01:00
Factor out onion address encoder to CryptoComponent
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;
|
|
||||||
|
|
||||||
public 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
|
||||||
|
|||||||
Reference in New Issue
Block a user