Changeset 13450 in josm


Ignore:
Timestamp:
2018-02-23T00:01:20+01:00 (6 months ago)
Author:
Don-vip
Message:

fix #15992 - load native certificates from macOS system root trust store, see https://support.apple.com/en-us/HT208127

Location:
trunk/src/org/openstreetmap/josm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/CertificateAmendment.java

    r12846 r13450  
    55
    66import java.io.ByteArrayInputStream;
    7 import java.io.File;
    87import java.io.IOException;
    98import java.io.InputStream;
     
    4948     * @since 11943
    5049     */
    51     public static class CertAmend {
    52         private final String id;
     50    public abstract static class CertAmend {
    5351        private final String filename;
    5452        private final String sha256;
    5553
    56         CertAmend(String id, String filename, String sha256) {
    57             this.id = id;
    58             this.filename = filename;
    59             this.sha256 = sha256;
    60         }
    61 
    62         /**
    63          * Returns the certificate identifier.
    64          * @return path for JOSM embedded certificate, alias for Windows platform certificate
    65          */
    66         public final String getId() {
    67             return id;
     54        CertAmend(String filename, String sha256) {
     55            this.filename = Objects.requireNonNull(filename);
     56            this.sha256 = Objects.requireNonNull(sha256);
    6857        }
    6958
     
    8776
    8877    /**
     78     * An embedded certificate amendment.
     79     * @since 13450
     80     */
     81    public static class EmbeddedCertAmend extends CertAmend {
     82        private final String url;
     83
     84        EmbeddedCertAmend(String url, String filename, String sha256) {
     85            super(filename, sha256);
     86            this.url = Objects.requireNonNull(url);
     87        }
     88
     89        /**
     90         * Returns the embedded URL in JOSM jar.
     91         * @return path for JOSM embedded certificate
     92         */
     93        public final String getUrl() {
     94            return url;
     95        }
     96
     97        @Override
     98        public String toString() {
     99            return url;
     100        }
     101    }
     102
     103    /**
     104     * A certificate amendment relying on native platform certificate store.
     105     * @since 13450
     106     */
     107    public static class NativeCertAmend extends CertAmend {
     108        private final String winAlias;
     109        private final String macAlias;
     110
     111        NativeCertAmend(String winAlias, String macAlias, String filename, String sha256) {
     112            super(filename, sha256);
     113            this.winAlias = Objects.requireNonNull(winAlias);
     114            this.macAlias = Objects.requireNonNull(macAlias);
     115        }
     116
     117        /**
     118         * Returns the Windows alias in System Root Certificates keystore.
     119         * @return the Windows alias in System Root Certificates keystore
     120         */
     121        public final String getWinAlias() {
     122            return winAlias;
     123        }
     124
     125        /**
     126         * Returns the macOS alias in System Root Certificates keychain.
     127         * @return the macOS alias in System Root Certificates keychain
     128         */
     129        public final String getMacAlias() {
     130            return macAlias;
     131        }
     132
     133        @Override
     134        public String toString() {
     135            String result = winAlias;
     136            if (!winAlias.equals(macAlias)) {
     137                result += " / " + macAlias;
     138            }
     139            return result;
     140        }
     141    }
     142
     143    /**
    89144     * Certificates embedded in JOSM
    90145     */
    91     private static final CertAmend[] CERT_AMEND = {
    92         new CertAmend("resource://data/security/DST_Root_CA_X3.pem", "DST_Root_CA_X3.pem",
     146    private static final EmbeddedCertAmend[] CERT_AMEND = {
     147        new EmbeddedCertAmend("resource://data/security/DST_Root_CA_X3.pem", "DST_Root_CA_X3.pem",
    93148                "0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739")
    94149    };
     
    96151    /**
    97152     * Certificates looked into platform native keystore and not embedded in JOSM.
    98      * Identifiers must match Windows keystore aliases and Unix filenames for efficient search.
    99      */
    100     private static final CertAmend[] PLATFORM_CERT_AMEND = {
     153     * Identifiers must match Windows/macOS keystore aliases and Unix filenames for efficient search.
     154     */
     155    private static final NativeCertAmend[] PLATFORM_CERT_AMEND = {
    101156        // Government of Netherlands
    102         new CertAmend("Staat der Nederlanden Root CA - G2", "Staat_der_Nederlanden_Root_CA_-_G2.crt",
     157        new NativeCertAmend("Staat der Nederlanden Root CA - G2", "Staat der Nederlanden Root CA - G2",
     158                "Staat_der_Nederlanden_Root_CA_-_G2.crt",
    103159                "668c83947da63b724bece1743c31a0e6aed0db8ec5b31be377bb784f91b6716f"),
    104160        // Government of Netherlands
    105         new CertAmend("Government of Netherlands G3", "Staat_der_Nederlanden_Root_CA_-_G3.crt",
     161        new NativeCertAmend("Government of Netherlands G3", "Staat der Nederlanden Root CA - G3",
     162                "Staat_der_Nederlanden_Root_CA_-_G3.crt",
    106163                "3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428"),
    107164        // Trusted and used by French Government - https://www.certigna.fr/autorites/index.xhtml?ac=Racine#lracine
    108         new CertAmend("Certigna", "Certigna.crt",
     165        new NativeCertAmend("Certigna", "Certigna", "Certigna.crt",
    109166                "e3b6a2db2ed7ce48842f7ac53241c7b71d54144bfb40c11f3f1d0b42f5eea12d"),
    110167    };
     
    132189        boolean certificateAdded = false;
    133190        // Add embedded certificates. Exit in case of error
    134         for (CertAmend certAmend : CERT_AMEND) {
    135             try (CachedFile certCF = new CachedFile(certAmend.id)) {
     191        for (EmbeddedCertAmend certAmend : CERT_AMEND) {
     192            try (CachedFile certCF = new CachedFile(certAmend.url)) {
    136193                X509Certificate cert = (X509Certificate) cf.generateCertificate(
    137194                        new ByteArrayInputStream(certCF.getByteContent()));
     
    144201        try {
    145202            // Try to add platform certificates. Do not exit in case of error (embedded certificates may be OK)
    146             for (CertAmend certAmend : PLATFORM_CERT_AMEND) {
     203            for (NativeCertAmend certAmend : PLATFORM_CERT_AMEND) {
    147204                X509Certificate cert = Main.platform.getX509Certificate(certAmend);
    148205                if (checkAndAddCertificate(md, cert, certAmend, keyStore)) {
     
    170227                throw new IllegalStateException(
    171228                        tr("Error adding certificate {0} - certificate fingerprint mismatch. Expected {1}, was {2}",
    172                             certAmend.id, certAmend.sha256, sha256));
     229                            certAmend, certAmend.sha256, sha256));
    173230            }
    174231            if (certificateIsMissing(keyStore, cert)) {
     
    176233                    Logging.debug(tr("Adding certificate for TLS connections: {0}", cert.getSubjectX500Principal().getName()));
    177234                }
    178                 String alias = "josm:" + new File(certAmend.id).getName();
     235                String alias = "josm:" + certAmend.filename;
    179236                keyStore.setCertificateEntry(alias, cert);
    180237                return true;
  • trunk/src/org/openstreetmap/josm/tools/PlatformHook.java

    r12919 r13450  
    2020
    2121import org.openstreetmap.josm.data.projection.datum.NTV2Proj4DirGridShiftFileSource;
    22 import org.openstreetmap.josm.io.CertificateAmendment.CertAmend;
     22import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
    2323import org.openstreetmap.josm.spi.preferences.Config;
    2424import org.openstreetmap.josm.tools.date.DateUtils;
     
    211211     * @throws CertificateException in case of error
    212212     * @throws NoSuchAlgorithmException in case of error
    213      * @since 11943
    214      */
    215     default X509Certificate getX509Certificate(CertAmend certAmend)
     213     * @since 13450
     214     */
     215    default X509Certificate getX509Certificate(NativeCertAmend certAmend)
    216216            throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
    217217        return null;
  • trunk/src/org/openstreetmap/josm/tools/PlatformHookOsx.java

    r12776 r13450  
    88import java.awt.Window;
    99import java.awt.event.KeyEvent;
     10import java.io.ByteArrayInputStream;
    1011import java.io.File;
    1112import java.io.IOException;
     
    1415import java.lang.reflect.Method;
    1516import java.lang.reflect.Proxy;
     17import java.nio.charset.StandardCharsets;
     18import java.security.KeyStoreException;
     19import java.security.NoSuchAlgorithmException;
     20import java.security.cert.CertificateException;
     21import java.security.cert.CertificateFactory;
     22import java.security.cert.X509Certificate;
    1623import java.util.Arrays;
    1724import java.util.List;
    1825import java.util.Objects;
     26import java.util.concurrent.ExecutionException;
    1927
    2028import javax.swing.UIManager;
    2129
    2230import org.openstreetmap.josm.Main;
     31import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
    2332
    2433/**
     
    427436                Main.pref.getJOSMDirectoryBaseName());
    428437    }
     438
     439    @Override
     440    public X509Certificate getX509Certificate(NativeCertAmend certAmend)
     441            throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
     442        try {
     443            // Get platform certificate in PEM format
     444            String pem = Utils.execOutput(Arrays.asList("security", "find-certificate",
     445                    "-c", certAmend.getMacAlias(), "-p", "/System/Library/Keychains/SystemRootCertificates.keychain"));
     446            Logging.debug(pem);
     447            return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(
     448                    new ByteArrayInputStream(pem.getBytes(StandardCharsets.UTF_8)));
     449        } catch (ExecutionException | InterruptedException | IllegalArgumentException e) {
     450            throw new IOException(e);
     451        }
     452    }
    429453}
  • trunk/src/org/openstreetmap/josm/tools/PlatformHookUnixoid.java

    r13204 r13450  
    2626
    2727import org.openstreetmap.josm.Main;
    28 import org.openstreetmap.josm.io.CertificateAmendment.CertAmend;
     28import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
    2929import org.openstreetmap.josm.spi.preferences.Config;
    3030
     
    398398
    399399    @Override
    400     public X509Certificate getX509Certificate(CertAmend certAmend)
     400    public X509Certificate getX509Certificate(NativeCertAmend certAmend)
    401401            throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
    402402        File f = new File("/usr/share/ca-certificates/mozilla", certAmend.getFilename());
  • trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java

    r13204 r13450  
    7171import org.openstreetmap.josm.data.StructUtils.StructEntry;
    7272import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
    73 import org.openstreetmap.josm.io.CertificateAmendment.CertAmend;
     73import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
    7474import org.openstreetmap.josm.spi.preferences.Config;
    7575
     
    439439
    440440    @Override
    441     public X509Certificate getX509Certificate(CertAmend certAmend)
     441    public X509Certificate getX509Certificate(NativeCertAmend certAmend)
    442442            throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
    443443        KeyStore ks = getRootKeystore();
    444444        // Search by alias (fast)
    445         Certificate result = ks.getCertificate(certAmend.getId());
     445        Certificate result = ks.getCertificate(certAmend.getWinAlias());
    446446        if (result instanceof X509Certificate) {
    447447            return (X509Certificate) result;
  • trunk/src/org/openstreetmap/josm/tools/Utils.java

    r13356 r13450  
    847847                    all = new StringBuilder(line);
    848848                } else {
    849                     all.append('\n');
    850                     all.append(line);
     849                    all.append('\n')
     850                       .append(line);
    851851                }
    852852            }
Note: See TracChangeset for help on using the changeset viewer.