From 99c5ccab96925e0fbfa1253436d93ac5b4949da3 Mon Sep 17 00:00:00 2001 From: Alameyo Date: Sat, 19 Aug 2017 11:34:44 +0200 Subject: [PATCH 1/3] SPARK-1989 --- .../certificates/CertificateController.java | 95 ++++++++++-------- .../certificates/IdentityController.java | 47 ++++----- .../SparkExceptionsTrustManager.java | 22 ++-- .../certificates/SparkSSLContext.java | 4 +- .../certificates/SparkTrustManager.java | 43 ++++++-- core/src/main/security/blacklist | Bin 1246 -> 0 bytes core/src/main/security/exceptions | Bin 3138 -> 0 bytes core/src/main/security/identitystore.jks | Bin 32 -> 0 bytes core/src/main/security/truststore | Bin 112432 -> 0 bytes 9 files changed, 121 insertions(+), 90 deletions(-) delete mode 100644 core/src/main/security/blacklist delete mode 100644 core/src/main/security/exceptions delete mode 100644 core/src/main/security/identitystore.jks delete mode 100644 core/src/main/security/truststore diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java index 379663b40..0f1fe0f2b 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java @@ -69,78 +69,85 @@ public class CertificateController extends CertManager { */ @Override public void loadKeyStores() { - try (InputStream inputStram = new FileInputStream(TRUSTED)) { - + try { trustStore = KeyStore.getInstance("JKS"); - trustStore.load(inputStram, passwd); - trustedCertificates = fillTableListWithKeyStoreContent(trustStore, trustedCertificates); - - } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - Log.warning("TrustStore couldn't be loaded: maybe empty"); - try { - trustStore.load(null, passwd); - } catch (NoSuchAlgorithmException | CertificateException | IOException e1) { - Log.warning("TrustStore couldn't be loaded: other bug"); + // checking if length >0 prevents EOFExceptions + if (TRUSTED.exists() && !TRUSTED.isDirectory() && TRUSTED.length() > 0) { + try (InputStream inputStream = new FileInputStream(TRUSTED)) { + trustStore.load(inputStream, passwd); + trustedCertificates = fillTableListWithKeyStoreContent(trustStore, trustedCertificates); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore", e); + } + } else { + trustStore.load(null, passwd); // if cannot open KeyStore then new empty one will be created } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); } - try (InputStream inputStram = new FileInputStream(EXCEPTIONS)) { + try { exceptionsStore = KeyStore.getInstance("JKS"); - exceptionsStore.load(inputStram, passwd); - exemptedCertificates = fillTableListWithKeyStoreContent(exceptionsStore, exemptedCertificates); - - } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - Log.warning("ExceptionsStore couldn't be loaded: maybe empty"); - try { + if (EXCEPTIONS.exists() && !EXCEPTIONS.isDirectory() && EXCEPTIONS.length() > 0) { + try (InputStream inputStream = new FileInputStream(EXCEPTIONS)) { + exceptionsStore.load(inputStream, passwd); + exemptedCertificates = fillTableListWithKeyStoreContent(exceptionsStore, exemptedCertificates); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore", e); + } + } else { exceptionsStore.load(null, passwd); - } catch (NoSuchAlgorithmException | CertificateException | IOException e1) { - Log.warning("ExceptionsStore couldn't be loaded: other bug"); } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); } - try (InputStream inputStram = new FileInputStream(BLACKLIST)) { - + + try { blackListStore = KeyStore.getInstance("JKS"); - blackListStore.load(inputStram, passwd); - blackListedCertificates = fillTableListWithKeyStoreContent(blackListStore, blackListedCertificates); - - } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - - try { - Log.warning("BlackListStore couldn't be loaded: maybe empty"); + if (BLACKLIST.exists() && !BLACKLIST.isDirectory() && BLACKLIST.length() > 0) { + try (InputStream inputStream = new FileInputStream(BLACKLIST)) { + blackListStore.load(inputStream, passwd); + blackListedCertificates = fillTableListWithKeyStoreContent(blackListStore, blackListedCertificates); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore", e); + } + } else { blackListStore.load(null, passwd); - } catch (NoSuchAlgorithmException | CertificateException | IOException e1) { - Log.warning("BlackListStore couldn't be loaded: other bug"); } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); } - } @Override public void overWriteKeyStores() { try (OutputStream outputStream = new FileOutputStream(TRUSTED)) { - trustStore.store(outputStream, passwd); - + if (trustStore != null) { + trustStore.store(outputStream, passwd); + } } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Couldn't save TrustStore"); + Log.error("Couldn't save TrustStore", e); } try (OutputStream outputStream = new FileOutputStream(EXCEPTIONS)) { - exceptionsStore.store(outputStream, passwd); - + if (exceptionsStore != null) { + exceptionsStore.store(outputStream, passwd); + } } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Couldn't save ExceptionsStore"); + Log.error("Couldn't save ExceptionsStore", e); } try (OutputStream outputStream = new FileOutputStream(BLACKLIST)) { - blackListStore.store(outputStream, passwd); - + if (blackListStore != null) { + blackListStore.store(outputStream, passwd); + } } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Couldn't save BlackListStore"); + Log.error("Couldn't save BlackListStore", e); } } - - public void createCertTableModel(){ + + public void createCertTableModel(){ tableModel = new DefaultTableModel() { // return adequate classes for columns so last column is Boolean // displayed as checkbox @@ -165,7 +172,7 @@ public class CertificateController extends CertManager { }; tableModel.setColumnIdentifiers(COLUMN_NAMES); - Object[] certEntry;certEntry = new Object[NUMBER_OF_COLUMNS]; + Object[] certEntry = new Object[NUMBER_OF_COLUMNS]; if (trustedCertificates != null) { // put certificate from arrayList into rows with chosen columns diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java index e8d1863ee..8fb42c542 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java @@ -6,6 +6,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.nio.file.Files; @@ -65,7 +66,7 @@ public class IdentityController extends CertManager { */ private static String commonName, organizationUnit, organization,city, country; - public final static File IDENTITY = new File( Spark.getSparkUserHome() + File.separator + "security" + File.separator + "identitystore.jks"); + public final static File IDENTITY = new File( Spark.getSparkUserHome() + File.separator + "security" + File.separator + "identitystore"); public final static File SECURITY_DIRECTORY = new File( Spark.getSparkUserHome() + File.separator + "security"); public static File CSR_FILE = new File( Spark.getSparkUserHome() + File.separator + "security" + File.separator + commonName + "_csr.pem"); public static File KEY_FILE = new File( Spark.getSparkUserHome() + File.separator + "security" + File.separator + commonName + "_key.pem"); @@ -85,45 +86,40 @@ public class IdentityController extends CertManager { } this.localPreferences = localPreferences; - try { - fillTableListWithKeyStoreContent(idStore, allCertificates); - } catch (KeyStoreException e) { - Log.error("Couldn't fill identity certificates list", e); - } + createTableModel(); } public void loadKeyStores() { - if (IDENTITY.exists() && IDENTITY.isFile()) { - try (final FileInputStream inputStream = new FileInputStream(IDENTITY)) { - - idStore = KeyStore.getInstance("JKS"); - idStore.load(inputStream, passwd); - - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.error("Couldn't open idetity store", e); - } - } else { - try { - - idStore = KeyStore.getInstance("JKS"); + try { + idStore = KeyStore.getInstance("JKS"); + if (IDENTITY.exists() && !IDENTITY.isDirectory() && IDENTITY.length() > 0) { + try (InputStream inputStream = new FileInputStream(IDENTITY)) { + idStore.load(inputStream, passwd); + allCertificates = fillTableListWithKeyStoreContent(idStore, allCertificates); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore", e); + } + } else { idStore.load(null, passwd); - - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.error("Couldn't create identity store", e); } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); } + + } @Override public void overWriteKeyStores() { try (OutputStream outputStream = new FileOutputStream(IDENTITY)) { - idStore.store(outputStream, passwd); - + if (idStore != null) { + idStore.store(outputStream, passwd); + } } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Couldn't save TrustStore"); + Log.error("Couldn't save TrustStore" , e); } } @@ -327,7 +323,6 @@ public class IdentityController extends CertManager { X509Certificate[] chain = {addedCert}; idStore.setKeyEntry(alias, key, passwd, chain); - idStore.setCertificateEntry(alias, addedCert); allCertificates.add(new CertificateModel(addedCert)); refreshCertTable(); JOptionPane.showMessageDialog(null, Res.getString("dialog.certificate.has.been.added")); diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java index 061ec0b26..20aaea3bb 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java @@ -32,13 +32,23 @@ public class SparkExceptionsTrustManager implements X509TrustManager { private Provider bcProvider = new BouncyCastleProvider(); // bc provider for path validation public SparkExceptionsTrustManager() { - try (InputStream inputStream = new FileInputStream(CertificateController.EXCEPTIONS)) { - this.exceptionsStore = KeyStore.getInstance("JKS"); - exceptionsStore.load(inputStream, CertificateController.passwd); - } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) { - Log.error("Couldn't load keystore for certificate exceptions authentication", e); - ; + + try { + exceptionsStore = KeyStore.getInstance("JKS"); + if (CertificateController.EXCEPTIONS.exists() && !CertificateController.EXCEPTIONS.isDirectory() + && CertificateController.EXCEPTIONS.length() > 0) { + try (InputStream inputStream = new FileInputStream(CertificateController.EXCEPTIONS)) { + exceptionsStore.load(inputStream, CertificateController.passwd); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore"); + } + } else { + exceptionsStore.load(null, CertificateController.passwd); + } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); } + } @Override diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkSSLContext.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkSSLContext.java index aa85e5d6b..b67c7ad39 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkSSLContext.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkSSLContext.java @@ -46,10 +46,8 @@ public class SparkSSLContext extends SSLContext { } else if (options == options.BOTH) { IdentityController identityController = new IdentityController(SettingsManager.getLocalPreferences()); - //X509ExtendedKeyManager[] km= (X509ExtendedKeyManager[]) identityController.initKeyManagerFactory().getKeyManagers(); - context.init(identityController.initKeyManagerFactory().getKeyManagers(), SparkTrustManager.getTrustManagerList(), new SecureRandom()); - + } else if (options == options.ONLY_CLIENT_SIDE){ IdentityController identityController = new IdentityController(SettingsManager.getLocalPreferences()); context.init(identityController.initKeyManagerFactory().getKeyManagers(), null, new SecureRandom()); diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java index fcf32f600..12068ce3d 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java @@ -341,21 +341,42 @@ public class SparkTrustManager implements X509TrustManager { * loads truststore and potentially (depending on settings) blacklist */ private void loadTrustStore() { - try (FileInputStream inputStream = new FileInputStream(CertificateController.TRUSTED)) { + try { trustStore = KeyStore.getInstance("JKS"); - trustStore.load(inputStream, CertificateController.passwd); - } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) { - Log.error("Error at accesing Truststore", e); + // checking if length >0 prevents EOFExceptions + if (CertificateController.TRUSTED.exists() && !CertificateController.TRUSTED.isDirectory() + && CertificateController.TRUSTED.length() > 0) { + try (InputStream inputStream = new FileInputStream(CertificateController.TRUSTED)) { + trustStore.load(inputStream, CertificateController.passwd); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore"); + } + } else { + trustStore.load(null, CertificateController.passwd); // if cannot open KeyStore then new empty one will + // be created + } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); } - if(acceptRevoked){ - try (FileInputStream inputStream = new FileInputStream(CertificateController.BLACKLIST)) { + + if (acceptRevoked) { + try { blackStore = KeyStore.getInstance("JKS"); - blackStore.load(inputStream, CertificateController.passwd); - } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) { - Log.error("Error at accesing blacklist Keystore", e); - } + if (CertificateController.BLACKLIST.exists() && !CertificateController.BLACKLIST.isDirectory() + && CertificateController.BLACKLIST.length() > 0) { + try (InputStream inputStream = new FileInputStream(CertificateController.BLACKLIST)) { + blackStore.load(inputStream, CertificateController.passwd); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore"); + } + } else { + blackStore.load(null, CertificateController.passwd); + } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); + } } - + } private void loadCRL(X509Certificate[] chain) throws IOException, InvalidAlgorithmParameterException, diff --git a/core/src/main/security/blacklist b/core/src/main/security/blacklist deleted file mode 100644 index c0b5f90fce6503922a64667a673b57afbc6369da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1246 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 diff --git a/core/src/main/security/identitystore.jks b/core/src/main/security/identitystore.jks deleted file mode 100644 index c408465500cb0af9cfd1f7371422ef8899ae6725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 ncmezO_TO6u1_mY|W_Xm5=la|E{*s%M?mC{^wn--0;QAy0^AQhj diff --git a/core/src/main/security/truststore b/core/src/main/security/truststore deleted file mode 100644 index f4de542f84b352f9434d1b08abe7ba79d95e2916..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112432 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 From bcbc7719a189c36a528d56ecd7d8b5290fec4d8c Mon Sep 17 00:00:00 2001 From: Alameyo Date: Sat, 19 Aug 2017 17:07:41 +0200 Subject: [PATCH 2/3] Create openKeyStore method in CertManager class. --- .../sparkimpl/certificates/CertManager.java | 27 +++++- .../certificates/CertificateController.java | 87 ++++++------------- .../certificates/IdentityController.java | 43 ++++----- .../SparkExceptionsTrustManager.java | 22 ++--- .../certificates/SparkTrustManager.java | 34 +------- 5 files changed, 75 insertions(+), 138 deletions(-) diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java index c6d72eb2a..3b18acd36 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java @@ -2,7 +2,10 @@ package org.jivesoftware.sparkimpl.certificates; import java.awt.HeadlessException; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; @@ -21,6 +24,7 @@ import javax.swing.table.DefaultTableModel; import org.jivesoftware.resource.Res; import org.jivesoftware.spark.ui.login.CertificateDialog; +import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.sparkimpl.settings.local.LocalPreferences; /** @@ -43,7 +47,7 @@ public abstract class CertManager { public abstract void deleteEntry(String alias) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException; public abstract void addOrRemoveFromExceptionList(boolean checked); - + protected abstract List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) throws KeyStoreException; public abstract boolean isOnExceptionList(CertificateModel cert); protected abstract void refreshCertTable(); @@ -148,5 +152,24 @@ public abstract class CertManager { new CertificateDialog(localPreferences, certModel, this, reason); } - + + protected KeyStore openKeyStore(File file){ + KeyStore keyStore = null; + try { + keyStore = KeyStore.getInstance("JKS"); + // checking if length >0 prevents EOFExceptions + if (file.exists() && !file.isDirectory() && file.length() > 0) { + try (InputStream inputStream = new FileInputStream(file)) { + keyStore.load(inputStream, passwd); + } catch (IOException | NoSuchAlgorithmException | CertificateException e) { + Log.error("Error at accesing exceptions KeyStore", e); + } + } else { + keyStore.load(null, passwd); // if cannot open KeyStore then new empty one will be created + } + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { + Log.warning("Cannot create exceptions KeyStore", e); + } + return keyStore; + } } diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java index 0f1fe0f2b..b30072734 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java @@ -69,56 +69,15 @@ public class CertificateController extends CertManager { */ @Override public void loadKeyStores() { - try { - trustStore = KeyStore.getInstance("JKS"); - // checking if length >0 prevents EOFExceptions - if (TRUSTED.exists() && !TRUSTED.isDirectory() && TRUSTED.length() > 0) { - try (InputStream inputStream = new FileInputStream(TRUSTED)) { - trustStore.load(inputStream, passwd); - trustedCertificates = fillTableListWithKeyStoreContent(trustStore, trustedCertificates); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore", e); - } - } else { - trustStore.load(null, passwd); // if cannot open KeyStore then new empty one will be created - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } - - try { - exceptionsStore = KeyStore.getInstance("JKS"); - if (EXCEPTIONS.exists() && !EXCEPTIONS.isDirectory() && EXCEPTIONS.length() > 0) { - try (InputStream inputStream = new FileInputStream(EXCEPTIONS)) { - exceptionsStore.load(inputStream, passwd); - exemptedCertificates = fillTableListWithKeyStoreContent(exceptionsStore, exemptedCertificates); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore", e); - } - } else { - exceptionsStore.load(null, passwd); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } - - try { - blackListStore = KeyStore.getInstance("JKS"); - if (BLACKLIST.exists() && !BLACKLIST.isDirectory() && BLACKLIST.length() > 0) { - try (InputStream inputStream = new FileInputStream(BLACKLIST)) { - blackListStore.load(inputStream, passwd); - blackListedCertificates = fillTableListWithKeyStoreContent(blackListStore, blackListedCertificates); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore", e); - } - } else { - blackListStore.load(null, passwd); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } + trustStore = openKeyStore(TRUSTED); + exceptionsStore = openKeyStore(EXCEPTIONS); + blackListStore = openKeyStore(BLACKLIST); + trustedCertificates = fillTableListWithKeyStoreContent(trustStore, trustedCertificates); + exemptedCertificates = fillTableListWithKeyStoreContent(exceptionsStore, exemptedCertificates); + blackListedCertificates = fillTableListWithKeyStoreContent(blackListStore, blackListedCertificates); + } - + @Override public void overWriteKeyStores() { try (OutputStream outputStream = new FileOutputStream(TRUSTED)) { @@ -252,20 +211,26 @@ public class CertificateController extends CertManager { * @param List list which will be filled with certificate models. * @throws KeyStoreException */ - - private List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) throws KeyStoreException { - Enumeration store = keyStore.aliases(); - while (store.hasMoreElements()) { - String alias = (String) store.nextElement(); - X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); - CertificateModel certModel = new CertificateModel(certificate, alias); - list.add(certModel); - allCertificates.add(certModel); + protected List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) { + if (keyStore != null) { + Enumeration store; + try { + store = keyStore.aliases(); + + while (store.hasMoreElements()) { + String alias = (String) store.nextElement(); + X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); + CertificateModel certModel = new CertificateModel(certificate, alias); + list.add(certModel); + allCertificates.add(certModel); + } + } catch (KeyStoreException e) { + Log.error("Cannot read KeyStore", e); } - - return list; - } + } + return list; + } /** * Return file path which contains certificate with given alias; diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java index 8fb42c542..31b1fe632 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java @@ -93,23 +93,9 @@ public class IdentityController extends CertManager { public void loadKeyStores() { - try { - idStore = KeyStore.getInstance("JKS"); - if (IDENTITY.exists() && !IDENTITY.isDirectory() && IDENTITY.length() > 0) { - try (InputStream inputStream = new FileInputStream(IDENTITY)) { - idStore.load(inputStream, passwd); - allCertificates = fillTableListWithKeyStoreContent(idStore, allCertificates); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore", e); - } - } else { - idStore.load(null, passwd); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } - - + idStore = openKeyStore(IDENTITY); + allCertificates = fillTableListWithKeyStoreContent(idStore, allCertificates); + } @Override @@ -161,17 +147,22 @@ public class IdentityController extends CertManager { } } - private List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) - throws KeyStoreException { + protected List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) { + if (keyStore != null) { + Enumeration store; + try { + store = keyStore.aliases(); - Enumeration store = keyStore.aliases(); - while (store.hasMoreElements()) { - String alias = (String) store.nextElement(); - X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); - CertificateModel certModel = new CertificateModel(certificate, alias); - list.add(certModel); + while (store.hasMoreElements()) { + String alias = (String) store.nextElement(); + X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); + CertificateModel certModel = new CertificateModel(certificate, alias); + list.add(certModel); + } + } catch (KeyStoreException e) { + Log.error("Cannot read KeyStore", e); + } } - return list; } diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java index 20aaea3bb..01a6552ae 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkExceptionsTrustManager.java @@ -25,29 +25,17 @@ import javax.net.ssl.X509TrustManager; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.jivesoftware.spark.util.log.Log; +import org.jivesoftware.sparkimpl.settings.local.LocalPreferences; +import org.jivesoftware.sparkimpl.settings.local.SettingsManager; public class SparkExceptionsTrustManager implements X509TrustManager { KeyStore exceptionsStore; private Provider bcProvider = new BouncyCastleProvider(); // bc provider for path validation - + private LocalPreferences localPref = SettingsManager.getLocalPreferences(); public SparkExceptionsTrustManager() { - - try { - exceptionsStore = KeyStore.getInstance("JKS"); - if (CertificateController.EXCEPTIONS.exists() && !CertificateController.EXCEPTIONS.isDirectory() - && CertificateController.EXCEPTIONS.length() > 0) { - try (InputStream inputStream = new FileInputStream(CertificateController.EXCEPTIONS)) { - exceptionsStore.load(inputStream, CertificateController.passwd); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore"); - } - } else { - exceptionsStore.load(null, CertificateController.passwd); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } + CertificateController certControll = new CertificateController(localPref); + exceptionsStore = certControll.openKeyStore(CertificateController.EXCEPTIONS); } diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java index 12068ce3d..43e653275 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/SparkTrustManager.java @@ -341,40 +341,10 @@ public class SparkTrustManager implements X509TrustManager { * loads truststore and potentially (depending on settings) blacklist */ private void loadTrustStore() { - try { - trustStore = KeyStore.getInstance("JKS"); - // checking if length >0 prevents EOFExceptions - if (CertificateController.TRUSTED.exists() && !CertificateController.TRUSTED.isDirectory() - && CertificateController.TRUSTED.length() > 0) { - try (InputStream inputStream = new FileInputStream(CertificateController.TRUSTED)) { - trustStore.load(inputStream, CertificateController.passwd); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore"); - } - } else { - trustStore.load(null, CertificateController.passwd); // if cannot open KeyStore then new empty one will - // be created - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } + trustStore = certControll.openKeyStore(CertificateController.TRUSTED); if (acceptRevoked) { - try { - blackStore = KeyStore.getInstance("JKS"); - if (CertificateController.BLACKLIST.exists() && !CertificateController.BLACKLIST.isDirectory() - && CertificateController.BLACKLIST.length() > 0) { - try (InputStream inputStream = new FileInputStream(CertificateController.BLACKLIST)) { - blackStore.load(inputStream, CertificateController.passwd); - } catch (IOException | NoSuchAlgorithmException | CertificateException e) { - Log.error("Error at accesing exceptions KeyStore"); - } - } else { - blackStore.load(null, CertificateController.passwd); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) { - Log.warning("Cannot create exceptions KeyStore", e); - } + blackStore = certControll.openKeyStore(CertificateController.BLACKLIST); } } From ca32089e9de247192b8e36836d4ed7af0db82e65 Mon Sep 17 00:00:00 2001 From: Alameyo Date: Sat, 19 Aug 2017 17:36:01 +0200 Subject: [PATCH 3/3] One more class, fillTableListWithKeyStoreContent() moved to the CertManager. --- .../sparkimpl/certificates/CertManager.java | 32 ++++++++++++++++++- .../certificates/CertificateController.java | 26 --------------- .../certificates/IdentityController.java | 23 +------------ 3 files changed, 32 insertions(+), 49 deletions(-) diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java index 3b18acd36..fb6ae6b90 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertManager.java @@ -13,6 +13,7 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.util.Base64; +import java.util.Enumeration; import java.util.LinkedList; import java.util.List; @@ -47,7 +48,6 @@ public abstract class CertManager { public abstract void deleteEntry(String alias) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException; public abstract void addOrRemoveFromExceptionList(boolean checked); - protected abstract List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) throws KeyStoreException; public abstract boolean isOnExceptionList(CertificateModel cert); protected abstract void refreshCertTable(); @@ -172,4 +172,34 @@ public abstract class CertManager { } return keyStore; } + + /** + * Add certificates from keyStore to list. Useful for displaying in certificate table. + * + * @param KeyStore source keystore. + * @param List list which will be filled with certificate models. + * @throws KeyStoreException + */ + + protected List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) { + if (keyStore != null) { + Enumeration store; + try { + store = keyStore.aliases(); + + while (store.hasMoreElements()) { + String alias = (String) store.nextElement(); + X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); + CertificateModel certModel = new CertificateModel(certificate, alias); + if (list != null) { + list.add(certModel); + } + allCertificates.add(certModel); + } + } catch (KeyStoreException e) { + Log.error("Cannot read KeyStore", e); + } + } + return list; + } } diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java index b30072734..5ed690c04 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/CertificateController.java @@ -204,33 +204,7 @@ public class CertificateController extends CertManager { return blackListedCertificates.contains(cert); } - /** - * Add certificates from keyStore to list. Useful for displaying in certificate table. - * - * @param KeyStore source keystore. - * @param List list which will be filled with certificate models. - * @throws KeyStoreException - */ - protected List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) { - if (keyStore != null) { - Enumeration store; - try { - store = keyStore.aliases(); - - while (store.hasMoreElements()) { - String alias = (String) store.nextElement(); - X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); - CertificateModel certModel = new CertificateModel(certificate, alias); - list.add(certModel); - allCertificates.add(certModel); - } - } catch (KeyStoreException e) { - Log.error("Cannot read KeyStore", e); - } - } - return list; - } /** * Return file path which contains certificate with given alias; diff --git a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java index 31b1fe632..461d54bd6 100644 --- a/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java +++ b/core/src/main/java/org/jivesoftware/sparkimpl/certificates/IdentityController.java @@ -2,11 +2,9 @@ package org.jivesoftware.sparkimpl.certificates; import java.awt.HeadlessException; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.nio.file.Files; @@ -94,7 +92,7 @@ public class IdentityController extends CertManager { public void loadKeyStores() { idStore = openKeyStore(IDENTITY); - allCertificates = fillTableListWithKeyStoreContent(idStore, allCertificates); + fillTableListWithKeyStoreContent(idStore, null); } @@ -147,25 +145,6 @@ public class IdentityController extends CertManager { } } - protected List fillTableListWithKeyStoreContent(KeyStore keyStore, List list) { - if (keyStore != null) { - Enumeration store; - try { - store = keyStore.aliases(); - - while (store.hasMoreElements()) { - String alias = (String) store.nextElement(); - X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); - CertificateModel certModel = new CertificateModel(certificate, alias); - list.add(certModel); - } - } catch (KeyStoreException e) { - Log.error("Cannot read KeyStore", e); - } - } - return list; - } - @Override public void showCertificate() { CertificateDialog certDialog = new CertificateDialog(localPreferences,