From 61276c81d23793ad5a580304b60e12986ce2637c Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 23 Nov 2018 12:52:40 +0000 Subject: [PATCH] Make it possible to start the headless app on MacOS. The app is still non-functional because we don't have a Tor plugin. --- .../system/AndroidSecureRandomProvider.java | 22 ++++++---- ...der.java => UnixSecureRandomProvider.java} | 19 +++++---- ...andomSpi.java => UnixSecureRandomSpi.java} | 10 +++-- ...java => UnixSecureRandomProviderTest.java} | 25 ++++++----- ...Test.java => UnixSecureRandomSpiTest.java} | 42 +++++++------------ .../system/DesktopSecureRandomModule.java | 5 ++- .../briar/headless/HeadlessModule.kt | 17 +++++--- 7 files changed, 72 insertions(+), 68 deletions(-) rename bramble-core/src/main/java/org/briarproject/bramble/system/{LinuxSecureRandomProvider.java => UnixSecureRandomProvider.java} (76%) rename bramble-core/src/main/java/org/briarproject/bramble/system/{LinuxSecureRandomSpi.java => UnixSecureRandomSpi.java} (83%) rename bramble-core/src/test/java/org/briarproject/bramble/system/{LinuxSecureRandomProviderTest.java => UnixSecureRandomProviderTest.java} (64%) rename bramble-core/src/test/java/org/briarproject/bramble/system/{LinuxSecureRandomSpiTest.java => UnixSecureRandomSpiTest.java} (74%) diff --git a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSecureRandomProvider.java b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSecureRandomProvider.java index 3779a16e8..0403ff99b 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSecureRandomProvider.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidSecureRandomProvider.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.system; +import android.annotation.SuppressLint; import android.app.Application; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -26,7 +27,7 @@ import static android.provider.Settings.Secure.ANDROID_ID; @Immutable @NotNullByDefault -class AndroidSecureRandomProvider extends LinuxSecureRandomProvider { +class AndroidSecureRandomProvider extends UnixSecureRandomProvider { private static final int SEED_LENGTH = 32; @@ -37,6 +38,7 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider { appContext = app.getApplicationContext(); } + @SuppressLint("HardwareIds") @Override protected void writeToEntropyPool(DataOutputStream out) throws IOException { super.writeToEntropyPool(out); @@ -49,12 +51,14 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider { String id = Settings.Secure.getString(contentResolver, ANDROID_ID); if (id != null) out.writeUTF(id); Parcel parcel = Parcel.obtain(); - WifiManager wm = - (WifiManager) appContext.getSystemService(WIFI_SERVICE); - List configs = wm.getConfiguredNetworks(); - if (configs != null) { - for (WifiConfiguration config : configs) - parcel.writeParcelable(config, 0); + WifiManager wm = (WifiManager) appContext.getApplicationContext() + .getSystemService(WIFI_SERVICE); + if (wm != null) { + List configs = wm.getConfiguredNetworks(); + if (configs != null) { + for (WifiConfiguration config : configs) + parcel.writeParcelable(config, 0); + } } BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); if (bt != null) { @@ -77,13 +81,13 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider { // Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html private void applyOpenSslFix() { - byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed( + byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed( SEED_LENGTH); try { // Seed the OpenSSL PRNG Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") .getMethod("RAND_seed", byte[].class) - .invoke(null, seed); + .invoke(null, (Object) seed); // Mix the output of the Linux PRNG into the OpenSSL PRNG int bytesRead = (Integer) Class.forName( "org.apache.harmony.xnet.provider.jsse.NativeCrypto") diff --git a/bramble-core/src/main/java/org/briarproject/bramble/system/LinuxSecureRandomProvider.java b/bramble-core/src/main/java/org/briarproject/bramble/system/UnixSecureRandomProvider.java similarity index 76% rename from bramble-core/src/main/java/org/briarproject/bramble/system/LinuxSecureRandomProvider.java rename to bramble-core/src/main/java/org/briarproject/bramble/system/UnixSecureRandomProvider.java index dd55fa5e9..a992b955c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/system/LinuxSecureRandomProvider.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/system/UnixSecureRandomProvider.java @@ -13,32 +13,33 @@ import java.util.logging.Logger; import javax.annotation.concurrent.Immutable; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException; @Immutable @NotNullByDefault -class LinuxSecureRandomProvider extends AbstractSecureRandomProvider { +class UnixSecureRandomProvider extends AbstractSecureRandomProvider { private static final Logger LOG = - Logger.getLogger(LinuxSecureRandomProvider.class.getName()); + getLogger(UnixSecureRandomProvider.class.getName()); private static final File RANDOM_DEVICE = new File("/dev/urandom"); private final AtomicBoolean seeded = new AtomicBoolean(false); private final File outputDevice; - LinuxSecureRandomProvider() { + UnixSecureRandomProvider() { this(RANDOM_DEVICE); } - LinuxSecureRandomProvider(File outputDevice) { + UnixSecureRandomProvider(File outputDevice) { this.outputDevice = outputDevice; } @Override public Provider getProvider() { if (!seeded.getAndSet(true)) writeSeed(); - return new LinuxProvider(); + return new UnixProvider(); } protected void writeSeed() { @@ -55,15 +56,15 @@ class LinuxSecureRandomProvider extends AbstractSecureRandomProvider { } // Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html - private static class LinuxProvider extends Provider { + private static class UnixProvider extends Provider { - private LinuxProvider() { - super("LinuxPRNG", 1.1, "A Linux-specific PRNG using /dev/urandom"); + private UnixProvider() { + super("UnixPRNG", 1.0, "A Unix-specific PRNG using /dev/urandom"); // Although /dev/urandom is not a SHA-1 PRNG, some callers // explicitly request a SHA1PRNG SecureRandom and we need to // prevent them from getting the default implementation whose // output may have low entropy. - put("SecureRandom.SHA1PRNG", LinuxSecureRandomSpi.class.getName()); + put("SecureRandom.SHA1PRNG", UnixSecureRandomSpi.class.getName()); put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/system/LinuxSecureRandomSpi.java b/bramble-core/src/main/java/org/briarproject/bramble/system/UnixSecureRandomSpi.java similarity index 83% rename from bramble-core/src/main/java/org/briarproject/bramble/system/LinuxSecureRandomSpi.java rename to bramble-core/src/main/java/org/briarproject/bramble/system/UnixSecureRandomSpi.java index 511afd27a..066598d9c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/system/LinuxSecureRandomSpi.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/system/UnixSecureRandomSpi.java @@ -10,22 +10,24 @@ import java.security.SecureRandomSpi; import java.util.logging.Logger; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException; -public class LinuxSecureRandomSpi extends SecureRandomSpi { +public class UnixSecureRandomSpi extends SecureRandomSpi { private static final Logger LOG = - Logger.getLogger(LinuxSecureRandomSpi.class.getName()); + getLogger(UnixSecureRandomSpi.class.getName()); private static final File RANDOM_DEVICE = new File("/dev/urandom"); private final File inputDevice, outputDevice; - public LinuxSecureRandomSpi() { + @SuppressWarnings("WeakerAccess") + public UnixSecureRandomSpi() { this(RANDOM_DEVICE, RANDOM_DEVICE); } - LinuxSecureRandomSpi(File inputDevice, File outputDevice) { + UnixSecureRandomSpi(File inputDevice, File outputDevice) { this.inputDevice = inputDevice; this.outputDevice = outputDevice; } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomProviderTest.java b/bramble-core/src/test/java/org/briarproject/bramble/system/UnixSecureRandomProviderTest.java similarity index 64% rename from bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomProviderTest.java rename to bramble-core/src/test/java/org/briarproject/bramble/system/UnixSecureRandomProviderTest.java index 8c4190ac9..a200d9a63 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomProviderTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/system/UnixSecureRandomProviderTest.java @@ -1,7 +1,6 @@ package org.briarproject.bramble.system; import org.briarproject.bramble.test.BrambleTestCase; -import org.briarproject.bramble.test.TestUtils; import org.briarproject.bramble.util.OsUtils; import org.junit.After; import org.junit.Before; @@ -10,48 +9,48 @@ import org.junit.Test; import java.io.File; import java.security.Provider; +import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; +import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; -public class LinuxSecureRandomProviderTest extends BrambleTestCase { +public class UnixSecureRandomProviderTest extends BrambleTestCase { - private final File testDir = TestUtils.getTestDirectory(); + private final File testDir = getTestDirectory(); @Before public void setUp() { - testDir.mkdirs(); + assumeTrue(OsUtils.isLinux() || OsUtils.isMac()); + assertTrue(testDir.mkdirs()); } @Test public void testGetProviderWritesToRandomDeviceOnFirstCall() throws Exception { - if (!(OsUtils.isLinux())) { - System.err.println("WARNING: Skipping test, can't run on this OS"); - return; - } // Redirect the provider's output to a file File urandom = new File(testDir, "urandom"); - urandom.delete(); + if (urandom.exists()) assertTrue(urandom.delete()); assertTrue(urandom.createNewFile()); assertEquals(0, urandom.length()); - LinuxSecureRandomProvider p = new LinuxSecureRandomProvider(urandom); + UnixSecureRandomProvider p = new UnixSecureRandomProvider(urandom); // Getting a provider should write entropy to the file Provider provider = p.getProvider(); assertNotNull(provider); - assertEquals("LinuxPRNG", provider.getName()); + assertEquals("UnixPRNG", provider.getName()); // There should be at least 16 bytes from the clock, 8 from the runtime long length = urandom.length(); assertTrue(length >= 24); // Getting another provider should not write to the file again provider = p.getProvider(); assertNotNull(provider); - assertEquals("LinuxPRNG", provider.getName()); + assertEquals("UnixPRNG", provider.getName()); assertEquals(length, urandom.length()); } @After public void tearDown() { - TestUtils.deleteTestDirectory(testDir); + deleteTestDirectory(testDir); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java b/bramble-core/src/test/java/org/briarproject/bramble/system/UnixSecureRandomSpiTest.java similarity index 74% rename from bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java rename to bramble-core/src/test/java/org/briarproject/bramble/system/UnixSecureRandomSpiTest.java index 3d48b647a..b31138bc1 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/system/LinuxSecureRandomSpiTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/system/UnixSecureRandomSpiTest.java @@ -15,31 +15,31 @@ import java.io.FileOutputStream; import java.util.HashSet; import java.util.Set; +import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; +import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; -public class LinuxSecureRandomSpiTest extends BrambleTestCase { +public class UnixSecureRandomSpiTest extends BrambleTestCase { private static final File RANDOM_DEVICE = new File("/dev/urandom"); private static final int SEED_BYTES = 32; - private final File testDir = TestUtils.getTestDirectory(); + private final File testDir = getTestDirectory(); @Before public void setUp() { - testDir.mkdirs(); + assumeTrue(OsUtils.isLinux() || OsUtils.isMac()); + assertTrue(testDir.mkdirs()); } @Test public void testSeedsAreDistinct() { - if (!(OsUtils.isLinux())) { - System.err.println("WARNING: Skipping test, can't run on this OS"); - return; - } Set seeds = new HashSet<>(); - LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(); + UnixSecureRandomSpi engine = new UnixSecureRandomSpi(); for (int i = 0; i < 1000; i++) { byte[] seed = engine.engineGenerateSeed(SEED_BYTES); assertEquals(SEED_BYTES, seed.length); @@ -49,19 +49,15 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase { @Test public void testEngineSetSeedWritesToRandomDevice() throws Exception { - if (!(OsUtils.isLinux())) { - System.err.println("WARNING: Skipping test, can't run on this OS"); - return; - } // Redirect the engine's output to a file File urandom = new File(testDir, "urandom"); - urandom.delete(); + if (urandom.exists()) assertTrue(urandom.delete()); assertTrue(urandom.createNewFile()); assertEquals(0, urandom.length()); // Generate a seed byte[] seed = TestUtils.getRandomBytes(SEED_BYTES); // Check that the engine writes the seed to the file - LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(RANDOM_DEVICE, + UnixSecureRandomSpi engine = new UnixSecureRandomSpi(RANDOM_DEVICE, urandom); engine.engineSetSeed(seed); assertEquals(SEED_BYTES, urandom.length()); @@ -74,15 +70,11 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase { @Test public void testEngineNextBytesReadsFromRandomDevice() throws Exception { - if (!(OsUtils.isLinux())) { - System.err.println("WARNING: Skipping test, can't run on this OS"); - return; - } // Generate some entropy byte[] entropy = TestUtils.getRandomBytes(SEED_BYTES); // Write the entropy to a file File urandom = new File(testDir, "urandom"); - urandom.delete(); + if (urandom.exists()) assertTrue(urandom.delete()); FileOutputStream out = new FileOutputStream(urandom); out.write(entropy); out.flush(); @@ -90,7 +82,7 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase { assertTrue(urandom.exists()); assertEquals(SEED_BYTES, urandom.length()); // Check that the engine reads from the file - LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(urandom, + UnixSecureRandomSpi engine = new UnixSecureRandomSpi(urandom, RANDOM_DEVICE); byte[] b = new byte[SEED_BYTES]; engine.engineNextBytes(b); @@ -99,15 +91,11 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase { @Test public void testEngineGenerateSeedReadsFromRandomDevice() throws Exception { - if (!(OsUtils.isLinux())) { - System.err.println("WARNING: Skipping test, can't run on this OS"); - return; - } // Generate some entropy byte[] entropy = TestUtils.getRandomBytes(SEED_BYTES); // Write the entropy to a file File urandom = new File(testDir, "urandom"); - urandom.delete(); + if (urandom.exists()) assertTrue(urandom.delete()); FileOutputStream out = new FileOutputStream(urandom); out.write(entropy); out.flush(); @@ -115,7 +103,7 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase { assertTrue(urandom.exists()); assertEquals(SEED_BYTES, urandom.length()); // Check that the engine reads from the file - LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(urandom, + UnixSecureRandomSpi engine = new UnixSecureRandomSpi(urandom, RANDOM_DEVICE); byte[] b = engine.engineGenerateSeed(SEED_BYTES); assertArrayEquals(entropy, b); @@ -123,6 +111,6 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase { @After public void tearDown() { - TestUtils.deleteTestDirectory(testDir); + deleteTestDirectory(testDir); } } diff --git a/bramble-java/src/main/java/org/briarproject/bramble/system/DesktopSecureRandomModule.java b/bramble-java/src/main/java/org/briarproject/bramble/system/DesktopSecureRandomModule.java index 65246870c..14e093287 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/system/DesktopSecureRandomModule.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/system/DesktopSecureRandomModule.java @@ -14,6 +14,9 @@ public class DesktopSecureRandomModule { @Provides @Singleton SecureRandomProvider provideSecureRandomProvider() { - return OsUtils.isLinux() ? new LinuxSecureRandomProvider() : null; + if (OsUtils.isLinux() || OsUtils.isMac()) + return new UnixSecureRandomProvider(); + // TODO: Create a secure random provider for Windows + throw new UnsupportedOperationException(); } } diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt index f9d3c00db..dea73be0f 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/HeadlessModule.kt @@ -26,6 +26,7 @@ import org.briarproject.bramble.plugin.tor.CircumventionModule import org.briarproject.bramble.plugin.tor.CircumventionProvider import org.briarproject.bramble.plugin.tor.LinuxTorPluginFactory import org.briarproject.bramble.system.JavaSystemModule +import org.briarproject.bramble.util.OsUtils import org.briarproject.bramble.util.StringUtils.fromHexString import org.briarproject.briar.headless.blogs.HeadlessBlogModule import org.briarproject.briar.headless.contact.HeadlessContactModule @@ -70,11 +71,17 @@ internal class HeadlessModule(private val appDir: File) { circumventionProvider: CircumventionProvider, batteryManager: BatteryManager, clock: Clock ): PluginConfig { val torDirectory = File(appDir, "tor") - val tor = LinuxTorPluginFactory( - ioExecutor, networkManager, locationUtils, eventBus, torSocketFactory, backoffFactory, - resourceProvider, circumventionProvider, batteryManager, clock, torDirectory - ) - val duplex = listOf(tor) + val duplex: List + if (OsUtils.isLinux()) { + val tor = LinuxTorPluginFactory( + ioExecutor, networkManager, locationUtils, eventBus, + torSocketFactory, backoffFactory, resourceProvider, circumventionProvider, + batteryManager, clock, torDirectory + ) + duplex = listOf(tor) + } else { + duplex = emptyList() + } return object : PluginConfig { override fun getDuplexFactories(): Collection { return duplex