diff --git a/common/src/main/java/io/bisq/common/util/Utilities.java b/common/src/main/java/io/bisq/common/util/Utilities.java index ecb4ecfaae..14ed7ff09a 100644 --- a/common/src/main/java/io/bisq/common/util/Utilities.java +++ b/common/src/main/java/io/bisq/common/util/Utilities.java @@ -31,10 +31,15 @@ import org.bitcoinj.core.Utils; import javax.annotation.Nullable; import javax.crypto.Cipher; import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.net.URI; import java.security.NoSuchAlgorithmException; +import java.security.Permission; +import java.security.PermissionCollection; import java.util.Collection; import java.util.Locale; +import java.util.Map; import java.util.Random; import java.util.concurrent.*; import java.util.stream.Collectors; @@ -450,4 +455,54 @@ public class Utilities { public static String collectionToCSV(Collection collection) { return collection.stream().map(Object::toString).collect(Collectors.joining(",")).toString(); } + + public static void removeCryptographyRestrictions() { + if (!isRestrictedCryptography()) { + System.out.println("Cryptography restrictions removal not needed"); + return; + } + try { + /* + * Do the following, but with reflection to bypass access checks: + * + * JceSecurity.isRestricted = false; + * JceSecurity.defaultPolicy.perms.clear(); + * JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE); + */ + final Class jceSecurity = Class.forName("javax.crypto.JceSecurity"); + final Class cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions"); + final Class cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission"); + + final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted"); + isRestrictedField.setAccessible(true); + final Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL); + isRestrictedField.set(null, false); + + final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy"); + defaultPolicyField.setAccessible(true); + final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null); + + final Field perms = cryptoPermissions.getDeclaredField("perms"); + perms.setAccessible(true); + ((Map) perms.get(defaultPolicy)).clear(); + + final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE"); + instance.setAccessible(true); + defaultPolicy.add((Permission) instance.get(null)); + + System.out.println("Successfully removed cryptography restrictions"); + } catch (final Exception e) { + System.err.println("Failed to remove cryptography restrictions" + e); + } + } + + public static boolean isRestrictedCryptography() { + // This matches Oracle Java 7 and 8, but not Java 9 or OpenJDK. + final String name = System.getProperty("java.runtime.name"); + final String ver = System.getProperty("java.version"); + return name != null && name.equals("Java(TM) SE Runtime Environment") + && ver != null && (ver.startsWith("1.7") || ver.startsWith("1.8")); + } } diff --git a/gui/src/main/java/io/bisq/gui/app/BisqAppMain.java b/gui/src/main/java/io/bisq/gui/app/BisqAppMain.java index 038a3e81b2..5adde95d79 100644 --- a/gui/src/main/java/io/bisq/gui/app/BisqAppMain.java +++ b/gui/src/main/java/io/bisq/gui/app/BisqAppMain.java @@ -17,6 +17,7 @@ package io.bisq.gui.app; +import io.bisq.common.util.Utilities; import io.bisq.core.app.AppOptionKeys; import io.bisq.core.app.BisqEnvironment; import io.bisq.core.app.BisqExecutable; @@ -24,12 +25,7 @@ import joptsimple.OptionException; import joptsimple.OptionParser; import joptsimple.OptionSet; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.security.Permission; -import java.security.PermissionCollection; import java.util.Locale; -import java.util.Map; import static io.bisq.core.app.BisqEnvironment.DEFAULT_APP_NAME; import static io.bisq.core.app.BisqEnvironment.DEFAULT_USER_DATA_DIR; @@ -39,8 +35,8 @@ public class BisqAppMain extends BisqExecutable { static { // Need to set default locale initially otherwise we get problems at non-english OS Locale.setDefault(new Locale("en", Locale.getDefault().getCountry())); - - removeCryptographyRestrictions(); + + Utilities.removeCryptographyRestrictions(); } public static void main(String[] args) throws Exception { @@ -79,55 +75,4 @@ public class BisqAppMain extends BisqExecutable { BisqApp.setEnvironment(getBisqEnvironment(options)); javafx.application.Application.launch(BisqApp.class); } - - private static void removeCryptographyRestrictions() { - if (!isRestrictedCryptography()) { - System.out.println("Cryptography restrictions removal not needed"); - return; - } - try { - /* - * Do the following, but with reflection to bypass access checks: - * - * JceSecurity.isRestricted = false; - * JceSecurity.defaultPolicy.perms.clear(); - * JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE); - */ - final Class jceSecurity = Class.forName("javax.crypto.JceSecurity"); - final Class cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions"); - final Class cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission"); - - final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted"); - isRestrictedField.setAccessible(true); - final Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL); - isRestrictedField.set(null, false); - - final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy"); - defaultPolicyField.setAccessible(true); - final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null); - - final Field perms = cryptoPermissions.getDeclaredField("perms"); - perms.setAccessible(true); - ((Map) perms.get(defaultPolicy)).clear(); - - final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE"); - instance.setAccessible(true); - defaultPolicy.add((Permission) instance.get(null)); - - System.out.println("Successfully removed cryptography restrictions"); - } catch (final Exception e) { - System.err.println("Failed to remove cryptography restrictions" + e); - } - } - - private static boolean isRestrictedCryptography() { - // This matches Oracle Java 7 and 8, but not Java 9 or OpenJDK. - final String name = System.getProperty("java.runtime.name"); - final String ver = System.getProperty("java.version"); - return name != null && name.equals("Java(TM) SE Runtime Environment") - && ver != null && (ver.startsWith("1.7") || ver.startsWith("1.8")); - } - } diff --git a/provider/src/main/java/io/bisq/provider/ProviderMain.java b/provider/src/main/java/io/bisq/provider/ProviderMain.java index 86d13693f2..1456daa866 100644 --- a/provider/src/main/java/io/bisq/provider/ProviderMain.java +++ b/provider/src/main/java/io/bisq/provider/ProviderMain.java @@ -19,6 +19,7 @@ package io.bisq.provider; import ch.qos.logback.classic.Level; import io.bisq.common.app.Log; +import io.bisq.common.util.Utilities; import io.bisq.network.http.HttpException; import io.bisq.provider.fee.FeeRequestService; import io.bisq.provider.price.PriceRequestService; @@ -31,6 +32,7 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; +import java.util.Locale; import static spark.Spark.get; import static spark.Spark.port; @@ -38,7 +40,11 @@ import static spark.Spark.port; public class ProviderMain { private static final Logger log = LoggerFactory.getLogger(ProviderMain.class); - public ProviderMain() { + static { + // Need to set default locale initially otherwise we get problems at non-english OS + Locale.setDefault(new Locale("en", Locale.getDefault().getCountry())); + + Utilities.removeCryptographyRestrictions(); } public static void main(String[] args) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, HttpException { diff --git a/seednode/src/main/java/io/bisq/seednode/SeedNodeMain.java b/seednode/src/main/java/io/bisq/seednode/SeedNodeMain.java index 7142d2076f..389f22c0b9 100644 --- a/seednode/src/main/java/io/bisq/seednode/SeedNodeMain.java +++ b/seednode/src/main/java/io/bisq/seednode/SeedNodeMain.java @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.bisq.common.UserThread; import io.bisq.common.util.Profiler; import io.bisq.common.util.RestartUtil; +import io.bisq.common.util.Utilities; import io.bisq.core.app.AppOptionKeys; import io.bisq.core.app.BisqEnvironment; import io.bisq.core.app.BisqExecutable; @@ -33,6 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.util.Locale; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -47,6 +49,13 @@ public class SeedNodeMain extends BisqExecutable { private volatile boolean stopped; private static long maxMemory = MAX_MEMORY_MB_DEFAULT; + static { + // Need to set default locale initially otherwise we get problems at non-english OS + Locale.setDefault(new Locale("en", Locale.getDefault().getCountry())); + + Utilities.removeCryptographyRestrictions(); + } + public static void main(String[] args) throws Exception { final ThreadFactory threadFactory = new ThreadFactoryBuilder() .setNameFormat("SeedNodeMain") diff --git a/statistics/src/main/java/io/bisq/statistics/StatisticsMain.java b/statistics/src/main/java/io/bisq/statistics/StatisticsMain.java index 518a5094e9..339317ac6d 100644 --- a/statistics/src/main/java/io/bisq/statistics/StatisticsMain.java +++ b/statistics/src/main/java/io/bisq/statistics/StatisticsMain.java @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.bisq.common.UserThread; import io.bisq.common.util.Profiler; import io.bisq.common.util.RestartUtil; +import io.bisq.common.util.Utilities; import io.bisq.core.app.AppOptionKeys; import io.bisq.core.app.BisqEnvironment; import io.bisq.core.app.BisqExecutable; @@ -33,6 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.util.Locale; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -47,6 +49,13 @@ public class StatisticsMain extends BisqExecutable { private volatile boolean stopped; private static long maxMemory = MAX_MEMORY_MB_DEFAULT; + static { + // Need to set default locale initially otherwise we get problems at non-english OS + Locale.setDefault(new Locale("en", Locale.getDefault().getCountry())); + + Utilities.removeCryptographyRestrictions(); + } + public static void main(String[] args) throws Exception { final ThreadFactory threadFactory = new ThreadFactoryBuilder() .setNameFormat("Statistics")