Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java	(revision 7338)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java	(revision 7343)
@@ -21,8 +21,10 @@
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.SecureRandom;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
@@ -91,5 +93,5 @@
      * @since 7335
      */
-    public StringProperty KEYSTORE_PASSWORD = new StringProperty("remotecontrol.https.keystore.password", "");
+    public static final StringProperty KEYSTORE_PASSWORD = new StringProperty("remotecontrol.https.keystore.password", "");
 
     /**
@@ -97,5 +99,11 @@
      * @since 7335
      */
-    public StringProperty KEYENTRY_PASSWORD = new StringProperty("remotecontrol.https.keyentry.password", "");
+    public static final StringProperty KEYENTRY_PASSWORD = new StringProperty("remotecontrol.https.keyentry.password", "");
+
+    /**
+     * Unique alias used to store JOSM localhost entry, both in JOSM keystore and system/browser keystores.
+     * @since 7343
+     */
+    public static final String ENTRY_ALIAS = "josm_localhost";
 
     /**
@@ -194,79 +202,117 @@
     }
 
+    /**
+     * Setup the JOSM internal keystore, used to store HTTPS certificate and private key.
+     * @return Path to the (initialized) JOSM keystore
+     * @throws IOException if an I/O error occurs
+     * @throws GeneralSecurityException if a security error occurs
+     * @since 7343
+     */
+    public static Path setupJosmKeystore() throws IOException, GeneralSecurityException {
+
+        char[] storePassword = KEYSTORE_PASSWORD.get().toCharArray();
+        char[] entryPassword = KEYENTRY_PASSWORD.get().toCharArray();
+
+        Path dir = Paths.get(RemoteControl.getRemoteControlDir());
+        Path path = dir.resolve(KEYSTORE_FILENAME);
+        Files.createDirectories(dir);
+
+        if (!Files.exists(path)) {
+            Main.debug("No keystore found, creating a new one");
+
+            // Create new keystore like previous one generated with JDK keytool as follows:
+            // keytool -genkeypair -storepass josm_ssl -keypass josm_ssl -alias josm_localhost -dname "CN=localhost, OU=JOSM, O=OpenStreetMap"
+            // -ext san=ip:127.0.0.1 -keyalg RSA -validity 1825
+
+            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
+            generator.initialize(2048);
+            KeyPair pair = generator.generateKeyPair();
+
+            X509Certificate cert = generateCertificate("CN=localhost, OU=JOSM, O=OpenStreetMap", pair, 1825, "SHA256withRSA",
+                    "dns:localhost,ip:127.0.0.1,ip:::1,uri:https://127.0.0.1:"+HTTPS_PORT+",uri:https://::1:"+HTTPS_PORT);
+
+            KeyStore ks = KeyStore.getInstance("JKS");
+            ks.load(null, null);
+
+            // Generate new passwords. See https://stackoverflow.com/a/41156/2257172
+            SecureRandom random = new SecureRandom();
+            KEYSTORE_PASSWORD.put(new BigInteger(130, random).toString(32));
+            KEYENTRY_PASSWORD.put(new BigInteger(130, random).toString(32));
+
+            storePassword = KEYSTORE_PASSWORD.get().toCharArray();
+            entryPassword = KEYENTRY_PASSWORD.get().toCharArray();
+
+            ks.setKeyEntry(ENTRY_ALIAS, pair.getPrivate(), entryPassword, new Certificate[]{cert});
+            ks.store(Files.newOutputStream(path, StandardOpenOption.CREATE), storePassword);
+        }
+        return path;
+    }
+
+    /**
+     * Loads the JOSM keystore.
+     * @return the (initialized) JOSM keystore
+     * @throws IOException if an I/O error occurs
+     * @throws GeneralSecurityException if a security error occurs
+     * @since 7343
+     */
+    public static KeyStore loadJosmKeystore() throws IOException, GeneralSecurityException {
+        try (InputStream in = Files.newInputStream(setupJosmKeystore())) {
+            KeyStore ks = KeyStore.getInstance("JKS");
+            ks.load(in, KEYSTORE_PASSWORD.get().toCharArray());
+
+            if (Main.isDebugEnabled()) {
+                for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) {
+                    Main.debug("Alias in JOSM keystore: "+aliases.nextElement());
+                }
+            }
+            return ks;
+        }
+    }
+
     private void initialize() {
         if (!initOK) {
             try {
-                char[] storePassword = KEYSTORE_PASSWORD.get().toCharArray();
-                char[] entryPassword = KEYENTRY_PASSWORD.get().toCharArray();
-
-                Path dir = Paths.get(RemoteControl.getRemoteControlDir());
-                Path path = dir.resolve(KEYSTORE_FILENAME);
-                Files.createDirectories(dir);
-
-                if (!Files.exists(path)) {
-                    Main.debug("No keystore found, creating a new one");
-
-                    // Create new keystore like previous one generated with JDK keytool as follows:
-                    // keytool -genkeypair -storepass josm_ssl -keypass josm_ssl -alias josm_localhost -dname "CN=localhost, OU=JOSM, O=OpenStreetMap"
-                    // -ext san=ip:127.0.0.1 -keyalg RSA -validity 1825
-
-                    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
-                    generator.initialize(2048);
-                    KeyPair pair = generator.generateKeyPair();
-
-                    X509Certificate cert = generateCertificate("CN=localhost, OU=JOSM, O=OpenStreetMap", pair, 1825, "SHA256withRSA",
-                            "dns:localhost,ip:127.0.0.1,ip:::1,uri:https://127.0.0.1:"+HTTPS_PORT+",uri:https://::1:"+HTTPS_PORT);
-
-                    KeyStore ks = KeyStore.getInstance("JKS");
-                    ks.load(null, null);
-
-                    // Generate new passwords. See https://stackoverflow.com/a/41156/2257172
-                    SecureRandom random = new SecureRandom();
-                    KEYSTORE_PASSWORD.put(new BigInteger(130, random).toString(32));
-                    KEYENTRY_PASSWORD.put(new BigInteger(130, random).toString(32));
-
-                    storePassword = KEYSTORE_PASSWORD.get().toCharArray();
-                    entryPassword = KEYENTRY_PASSWORD.get().toCharArray();
-
-                    ks.setKeyEntry("josm_localhost", pair.getPrivate(), entryPassword, new Certificate[]{cert});
-                    ks.store(Files.newOutputStream(path, StandardOpenOption.CREATE), storePassword);
-                }
-
-                try (InputStream in = Files.newInputStream(path)) {
-                    // Load keystore
-                    KeyStore ks = KeyStore.getInstance("JKS");
-                    ks.load(in, storePassword);
-
-                    if (Main.isDebugEnabled()) {
-                        for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) {
-                            Main.debug("Alias in keystore: "+aliases.nextElement());
-                        }
-                    }
-
-                    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
-                    kmf.init(ks, entryPassword);
-
-                    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
-                    tmf.init(ks);
-
-                    sslContext = SSLContext.getInstance("TLS");
-                    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-
-                    if (Main.isTraceEnabled()) {
-                        Main.trace("SSL Context protocol: " + sslContext.getProtocol());
-                        Main.trace("SSL Context provider: " + sslContext.getProvider());
-                    }
-
-                    Enumeration<String> aliases = ks.aliases();
-                    if (aliases.hasMoreElements()) {
-                        Main.platform.setupHttpsCertificate(new KeyStore.TrustedCertificateEntry(ks.getCertificate(aliases.nextElement())));
-                    }
-
-                    initOK = true;
-                }
+                KeyStore ks = loadJosmKeystore();
+
+                KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+                kmf.init(ks, KEYENTRY_PASSWORD.get().toCharArray());
+
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+                tmf.init(ks);
+
+                sslContext = SSLContext.getInstance("TLS");
+                sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+                if (Main.isTraceEnabled()) {
+                    Main.trace("SSL Context protocol: " + sslContext.getProtocol());
+                    Main.trace("SSL Context provider: " + sslContext.getProvider());
+                }
+
+                setupPlatform(ks);
+
+                initOK = true;
             } catch (IOException | GeneralSecurityException e) {
                 Main.error(e);
             }
         }
+    }
+
+    /**
+     * Setup the platform-dependant certificate stuff.
+     * @param josmKs The JOSM keystore, containing localhost certificate and private key.
+     * @return {@code true} if something has changed as a result of the call (certificate installation, etc.)
+     * @throws KeyStoreException if the keystore has not been initialized (loaded)
+     * @throws NoSuchAlgorithmException in case of error
+     * @throws CertificateException in case of error
+     * @throws IOException in case of error
+     * @since 7343
+     */
+    public static boolean setupPlatform(KeyStore josmKs) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
+        Enumeration<String> aliases = josmKs.aliases();
+        if (aliases.hasMoreElements()) {
+            return Main.platform.setupHttpsCertificate(ENTRY_ALIAS,
+                    new KeyStore.TrustedCertificateEntry(josmKs.getCertificate(aliases.nextElement())));
+        }
+        return false;
     }
 
