Ignore:
Timestamp:
2019-10-22T23:32:51+02:00 (4 years ago)
Author:
Don-vip
Message:

fix #10033, fix #15748, fix #17097 - drop remote control https support

Rationale: all modern browsers (including next version of Safari) allow mixed-content to localhost.

Cross-platform / cross-browser HTTPS support is a pain to maintain, was never completed, and is no longer needed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java

    r15006 r15469  
    3232
    3333import java.awt.Desktop;
    34 import java.awt.GraphicsEnvironment;
    3534import java.io.BufferedWriter;
    3635import java.io.File;
     
    5049import java.nio.file.InvalidPathException;
    5150import java.nio.file.Path;
    52 import java.security.InvalidKeyException;
    53 import java.security.KeyFactory;
    5451import java.security.KeyStore;
    5552import java.security.KeyStoreException;
    5653import java.security.MessageDigest;
    5754import java.security.NoSuchAlgorithmException;
    58 import java.security.NoSuchProviderException;
    59 import java.security.PublicKey;
    60 import java.security.SignatureException;
    6155import java.security.cert.Certificate;
    6256import java.security.cert.CertificateException;
    6357import java.security.cert.X509Certificate;
    64 import java.security.spec.InvalidKeySpecException;
    65 import java.security.spec.X509EncodedKeySpec;
    6658import java.text.ParseException;
    6759import java.util.ArrayList;
     
    7971import java.util.regex.Pattern;
    8072
    81 import javax.swing.JOptionPane;
    82 
    8373import org.openstreetmap.josm.data.Preferences;
    8474import org.openstreetmap.josm.data.StructUtils;
    8575import org.openstreetmap.josm.data.StructUtils.StructEntry;
    8676import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
    87 import org.openstreetmap.josm.gui.MainApplication;
    8877import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
    8978import org.openstreetmap.josm.io.NetworkManager;
     
    147136        }
    148137    }
    149 
    150     private static final byte[] INSECURE_PUBLIC_KEY = new byte[] {
    151         0x30, (byte) 0x82, 0x1, 0x22, 0x30, 0xd, 0x6, 0x9, 0x2a, (byte) 0x86, 0x48,
    152         (byte) 0x86, (byte) 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0, 0x3, (byte) 0x82, 0x1, 0xf, 0x0,
    153         0x30, (byte) 0x82, 0x01, 0x0a, 0x02, (byte) 0x82, 0x01, 0x01, 0x00, (byte) 0x95, (byte) 0x95, (byte) 0x88,
    154         (byte) 0x84, (byte) 0xc8, (byte) 0xd9, 0x6b, (byte) 0xc5, (byte) 0xda, 0x0b, 0x69, (byte) 0xbf, (byte) 0xfc,
    155         0x7e, (byte) 0xb9, (byte) 0x96, 0x2c, (byte) 0xeb, (byte) 0x8f, (byte) 0xbc, 0x6e, 0x40, (byte) 0xe6, (byte) 0xe2,
    156         (byte) 0xfc, (byte) 0xf1, 0x7f, 0x73, (byte) 0xa7, (byte) 0x9d, (byte) 0xde, (byte) 0xc7, (byte) 0x88, 0x57, 0x51,
    157         (byte) 0x84, (byte) 0xed, (byte) 0x96, (byte) 0xfb, (byte) 0xe1, 0x38, (byte) 0xef, 0x08, 0x2b, (byte) 0xf3,
    158         (byte) 0xc7, (byte) 0xc3, 0x5d, (byte) 0xfe, (byte) 0xf9, 0x51, (byte) 0xe6, 0x29, (byte) 0xfc, (byte) 0xe5, 0x0d,
    159         (byte) 0xa1, 0x0d, (byte) 0xa8, (byte) 0xb4, (byte) 0xae, 0x26, 0x18, 0x19, 0x4d, 0x6c, 0x0c, 0x3b, 0x12, (byte) 0xba,
    160         (byte) 0xbc, 0x5f, 0x32, (byte) 0xb3, (byte) 0xbe, (byte) 0x9d, 0x17, 0x0d, 0x4d, 0x2f, 0x1a, 0x48, (byte) 0xb7,
    161         (byte) 0xac, (byte) 0xf7, 0x1a, 0x43, 0x01, (byte) 0x97, (byte) 0xf4, (byte) 0xf8, 0x4c, (byte) 0xbb, 0x6a, (byte) 0xbc,
    162         0x33, (byte) 0xe1, 0x73, 0x1e, (byte) 0x86, (byte) 0xfb, 0x2e, (byte) 0xb1, 0x63, 0x75, (byte) 0x85, (byte) 0xdc,
    163         (byte) 0x82, 0x6c, 0x28, (byte) 0xf1, (byte) 0xe3, (byte) 0x90, 0x63, (byte) 0x9d, 0x3d, 0x48, (byte) 0x8a, (byte) 0x8c,
    164         0x47, (byte) 0xe2, 0x10, 0x0b, (byte) 0xef, (byte) 0x91, (byte) 0x94, (byte) 0xb0, 0x6c, 0x4c, (byte) 0x80, 0x76, 0x03,
    165         (byte) 0xe1, (byte) 0xb6, (byte) 0x90, (byte) 0x87, (byte) 0xd9, (byte) 0xae, (byte) 0xf4, (byte) 0x8e, (byte) 0xe0,
    166         (byte) 0x9f, (byte) 0xe7, 0x3a, 0x2c, 0x2f, 0x21, (byte) 0xd4, 0x46, (byte) 0xba, (byte) 0x95, 0x70, (byte) 0xa9, 0x5b,
    167         0x20, 0x2a, (byte) 0xfa, 0x52, 0x3e, (byte) 0x9d, (byte) 0xd9, (byte) 0xef, 0x28, (byte) 0xc5, (byte) 0xd1, 0x60,
    168         (byte) 0x89, 0x68, 0x6e, 0x7f, (byte) 0xd7, (byte) 0x9e, (byte) 0x89, 0x4c, (byte) 0xeb, 0x4d, (byte) 0xd2, (byte) 0xc6,
    169         (byte) 0xf4, 0x2d, 0x02, 0x5d, (byte) 0xda, (byte) 0xde, 0x33, (byte) 0xfe, (byte) 0xc1, 0x7e, (byte) 0xde, 0x4f, 0x1f,
    170         (byte) 0x9b, 0x6e, 0x6f, 0x0f, 0x66, 0x71, 0x19, (byte) 0xe9, 0x43, 0x3c, (byte) 0x83, 0x0a, 0x0f, 0x28, 0x21, (byte) 0xc8,
    171         0x38, (byte) 0xd3, 0x4e, 0x48, (byte) 0xdf, (byte) 0xd4, (byte) 0x99, (byte) 0xb5, (byte) 0xc6, (byte) 0x8d, (byte) 0xd4,
    172         (byte) 0xc1, 0x69, 0x58, 0x79, (byte) 0x82, 0x32, (byte) 0x82, (byte) 0xd4, (byte) 0x86, (byte) 0xe2, 0x04, 0x08, 0x63,
    173         (byte) 0x87, (byte) 0xf0, 0x2a, (byte) 0xf6, (byte) 0xec, 0x3e, 0x51, 0x0f, (byte) 0xda, (byte) 0xb4, 0x67, 0x19, 0x5e,
    174         0x16, 0x02, (byte) 0x9f, (byte) 0xf1, 0x19, 0x0c, 0x3e, (byte) 0xb8, 0x04, 0x49, 0x07, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01
    175     };
    176138
    177139    private static final String WINDOWS_ROOT = "Windows-ROOT";
     
    374336        ks.load(null, null);
    375337        return ks;
    376     }
    377 
    378     /**
    379      * Removes potential insecure certificates installed with previous versions of JOSM on Windows.
    380      * @throws NoSuchAlgorithmException on unsupported signature algorithms
    381      * @throws CertificateException if any of the certificates in the Windows keystore could not be loaded
    382      * @throws KeyStoreException if no Provider supports a KeyStoreSpi implementation for the type "Windows-ROOT"
    383      * @throws IOException if there is an I/O or format problem with the keystore data, if a password is required but not given
    384      * @since 7335
    385      */
    386     public static void removeInsecureCertificates() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
    387         // We offered before a public private key we need now to remove from Windows PCs as it might be a huge security risk (see #10230)
    388         PublicKey insecurePubKey = null;
    389         try {
    390             insecurePubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(INSECURE_PUBLIC_KEY));
    391         } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
    392             Logging.error(e);
    393             return;
    394         }
    395         KeyStore ks = getRootKeystore();
    396         Enumeration<String> en = ks.aliases();
    397         Collection<String> insecureCertificates = new ArrayList<>();
    398         while (en.hasMoreElements()) {
    399             String alias = en.nextElement();
    400             // Look for certificates associated with a private key
    401             if (ks.isKeyEntry(alias)) {
    402                 try {
    403                     ks.getCertificate(alias).verify(insecurePubKey);
    404                     // If no exception, this is a certificate signed with the insecure key -> remove it
    405                     insecureCertificates.add(alias);
    406                 } catch (InvalidKeyException | NoSuchProviderException | SignatureException e) {
    407                     // If exception this is not a certificate related to JOSM, just trace it
    408                     Logging.trace(alias + " --> " + e.getClass().getName());
    409                     Logging.trace(e);
    410                 }
    411             }
    412         }
    413         // Remove insecure certificates
    414         if (!insecureCertificates.isEmpty()) {
    415             StringBuilder message = new StringBuilder("<html>");
    416             message.append(tr("A previous version of JOSM has installed a custom certificate "+
    417                     "in order to provide HTTPS support for Remote Control:"))
    418                    .append("<br><ul>");
    419             for (String alias : insecureCertificates) {
    420                 message.append("<li>")
    421                        .append(alias)
    422                        .append("</li>");
    423             }
    424             message.append("</ul>")
    425                    .append(tr("It appears it could be an important <b>security risk</b>.<br><br>"+
    426                     "You are now going to be prompted by Windows to remove this insecure certificate.<br>"+
    427                     "For your own safety, <b>please click Yes</b> in next dialog."))
    428                    .append("</html>");
    429             JOptionPane.showMessageDialog(MainApplication.getMainFrame(), message.toString(), tr("Warning"), JOptionPane.WARNING_MESSAGE);
    430             for (String alias : insecureCertificates) {
    431                 Logging.warn(tr("Removing insecure certificate from {0} keystore: {1}", WINDOWS_ROOT, alias));
    432                 try {
    433                     ks.deleteEntry(alias);
    434                 } catch (KeyStoreException e) {
    435                     Logging.log(Logging.LEVEL_ERROR, tr("Unable to remove insecure certificate from keystore: {0}", e.getMessage()), e);
    436                 }
    437             }
    438         }
    439     }
    440 
    441     @Override
    442     public boolean setupHttpsCertificate(String entryAlias, KeyStore.TrustedCertificateEntry trustedCert)
    443             throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
    444         KeyStore ks = getRootKeystore();
    445         // Look for certificate to install
    446         try {
    447             String alias = ks.getCertificateAlias(trustedCert.getTrustedCertificate());
    448             if (alias != null) {
    449                 // JOSM certificate found, return
    450                 Logging.debug(tr("JOSM localhost certificate found in {0} keystore: {1}", WINDOWS_ROOT, alias));
    451                 return false;
    452             }
    453         } catch (ArrayIndexOutOfBoundsException e) {
    454             // catch error of JDK-8172244 as bug seems to not be fixed anytime soon
    455             Logging.log(Logging.LEVEL_ERROR, "JDK-8172244 occurred. Abort HTTPS setup", e);
    456             return false;
    457         }
    458         if (!GraphicsEnvironment.isHeadless()) {
    459             // JOSM certificate not found, warn user
    460             StringBuilder message = new StringBuilder("<html>");
    461             message.append(tr("Remote Control is configured to provide HTTPS support.<br>"+
    462                     "This requires to add a custom certificate generated by JOSM to the Windows Root CA store.<br><br>"+
    463                     "You are now going to be prompted by Windows to confirm this operation.<br>"+
    464                     "To enable proper HTTPS support, <b>please click Yes</b> in next dialog.<br><br>"+
    465                     "If unsure, you can also click No then disable HTTPS support in Remote Control preferences."))
    466                    .append("</html>");
    467             JOptionPane.showMessageDialog(MainApplication.getMainFrame(), message.toString(),
    468                     tr("HTTPS support in Remote Control"), JOptionPane.INFORMATION_MESSAGE);
    469         }
    470         // install it to Windows-ROOT keystore, used by IE, Chrome and Safari, but not by Firefox
    471         Logging.info(tr("Adding JOSM localhost certificate to {0} keystore", WINDOWS_ROOT));
    472         ks.setEntry(entryAlias, trustedCert, null);
    473         return true;
    474338    }
    475339
Note: See TracChangeset for help on using the changeset viewer.