Changeset 11943 in josm for trunk/src/org
- Timestamp:
- 2017-04-17T14:07:04+02:00 (7 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/io/CertificateAmendment.java
r11903 r11943 16 16 import java.security.KeyStoreException; 17 17 import java.security.MessageDigest; 18 import java.security.NoSuchAlgorithmException; 19 import java.security.cert.CertificateEncodingException; 20 import java.security.cert.CertificateException; 18 21 import java.security.cert.CertificateFactory; 19 22 import java.security.cert.PKIXParameters; … … 40 43 public final class CertificateAmendment { 41 44 42 private static final String[] CERT_AMEND = { 43 "resource://data/security/DST_Root_CA_X3.pem" 45 /** 46 * A certificate amendment. 47 * @since 11940 48 */ 49 public static class CertAmend { 50 private final String id; 51 private final String sha256; 52 53 CertAmend(String path, String sha256) { 54 this.id = path; 55 this.sha256 = sha256; 56 } 57 58 /** 59 * Returns the certificate identifier. 60 * @return path for JOSM embedded certificate, alias for platform certificate 61 */ 62 public final String getId() { 63 return id; 64 } 65 66 /** 67 * Returns the SHA-256 hash. 68 * @return the SHA-256 hash, in hexadecimal 69 */ 70 public final String getSha256() { 71 return sha256; 72 } 73 } 74 75 /** 76 * Certificates embedded in JOSM 77 */ 78 private static final CertAmend[] CERT_AMEND = { 79 new CertAmend("resource://data/security/DST_Root_CA_X3.pem", 80 "0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739") 44 81 }; 45 82 46 private static final String[] SHA_HASHES = { 47 "0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739" 83 /** 84 * Certificates looked into platform native keystore and not embedded in JOSM. 85 * Identifiers must match Windows keystore aliases for efficient search. 86 */ 87 private static final CertAmend[] PLATFORM_CERT_AMEND = { 88 new CertAmend("Staat der Nederlanden Root CA - G2", 89 "668c83947da63b724bece1743c31a0e6aed0db8ec5b31be377bb784f91b6716f"), 90 new CertAmend("Government of Netherlands G3", 91 "3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428") 48 92 }; 49 93 … … 66 110 } 67 111 112 MessageDigest md = MessageDigest.getInstance("SHA-256"); 68 113 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 69 114 boolean certificateAdded = false; 70 for (int i = 0; i < CERT_AMEND.length; i++) { 71 try (CachedFile certCF = new CachedFile(CERT_AMEND[i])) { 72 byte[] certBytes = certCF.getByteContent(); 73 ByteArrayInputStream certIS = new ByteArrayInputStream(certBytes); 74 X509Certificate cert = (X509Certificate) cf.generateCertificate(certIS); 75 MessageDigest md = MessageDigest.getInstance("SHA-256"); 76 String sha1 = Utils.toHexString(md.digest(cert.getEncoded())); 77 if (!SHA_HASHES[i].equals(sha1)) { 78 throw new IllegalStateException( 79 tr("Error adding certificate {0} - certificate fingerprint mismatch. Expected {1}, was {2}", 80 CERT_AMEND[i], 81 SHA_HASHES[i], 82 sha1 83 )); 84 } 85 if (certificateIsMissing(keyStore, cert)) { 86 if (Main.isDebugEnabled()) { 87 Main.debug(tr("Adding certificate for TLS connections: {0}", cert.getSubjectX500Principal().getName())); 88 } 89 String alias = "josm:" + new File(CERT_AMEND[i]).getName(); 90 keyStore.setCertificateEntry(alias, cert); 115 // Add embedded certificates. Exit in case of error 116 for (CertAmend certAmend : CERT_AMEND) { 117 try (CachedFile certCF = new CachedFile(certAmend.id)) { 118 X509Certificate cert = (X509Certificate) cf.generateCertificate( 119 new ByteArrayInputStream(certCF.getByteContent())); 120 if (checkAndAddCertificate(md, cert, certAmend, keyStore)) { 91 121 certificateAdded = true; 92 122 } 93 123 } 124 } 125 126 try { 127 // Try to add platform certificates. Do not exit in case of error (embedded certificates may be OK) 128 for (CertAmend certAmend : PLATFORM_CERT_AMEND) { 129 X509Certificate cert = Main.platform.getX509Certificate(certAmend); 130 if (checkAndAddCertificate(md, cert, certAmend, keyStore)) { 131 certificateAdded = true; 132 } 133 } 134 } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | IllegalStateException e) { 135 Main.error(e); 94 136 } 95 137 … … 101 143 SSLContext.setDefault(sslContext); 102 144 } 145 } 146 147 private static boolean checkAndAddCertificate(MessageDigest md, X509Certificate cert, CertAmend certAmend, KeyStore keyStore) 148 throws CertificateEncodingException, KeyStoreException, InvalidAlgorithmParameterException { 149 if (cert != null) { 150 String sha256 = Utils.toHexString(md.digest(cert.getEncoded())); 151 if (!certAmend.sha256.equals(sha256)) { 152 throw new IllegalStateException( 153 tr("Error adding certificate {0} - certificate fingerprint mismatch. Expected {1}, was {2}", 154 certAmend.id, certAmend.sha256, sha256)); 155 } 156 if (certificateIsMissing(keyStore, cert)) { 157 if (Main.isDebugEnabled()) { 158 Main.debug(tr("Adding certificate for TLS connections: {0}", cert.getSubjectX500Principal().getName())); 159 } 160 String alias = "josm:" + new File(certAmend.id).getName(); 161 keyStore.setCertificateEntry(alias, cert); 162 return true; 163 } 164 } 165 return false; 103 166 } 104 167 -
trunk/src/org/openstreetmap/josm/tools/PlatformHook.java
r11642 r11943 9 9 import java.security.NoSuchAlgorithmException; 10 10 import java.security.cert.CertificateException; 11 import java.security.cert.X509Certificate; 11 12 import java.util.List; 13 14 import org.openstreetmap.josm.io.CertificateAmendment.CertAmend; 12 15 13 16 /** … … 154 157 155 158 /** 159 * Returns the {@code X509Certificate} matching the given certificate amendment information. 160 * @param certAmend certificate amendment 161 * @return the {@code X509Certificate} matching the given certificate amendment information, or {@code null} 162 * @throws KeyStoreException in case of error 163 * @throws IOException in case of error 164 * @throws CertificateException in case of error 165 * @throws NoSuchAlgorithmException in case of error 166 * @since 11940 167 */ 168 default X509Certificate getX509Certificate(CertAmend certAmend) 169 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 170 return null; 171 } 172 173 /** 156 174 * Returns the platform-dependent default cache directory. 157 175 * @return the platform-dependent default cache directory -
trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java
r11939 r11943 45 45 import java.security.KeyStore; 46 46 import java.security.KeyStoreException; 47 import java.security.MessageDigest; 47 48 import java.security.NoSuchAlgorithmException; 48 49 import java.security.NoSuchProviderException; 49 50 import java.security.PublicKey; 50 51 import java.security.SignatureException; 52 import java.security.cert.Certificate; 51 53 import java.security.cert.CertificateException; 54 import java.security.cert.X509Certificate; 52 55 import java.security.spec.InvalidKeySpecException; 53 56 import java.security.spec.X509EncodedKeySpec; … … 64 67 import org.openstreetmap.josm.Main; 65 68 import org.openstreetmap.josm.data.Preferences; 69 import org.openstreetmap.josm.io.CertificateAmendment.CertAmend; 66 70 67 71 /** 68 69 70 72 * {@code PlatformHook} implementation for Microsoft Windows systems. 73 * @since 1023 74 */ 71 75 public class PlatformHookWindows implements PlatformHook { 72 76 … … 351 355 ks.setEntry(entryAlias, trustedCert, null); 352 356 return true; 357 } 358 359 @Override 360 public X509Certificate getX509Certificate(CertAmend certAmend) 361 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 362 KeyStore ks = getRootKeystore(); 363 // Search by alias (fast) 364 Certificate result = ks.getCertificate(certAmend.getId()); 365 if (result instanceof X509Certificate) { 366 return (X509Certificate) result; 367 } 368 // If not found, search by SHA-256 (slower) 369 MessageDigest md = MessageDigest.getInstance("SHA-256"); 370 for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) { 371 result = ks.getCertificate(aliases.nextElement()); 372 if (result instanceof X509Certificate 373 && certAmend.getSha256().equalsIgnoreCase(Utils.toHexString(md.digest(result.getEncoded())))) { 374 return (X509Certificate) result; 375 } 376 } 377 // Not found 378 return null; 353 379 } 354 380
Note:
See TracChangeset
for help on using the changeset viewer.