diff --git a/kse/build.gradle b/kse/build.gradle index 8e3cf4877..02a4aef89 100644 --- a/kse/build.gradle +++ b/kse/build.gradle @@ -112,6 +112,8 @@ dependencies { implementation('org.violetlib:vaqua:11') implementation('io.github.java-diff-utils:java-diff-utils:4.12') implementation('org.openjdk.nashorn:nashorn-core:15.4') + implementation('com.fasterxml.jackson.jr:jackson-jr-objects:2.14.2') + implementation('com.fasterxml.jackson.jr:jackson-jr-annotation-support:2.14.2') testImplementation('org.assertj:assertj-core:3.23.1') testImplementation('org.junit.jupiter:junit-jupiter-api:5.9.0') diff --git a/kse/src/main/java/org/kse/KSE.java b/kse/src/main/java/org/kse/KSE.java index 960159141..951d80a11 100644 --- a/kse/src/main/java/org/kse/KSE.java +++ b/kse/src/main/java/org/kse/KSE.java @@ -40,7 +40,10 @@ import org.kse.gui.CreateApplicationGui; import org.kse.gui.CurrentDirectory; import org.kse.gui.error.DError; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; +import org.kse.gui.preferences.data.LanguageItem; +import org.kse.utilities.net.ProxySettingsUpdater; import org.kse.utilities.os.OperatingSystem; import org.kse.version.JavaVersion; import org.kse.version.Version; @@ -94,17 +97,19 @@ public static void main(String[] args) { setInstallDirProperty(); - ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); - setCurrentDirectory(applicationSettings); + KsePreferences preferences = PreferencesManager.getPreferences(); + setCurrentDirectory(preferences.getCurrentDirectory()); - String languageCode = applicationSettings.getLanguage(); - if (!ApplicationSettings.SYSTEM_LANGUAGE.equals(languageCode)) { - Locale.setDefault(new Locale(languageCode)); + ProxySettingsUpdater.updateSystem(preferences.getProxySettings()); + + String language = preferences.getLanguage(); + if (!language.equals(LanguageItem.SYSTEM_LANGUAGE)) { + Locale.setDefault(new Locale(language)); } initialiseSecurity(); - Pkcs12Util.setEncryptionStrength(applicationSettings.getPkcs12EncryptionSetting()); + Pkcs12Util.setEncryptionStrength(preferences.getPkcs12EncryptionSetting()); // list of files to open after start List parameterFiles = new ArrayList<>(); @@ -115,7 +120,7 @@ public static void main(String[] args) { } } - SwingUtilities.invokeLater(new CreateApplicationGui(applicationSettings, parameterFiles)); + SwingUtilities.invokeLater(new CreateApplicationGui(preferences, parameterFiles)); } catch (Throwable t) { DError dError = new DError(new JFrame(), t); dError.setLocationRelativeTo(null); @@ -156,11 +161,9 @@ private static void setInstallDirProperty() { System.setProperty("kse.install.dir", System.getProperty("user.dir")); } - private static void setCurrentDirectory(ApplicationSettings applicationSettings) { - File currentDirectory = applicationSettings.getCurrentDirectory(); - - if (currentDirectory != null) { - CurrentDirectory.update(currentDirectory); + private static void setCurrentDirectory(String currentDir) { + if (currentDir != null) { + CurrentDirectory.update(new File(currentDir)); } } diff --git a/kse/src/main/java/org/kse/crypto/csr/pkcs12/Pkcs12Util.java b/kse/src/main/java/org/kse/crypto/csr/pkcs12/Pkcs12Util.java index 39abe51dd..15fe65cca 100644 --- a/kse/src/main/java/org/kse/crypto/csr/pkcs12/Pkcs12Util.java +++ b/kse/src/main/java/org/kse/crypto/csr/pkcs12/Pkcs12Util.java @@ -20,7 +20,7 @@ package org.kse.crypto.csr.pkcs12; -import org.kse.gui.preferences.Pkcs12EncryptionSetting; +import org.kse.gui.preferences.data.Pkcs12EncryptionSetting; /** * Provides utility methods relating to PKCS #12 containers. diff --git a/kse/src/main/java/org/kse/crypto/keystore/KeyStoreUtil.java b/kse/src/main/java/org/kse/crypto/keystore/KeyStoreUtil.java index 17f9bd00d..63e69077a 100644 --- a/kse/src/main/java/org/kse/crypto/keystore/KeyStoreUtil.java +++ b/kse/src/main/java/org/kse/crypto/keystore/KeyStoreUtil.java @@ -48,11 +48,11 @@ import java.util.Enumeration; import java.util.ResourceBundle; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.KSE; import org.kse.crypto.CryptoException; import org.kse.crypto.Password; import org.kse.crypto.filetype.CryptoFileUtil; +import org.kse.gui.preferences.PreferencesManager; /** * Provides utility methods for loading/saving KeyStores. The BouncyCastle @@ -230,7 +230,7 @@ public static boolean areMsCapiStoresSupported() { public static KeyStore loadMsCapiStore(MsCapiStoreType msCapiStoreType) throws CryptoException { if (!areMsCapiStoresSupported()) { // May previously have been set on an MSCAPI supporting JRE - ApplicationSettings.getInstance().setUseWindowsTrustedRootCertificates(false); + PreferencesManager.getPreferences().getCaCertsSettings().setUseWindowsTrustedRootCertificates(false); throw new CryptoException(res.getString("MsCapiStoresNotSupported.exception.message")); } diff --git a/kse/src/main/java/org/kse/crypto/x509/X509CertUtil.java b/kse/src/main/java/org/kse/crypto/x509/X509CertUtil.java index 7e5e668a8..ecbc37cbf 100644 --- a/kse/src/main/java/org/kse/crypto/x509/X509CertUtil.java +++ b/kse/src/main/java/org/kse/crypto/x509/X509CertUtil.java @@ -58,7 +58,7 @@ import org.kse.KSE; import org.kse.crypto.CryptoException; import org.kse.crypto.signing.SignatureType; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.PreferencesManager; import org.kse.utilities.SerialNumbers; import org.kse.utilities.StringUtils; import org.kse.utilities.io.HexUtil; @@ -754,7 +754,7 @@ public static String getSerialNumberAsDec(X509Certificate cert) { * @return Serial number as hex string with "0x" prefix */ public static String generateCertSerialNumber() { - int snLength = ApplicationSettings.getInstance().getSerialNumberLengthInBytes(); + int snLength = PreferencesManager.getPreferences().getSerialNumberLengthInBytes(); return HexUtil.getHexString(SerialNumbers.generate(snLength), "0x", 0, 0); } } diff --git a/kse/src/main/java/org/kse/gui/CreateApplicationGui.java b/kse/src/main/java/org/kse/gui/CreateApplicationGui.java index ccb42dc55..a65757ae1 100644 --- a/kse/src/main/java/org/kse/gui/CreateApplicationGui.java +++ b/kse/src/main/java/org/kse/gui/CreateApplicationGui.java @@ -30,7 +30,6 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.AuthorityCertificates; import org.kse.KSE; import org.kse.crypto.jcepolicy.JcePolicyUtil; @@ -38,6 +37,7 @@ import org.kse.gui.crypto.DUpgradeCryptoStrength; import org.kse.gui.dnd.DroppedFileHandler; import org.kse.gui.error.DError; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.os.OperatingSystem; import org.kse.version.JavaVersion; import org.kse.version.VersionException; @@ -51,17 +51,17 @@ public class CreateApplicationGui implements Runnable { private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/resources"); private static final JavaVersion MIN_JRE_VERSION = JavaVersion.JRE_VERSION_180; - private ApplicationSettings applicationSettings; + private KsePreferences ksePreferences; private List parameterFiles; /** * Construct CreateApplicationGui. * - * @param applicationSettings Application settings + * @param ksePreferences Application settings * @param parameterFiles File list to open */ - public CreateApplicationGui(ApplicationSettings applicationSettings, List parameterFiles) { - this.applicationSettings = applicationSettings; + public CreateApplicationGui(KsePreferences ksePreferences, List parameterFiles) { + this.ksePreferences = ksePreferences; this.parameterFiles = parameterFiles; } @@ -75,7 +75,7 @@ public void run() { System.exit(1); } - initLookAndFeel(applicationSettings); + initLookAndFeel(ksePreferences); // try to remove crypto restrictions JcePolicyUtil.removeRestrictions(); @@ -119,7 +119,7 @@ public void run() { private void checkCaCerts(final KseFrame kseFrame) { - File caCertificatesFile = applicationSettings.getCaCertificatesFile(); + File caCertificatesFile = new File(ksePreferences.getCaCertsSettings().getCaCertificatesFile()); if (caCertificatesFile.exists()) { return; @@ -136,7 +136,7 @@ private void checkCaCerts(final KseFrame kseFrame) { KSE.getApplicationName(), JOptionPane.YES_NO_OPTION); if (selected == JOptionPane.YES_OPTION) { - applicationSettings.setCaCertificatesFile(newCaCertsFile); + ksePreferences.getCaCertsSettings().setCaCertificatesFile(newCaCertsFile.getAbsolutePath()); } }); } @@ -152,7 +152,7 @@ private void checkForUpdates(final KseFrame kseFrame) { }).start(); } - private static void initLookAndFeel(ApplicationSettings applicationSettings) { + private static void initLookAndFeel(KsePreferences applicationSettings) { LnfUtil.installLnfs(); String lookFeelClassName = applicationSettings.getLookAndFeelClass(); @@ -163,7 +163,7 @@ private static void initLookAndFeel(ApplicationSettings applicationSettings) { } LnfUtil.useLnf(lookFeelClassName); - boolean lookFeelDecorated = applicationSettings.getLookAndFeelDecorated(); + boolean lookFeelDecorated = applicationSettings.isLookAndFeelDecorated(); JFrame.setDefaultLookAndFeelDecorated(lookFeelDecorated); JDialog.setDefaultLookAndFeelDecorated(lookFeelDecorated); diff --git a/kse/src/main/java/org/kse/gui/FileChooserFactory.java b/kse/src/main/java/org/kse/gui/FileChooserFactory.java index 00927c21c..b3641edc0 100644 --- a/kse/src/main/java/org/kse/gui/FileChooserFactory.java +++ b/kse/src/main/java/org/kse/gui/FileChooserFactory.java @@ -26,7 +26,7 @@ import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.PreferencesManager; import org.kse.utilities.os.OperatingSystem; /** @@ -428,7 +428,7 @@ private static JFileChooser getFileChooser() { JFileChooser fileChooser = JavaFXFileChooser.isFxAvailable() ? new JavaFXFileChooser() : new JFileChooser(); // show/hide hidden files - fileChooser.setFileHidingEnabled(!ApplicationSettings.getInstance().isShowHiddenFilesEnabled()); + fileChooser.setFileHidingEnabled(!PreferencesManager.getPreferences().isShowHiddenFilesEnabled()); return fileChooser; } diff --git a/kse/src/main/java/org/kse/gui/JKseTable.java b/kse/src/main/java/org/kse/gui/JKseTable.java index a52103577..015b002d4 100644 --- a/kse/src/main/java/org/kse/gui/JKseTable.java +++ b/kse/src/main/java/org/kse/gui/JKseTable.java @@ -107,35 +107,35 @@ public void colAdjust(KeyStoreTableColumns keyStoreTableColumns, int autoResizeM } int l = width; - if (i == keyStoreTableColumns.colEntryName()) { + if (i == keyStoreTableColumns.colIndexEntryName()) { column.setMinWidth((2 + res.getString("KeyStoreTableModel.NameColumn")).length() * iFontSize); column.setPreferredWidth( Math.max(1 + res.getString("KeyStoreTableModel.NameColumn").length(), 20) * iFontSize); column.setMaxWidth( Math.max(2 + res.getString("KeyStoreTableModel.NameColumn").length(), 50) * iFontSize); } - if (i == keyStoreTableColumns.colAlgorithm()) { + if (i == keyStoreTableColumns.colIndexAlgorithm()) { column.setMinWidth((4) * iFontSize); column.setPreferredWidth( Math.max(1 + res.getString("KeyStoreTableModel.AlgorithmColumn").length(), 4) * iFontSize); column.setMaxWidth( Math.max(2 + res.getString("KeyStoreTableModel.AlgorithmColumn").length(), 5) * iFontSize); } - if (i == keyStoreTableColumns.colKeySize()) { + if (i == keyStoreTableColumns.colIndexKeySize()) { column.setMinWidth((4) * iFontSize); column.setPreferredWidth( Math.max(1 + res.getString("KeyStoreTableModel.KeySizeColumn").length(), (l + 1)) * iFontSize); column.setMaxWidth( Math.max(2 + res.getString("KeyStoreTableModel.KeySizeColumn").length(), l + 1) * iFontSize); } - if (i == keyStoreTableColumns.colCurve()) { + if (i == keyStoreTableColumns.colIndexCurve()) { column.setMinWidth(8 * iFontSize); column.setPreferredWidth( 1 + Math.max(res.getString("KeyStoreTableModel.CurveColumn").length(), l) * iFontSize); column.setMaxWidth(2 + Math.max("brainpool999r1".length(), res.getString("KeyStoreTableModel.CurveColumn").length()) * iFontSize); } - if (i == keyStoreTableColumns.colCertificateExpiry()) { + if (i == keyStoreTableColumns.colIndexCertificateExpiry()) { l = "20.00.2000 00:00:00 MESZ".length(); column.setMinWidth("20.00.2000".length() * iFontSize); column.setPreferredWidth( @@ -143,7 +143,7 @@ public void colAdjust(KeyStoreTableColumns keyStoreTableColumns, int autoResizeM column.setMaxWidth( 2 + Math.max(res.getString("KeyStoreTableModel.CertExpiryColumn").length(), l) * iFontSize); } - if (i == keyStoreTableColumns.colLastModified()) { + if (i == keyStoreTableColumns.colIndexLastModified()) { l = "20.09.2000 00:00:00 MESZ".length(); column.setMinWidth("20.00.2000".length() * iFontSize); column.setPreferredWidth( @@ -151,7 +151,7 @@ public void colAdjust(KeyStoreTableColumns keyStoreTableColumns, int autoResizeM column.setMaxWidth( 2 + Math.max(res.getString("KeyStoreTableModel.LastModifiedColumn").length(), l) * iFontSize); } - if (i == keyStoreTableColumns.colAKI()) { + if (i == keyStoreTableColumns.colIndexAKI()) { l = 41; column.setMinWidth(8 * iFontSize); column.setPreferredWidth( @@ -159,7 +159,7 @@ public void colAdjust(KeyStoreTableColumns keyStoreTableColumns, int autoResizeM column.setMaxWidth( Math.max(2 + res.getString("KeyStoreTableModel.AKIColumn").length(), (l + 1)) * iFontSize); } - if (i == keyStoreTableColumns.colSKI()) { + if (i == keyStoreTableColumns.colIndexSKI()) { l = 41; column.setMinWidth(8 * iFontSize); column.setPreferredWidth( @@ -167,19 +167,19 @@ public void colAdjust(KeyStoreTableColumns keyStoreTableColumns, int autoResizeM column.setMaxWidth( Math.max(2 + res.getString("KeyStoreTableModel.SKIColumn").length(), (l + 1)) * iFontSize); } - if (i == keyStoreTableColumns.colIssuerCN()) { + if (i == keyStoreTableColumns.colIndexIssuerCN()) { column.setMinWidth(8 * iFontSize); column.setPreferredWidth( Math.max(2 + res.getString("KeyStoreTableModel.IssuerCNColumn").length(), (l + 1)) * iFontSize); column.setMaxWidth(100 * iFontSize); } - if (i == keyStoreTableColumns.colIssuerDN()) { + if (i == keyStoreTableColumns.colIndexIssuerDN()) { column.setMinWidth(8 * iFontSize); column.setPreferredWidth( Math.max(2 + res.getString("KeyStoreTableModel.IssuerDNColumn").length(), (l + 1)) * iFontSize); column.setMaxWidth(100 * iFontSize); } - if (i == keyStoreTableColumns.colIssuerO()) { + if (i == keyStoreTableColumns.colIndexIssuerO()) { column.setMinWidth(8 * iFontSize); column.setPreferredWidth( Math.max(2 + res.getString("KeyStoreTableModel.IssuerOColumn").length(), (l + 1)) * iFontSize); diff --git a/kse/src/main/java/org/kse/gui/JMenuRecentFiles.java b/kse/src/main/java/org/kse/gui/JMenuRecentFiles.java index 49b4003d6..b714d7c6c 100644 --- a/kse/src/main/java/org/kse/gui/JMenuRecentFiles.java +++ b/kse/src/main/java/org/kse/gui/JMenuRecentFiles.java @@ -38,16 +38,11 @@ public class JMenuRecentFiles extends JMenu { * Construct a JMenuRecentFiles. * * @param title Title of menu - * @param length Length of recent files list to maintain */ - public JMenuRecentFiles(String title, int length) { + public JMenuRecentFiles(String title) { super(title); - if (length > MAX_LENGTH) { - length = MAX_LENGTH; - } - - jmiRecentFiles = new JMenuItemRecentFile[length]; + jmiRecentFiles = new JMenuItemRecentFile[MAX_LENGTH]; } private void removeAllRecentFiles() { @@ -106,19 +101,15 @@ public void add(JMenuItemRecentFile jmirfNew) { // Item already exists outside first position if (index != -1) { - // Introduce it to the first position and move the others up over - // its old position + // Introduce it to the first position and move the others up over its old position for (int i = 0; i <= index; i++) { JMenuItemRecentFile jmirfTmp = jmiRecentFiles[i]; jmiRecentFiles[i] = jmirfNew; jmirfNew = jmirfTmp; jmirfNew.setPosition(i + 2); } - } - // Item does not exist in the menu - else { - // Introduce new item to the start of the list and shift the others - // up one + } else { + // Introduce new item to the start of the list and shift the others up one for (int i = 0; i < jmiRecentFiles.length; i++) { JMenuItemRecentFile jmirfTmp = jmiRecentFiles[i]; jmiRecentFiles[i] = jmirfNew; diff --git a/kse/src/main/java/org/kse/gui/KeyStoreTableColumns.java b/kse/src/main/java/org/kse/gui/KeyStoreTableColumns.java index 90b491788..e608ea7d7 100644 --- a/kse/src/main/java/org/kse/gui/KeyStoreTableColumns.java +++ b/kse/src/main/java/org/kse/gui/KeyStoreTableColumns.java @@ -21,456 +21,342 @@ import java.util.stream.Stream; +import com.fasterxml.jackson.annotation.JsonIgnore; + /** * POJO class to configure the cells shown in the KeyStore table of KeyStore Explorer. */ public class KeyStoreTableColumns { - private int expiryWarnDays; - private boolean bEnableEntryName; - private boolean bEnableAlgorithm; - private boolean bEnableKeySize; - private boolean bEnableCertificateValidityStart; - private boolean bEnableCertificateExpiry; - private boolean bEnableLastModified; - private boolean bEnableSKI; - private boolean bEnableAKI; - private boolean bEnableIssuerDN; - private boolean bEnableSubjectDN; - private boolean bEnableIssuerCN; - private boolean bEnableSubjectCN; - private boolean bEnableIssuerO; - private boolean bEnableSubjectO; - private boolean bEnableCurve; - private boolean bEnableSerialNumberHex; - private boolean bEnableSerialNumberDec; + + private boolean enableEntryName = true; + private boolean enableAlgorithm = true; + private boolean enableKeySize = true; + private boolean enableCertificateValidityStart = false; + private boolean enableCertificateExpiry = true; + private boolean enableLastModified = true; + private boolean enableSKI = false; + private boolean enableAKI = false; + private boolean enableIssuerDN = false; + private boolean enableSubjectDN = false; + private boolean enableCurve = false; + private boolean enableIssuerCN = false; + private boolean enableSubjectCN = false; + private boolean enableIssuerO = false; + private boolean enableSubjectO = false; + private boolean enableSerialNumberHex = false; + private boolean enableSerialNumberDec = false; + /** - * Column for a property + * Get number of activated columns. The actual table has 3 columns more, as the first 3 are fixed. + * + * @return number of columns selected */ - private int iNameColumn = -1; - private int iAlgorithmColumn = -1; - private int iKeySizeColumn = -1; - private int iCurveColumn = -1; - private int iCertValidityStartColumn = -1; - private int iCertExpiryColumn = -1; - private int iLastModifiedColumn = -1; - private int iAKIColumn = -1; - private int iSKIColumn = -1; - private int iIssuerDNColumn = -1; - private int iSubjectDNColumn = -1; - private int iIssuerCNColumn = -1; - private int iSubjectCNColumn = -1; - private int iIssuerOColumn = -1; - private int iSubjectOColumn = -1; - private int iSerialNumberHexColumn = -1; - private int iSerialNumberDecColumn = -1; - - // As default set to previous layout from older KSE versions - public KeyStoreTableColumns() { - expiryWarnDays = 0; - bEnableEntryName = true; - bEnableAlgorithm = true; - bEnableKeySize = true; - bEnableCertificateValidityStart = false; - bEnableCertificateExpiry = true; - bEnableLastModified = true; - bEnableSKI = false; - bEnableAKI = false; - bEnableIssuerDN = false; - bEnableSubjectDN = false; - bEnableCurve = false; - bEnableIssuerCN = false; - bEnableSubjectCN = false; - bEnableIssuerO = false; - bEnableSubjectO = false; - bEnableSerialNumberHex = false; - bEnableSerialNumberDec = false; - } - - public KeyStoreTableColumns(boolean bEnableEntryName, boolean bEnableAlgorithm, boolean bEnableKeySize, - boolean bEnableCertificateValidityStart, boolean bEnableCertificateExpiry, - boolean bEnableLastModified, boolean bEnableSKI, boolean bEnableAKI, - boolean bEnableIssuerDN, boolean bEnableSubjectDN, boolean bEnableIssuerCN, - boolean bEnableSubjectCN, boolean bEnableIssuerO, boolean bEnableSubjectO, - boolean bEnableCurve, int expiryWarnDays, boolean bEnableSerialNumberHex, - boolean bEnableSerialNumberDec) { - super(); - this.bEnableEntryName = bEnableEntryName; - this.bEnableAlgorithm = bEnableAlgorithm; - this.bEnableKeySize = bEnableKeySize; - this.bEnableCertificateValidityStart = bEnableCertificateValidityStart; - this.bEnableCertificateExpiry = bEnableCertificateExpiry; - this.bEnableLastModified = bEnableLastModified; - this.bEnableSKI = bEnableSKI; - this.bEnableAKI = bEnableAKI; - this.bEnableIssuerDN = bEnableIssuerDN; - this.bEnableSubjectDN = bEnableSubjectDN; - this.bEnableIssuerCN = bEnableIssuerCN; - this.bEnableSubjectCN = bEnableSubjectCN; - this.bEnableIssuerO = bEnableIssuerO; - this.bEnableSubjectO = bEnableSubjectO; - this.bEnableCurve = bEnableCurve; - this.expiryWarnDays = expiryWarnDays; - this.bEnableSerialNumberHex = bEnableSerialNumberHex; - this.bEnableSerialNumberDec = bEnableSerialNumberDec; - sortCol(); - } - - private void sortCol() { - int col = 2; - iNameColumn = -1; - iAlgorithmColumn = -1; - iKeySizeColumn = -1; - iCurveColumn = -1; - iCertValidityStartColumn = -1; - iCertExpiryColumn = -1; - iLastModifiedColumn = -1; - iAKIColumn = -1; - iSKIColumn = -1; - iIssuerDNColumn = -1; - iSubjectDNColumn = -1; - iIssuerCNColumn = -1; - iSubjectCNColumn = -1; - iIssuerOColumn = -1; - iSubjectOColumn = -1; - iSerialNumberHexColumn = -1; - iSerialNumberDecColumn = -1; - - if (bEnableEntryName) { - iNameColumn = ++col; - } - if (bEnableAlgorithm) { - iAlgorithmColumn = ++col; - } - if (bEnableKeySize) { - iKeySizeColumn = ++col; - } - if (bEnableCurve) { - iCurveColumn = ++col; - } - if (bEnableCertificateValidityStart) { - iCertValidityStartColumn = ++col; - } - if (bEnableCertificateExpiry) { - iCertExpiryColumn = ++col; - } - if (bEnableLastModified) { - iLastModifiedColumn = ++col; - } - if (bEnableAKI) { - iAKIColumn = ++col; - } - if (bEnableSKI) { - iSKIColumn = ++col; - } - if (bEnableIssuerDN) { - iIssuerDNColumn = ++col; - } - if (bEnableSubjectDN) { - iSubjectDNColumn = ++col; - } - if (bEnableIssuerCN) { - iIssuerCNColumn = ++col; - } - if (bEnableSubjectCN) { - iSubjectCNColumn = ++col; - } - if (bEnableIssuerO) { - iIssuerOColumn = ++col; - } - if (bEnableSubjectO) { - iSubjectOColumn = ++col; - } - if (bEnableSerialNumberHex) { - iSerialNumberHexColumn = ++col; - } - if (bEnableSerialNumberDec) { - iSerialNumberDecColumn = ++col; - } + @JsonIgnore + public int getNofColumns() { + return Stream.of(enableEntryName, enableAlgorithm, enableKeySize, enableCertificateValidityStart, + enableCertificateExpiry, enableLastModified, enableSKI, enableAKI, enableIssuerDN, + enableSubjectDN, enableCurve, enableIssuerCN, enableSubjectCN, enableIssuerO, enableSubjectO, + enableSerialNumberHex, enableSerialNumberDec + ).mapToInt(b -> b ? 1 : 0).sum(); } - public void setColumns(boolean bEnableEntryName, boolean bEnableAlgorithm, boolean bEnableKeySize, - boolean bEnableCertificateValidityStart, boolean bEnableCertificateExpiry, - boolean bEnableLastModified, boolean bEnableSKI, boolean bEnableAKI, boolean bEnableIssuerDN, - boolean bEnableSubjectDN, boolean bEnableIssuerCN, boolean bEnableSubjectCN, - boolean bEnableIssuerO, boolean bEnableSubjectO, boolean bEnableCurve, - boolean bEnableSerialNumberHex, boolean bEnableSerialNumberDec, int expiryWarnDays) { - this.bEnableEntryName = bEnableEntryName; - this.bEnableAlgorithm = bEnableAlgorithm; - this.bEnableKeySize = bEnableKeySize; - this.bEnableCertificateValidityStart = bEnableCertificateValidityStart; - this.bEnableCertificateExpiry = bEnableCertificateExpiry; - this.bEnableLastModified = bEnableLastModified; - this.bEnableSKI = bEnableSKI; - this.bEnableAKI = bEnableAKI; - this.bEnableIssuerDN = bEnableIssuerDN; - this.bEnableSubjectDN = bEnableSubjectDN; - this.bEnableIssuerCN = bEnableIssuerCN; - this.bEnableSubjectCN = bEnableSubjectCN; - this.bEnableIssuerO = bEnableIssuerO; - this.bEnableSubjectO = bEnableSubjectO; - this.bEnableCurve = bEnableCurve; - this.bEnableSerialNumberHex = bEnableSerialNumberHex; - this.bEnableSerialNumberDec = bEnableSerialNumberDec; - this.expiryWarnDays = expiryWarnDays; - sortCol(); + private int calculateActualColumnIndex(int originalIndex) { + // convert from original index of column to index for actually enabled columns; columns 0-2 are fixed + return 2 + Stream.of(enableEntryName, enableAlgorithm, enableKeySize, enableCurve, + enableCertificateValidityStart, enableCertificateExpiry, enableLastModified, enableAKI, + enableSKI, enableIssuerDN, enableSubjectDN, enableIssuerCN, enableSubjectCN, enableIssuerO, + enableSubjectO, enableSerialNumberHex, enableSerialNumberDec) + .mapToInt(b -> b ? 1 : 0) + .limit(originalIndex) + .sum(); } - /** - * Restore from bitmap - * - * @param col - */ - public void setColumns(int col) { - - bEnableEntryName = ((col & 1 << 0) != 0); - bEnableAlgorithm = ((col & 1 << 1) != 0); - bEnableKeySize = ((col & 1 << 2) != 0); - bEnableCertificateExpiry = ((col & 1 << 3) != 0); - bEnableLastModified = ((col & 1 << 4) != 0); - bEnableSKI = ((col & 1 << 5) != 0); - bEnableAKI = ((col & 1 << 6) != 0); - bEnableIssuerDN = ((col & 1 << 7) != 0); - bEnableSubjectDN = ((col & 1 << 8) != 0); - bEnableCurve = ((col & 1 << 9) != 0); - bEnableIssuerCN = ((col & 1 << 10) != 0); - bEnableSubjectCN = ((col & 1 << 11) != 0); - bEnableIssuerO = ((col & 1 << 12) != 0); - bEnableSubjectO = ((col & 1 << 13) != 0); - bEnableSerialNumberHex = ((col & 1 << 14) != 0); - bEnableSerialNumberDec = ((col & 1 << 15) != 0); - bEnableCertificateValidityStart = ((col & 1 << 16) != 0); - sortCol(); + public int colIndexEntryName() { + return calculateActualColumnIndex(1); } - /** - * Get as bitmap - * - * @return col - */ - public int getColumns() { - int col = 0; - if (bEnableEntryName) { - col += 1 << 0; - } - if (bEnableAlgorithm) { - col += 1 << 1; - } - if (bEnableKeySize) { - col += 1 << 2; - } - if (bEnableCertificateExpiry) { - col += 1 << 3; - } - if (bEnableLastModified) { - col += 1 << 4; - } - if (bEnableSKI) { - col += 1 << 5; - } - if (bEnableAKI) { - col += 1 << 6; - } - if (bEnableIssuerDN) { - col += 1 << 7; - } - if (bEnableSubjectDN) { - col += 1 << 8; - } - if (bEnableCurve) { - col += 1 << 9; - } - if (bEnableIssuerCN) { - col += 1 << 10; - } - if (bEnableSubjectCN) { - col += 1 << 11; - } - if (bEnableIssuerO) { - col += 1 << 12; - } - if (bEnableSubjectO) { - col += 1 << 13; - } - if (bEnableSerialNumberHex) { - col += 1 << 14; - } - if (bEnableSerialNumberDec) { - col += 1 << 15; - } - if (bEnableCertificateValidityStart) { - col += 1 << 16; - } - return col; + public int colIndexAlgorithm() { + return calculateActualColumnIndex(2); } - /** - * Get number of columns selected. The actual table has 3 columns more, as the first 3 are fixed. - * - * @return number of columns selected - */ - public int getNofColumns() { - return Stream.of( - bEnableEntryName, - bEnableAlgorithm, - bEnableKeySize, - bEnableCertificateValidityStart, - bEnableCertificateExpiry, - bEnableLastModified, - bEnableSKI, - bEnableAKI, - bEnableIssuerDN, - bEnableSubjectDN, - bEnableCurve, - bEnableIssuerCN, - bEnableSubjectCN, - bEnableIssuerO, - bEnableSubjectO, - bEnableSerialNumberHex, - bEnableSerialNumberDec - ).mapToInt(b -> b ? 1 : 0).sum(); + public int colIndexKeySize() { + return calculateActualColumnIndex(3); + } + + public int colIndexCurve() { + return calculateActualColumnIndex(4); + } + + public int colIndexCertificateValidityStart() { + return calculateActualColumnIndex(5); + } + + public int colIndexCertificateExpiry() { + return calculateActualColumnIndex(6); + } + + public int colIndexLastModified() { + return calculateActualColumnIndex(7); + } + + public int colIndexAKI() { + return calculateActualColumnIndex(8); + } + + public int colIndexSKI() { + return calculateActualColumnIndex(9); + } + + public int colIndexIssuerDN() { + return calculateActualColumnIndex(10); + } + + public int colIndexSubjectDN() { + return calculateActualColumnIndex(11); + } + + public int colIndexIssuerCN() { + return calculateActualColumnIndex(12); + } + + public int colIndexSubjectCN() { + return calculateActualColumnIndex(13); + } + + public int colIndexIssuerO() { + return calculateActualColumnIndex(14); + } + + public int colIndexSubjectO() { + return calculateActualColumnIndex(15); } + public int colIndexSerialNumberHex() { + return calculateActualColumnIndex(16); + } + + public int colIndexSerialNumberDec() { + return calculateActualColumnIndex(17); + } + + public boolean getEnableEntryName() { - return bEnableEntryName; + return enableEntryName; } public boolean getEnableAlgorithm() { - return bEnableAlgorithm; + return enableAlgorithm; } public boolean getEnableKeySize() { - return bEnableKeySize; + return enableKeySize; } public boolean getEnableCertificateValidityStart() { - return bEnableCertificateValidityStart; + return enableCertificateValidityStart; } public boolean getEnableCertificateExpiry() { - return bEnableCertificateExpiry; + return enableCertificateExpiry; } public boolean getEnableLastModified() { - return bEnableLastModified; + return enableLastModified; } public boolean getEnableSKI() { - return bEnableSKI; + return enableSKI; } public boolean getEnableAKI() { - return bEnableAKI; + return enableAKI; } public boolean getEnableCurve() { - return bEnableCurve; + return enableCurve; } public boolean getEnableIssuerDN() { - return bEnableIssuerDN; + return enableIssuerDN; } public boolean getEnableSubjectDN() { - return bEnableSubjectDN; + return enableSubjectDN; } public boolean getEnableIssuerCN() { - return bEnableIssuerCN; + return enableIssuerCN; } public boolean getEnableSubjectCN() { - return bEnableSubjectCN; + return enableSubjectCN; } public boolean getEnableIssuerO() { - return bEnableIssuerO; + return enableIssuerO; } public boolean getEnableSubjectO() { - return bEnableSubjectO; + return enableSubjectO; } - public boolean getbEnableSerialNumberHex() { - return bEnableSerialNumberHex; + public boolean getEnableSerialNumberHex() { + return enableSerialNumberHex; } - public boolean getbEnableSerialNumberDec() { - return bEnableSerialNumberDec; + public boolean getEnableSerialNumberDec() { + return enableSerialNumberDec; } - public int getExpiryWarnDays() { - return expiryWarnDays; + public void setEnableEntryName(boolean enableEntryName) { + this.enableEntryName = enableEntryName; } - public void setExpiryWarnDays(int expiryWarnDays) { - this.expiryWarnDays = expiryWarnDays; + public void setEnableAlgorithm(boolean enableAlgorithm) { + this.enableAlgorithm = enableAlgorithm; } - public int colEntryName() { - return iNameColumn; + public void setEnableKeySize(boolean enableKeySize) { + this.enableKeySize = enableKeySize; } - public int colAlgorithm() { - return iAlgorithmColumn; + public void setEnableCertificateValidityStart(boolean enableCertificateValidityStart) { + this.enableCertificateValidityStart = enableCertificateValidityStart; } - public int colKeySize() { - return iKeySizeColumn; + public void setEnableCertificateExpiry(boolean enableCertificateExpiry) { + this.enableCertificateExpiry = enableCertificateExpiry; } - public int colCertificateValidityStart() { - return iCertValidityStartColumn; + public void setEnableLastModified(boolean enableLastModified) { + this.enableLastModified = enableLastModified; } - public int colCertificateExpiry() { - return iCertExpiryColumn; + public void setEnableSKI(boolean enableSKI) { + this.enableSKI = enableSKI; } - public int colLastModified() { - return iLastModifiedColumn; + public void setEnableAKI(boolean enableAKI) { + this.enableAKI = enableAKI; } - public int colSKI() { - return iSKIColumn; + public void setEnableIssuerDN(boolean enableIssuerDN) { + this.enableIssuerDN = enableIssuerDN; } - public int colAKI() { - return iAKIColumn; + public void setEnableSubjectDN(boolean enableSubjectDN) { + this.enableSubjectDN = enableSubjectDN; } - public int colCurve() { - return iCurveColumn; + public void setEnableCurve(boolean enableCurve) { + this.enableCurve = enableCurve; } - public int colIssuerDN() { - return iIssuerDNColumn; + public void setEnableIssuerCN(boolean enableIssuerCN) { + this.enableIssuerCN = enableIssuerCN; } - public int colSubjectDN() { - return iSubjectDNColumn; + public void setEnableSubjectCN(boolean enableSubjectCN) { + this.enableSubjectCN = enableSubjectCN; } - public int colIssuerCN() { - return iIssuerCNColumn; + public void setEnableIssuerO(boolean enableIssuerO) { + this.enableIssuerO = enableIssuerO; } - public int colSubjectCN() { - return iSubjectCNColumn; + public void setEnableSubjectO(boolean enableSubjectO) { + this.enableSubjectO = enableSubjectO; } - public int colIssuerO() { - return iIssuerOColumn; + public void setEnableSerialNumberHex(boolean enableSerialNumberHex) { + this.enableSerialNumberHex = enableSerialNumberHex; } - public int colSubjectO() { - return iSubjectOColumn; + public void setEnableSerialNumberDec(boolean enableSerialNumberDec) { + this.enableSerialNumberDec = enableSerialNumberDec; } - public int colSerialNumberHex() { - return iSerialNumberHexColumn; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + KeyStoreTableColumns that = (KeyStoreTableColumns) o; + + if (enableEntryName != that.enableEntryName) { + return false; + } + if (enableAlgorithm != that.enableAlgorithm) { + return false; + } + if (enableKeySize != that.enableKeySize) { + return false; + } + if (enableCertificateValidityStart != that.enableCertificateValidityStart) { + return false; + } + if (enableCertificateExpiry != that.enableCertificateExpiry) { + return false; + } + if (enableLastModified != that.enableLastModified) { + return false; + } + if (enableSKI != that.enableSKI) { + return false; + } + if (enableAKI != that.enableAKI) { + return false; + } + if (enableIssuerDN != that.enableIssuerDN) { + return false; + } + if (enableSubjectDN != that.enableSubjectDN) { + return false; + } + if (enableCurve != that.enableCurve) { + return false; + } + if (enableIssuerCN != that.enableIssuerCN) { + return false; + } + if (enableSubjectCN != that.enableSubjectCN) { + return false; + } + if (enableIssuerO != that.enableIssuerO) { + return false; + } + if (enableSubjectO != that.enableSubjectO) { + return false; + } + if (enableSerialNumberHex != that.enableSerialNumberHex) { + return false; + } + return enableSerialNumberDec == that.enableSerialNumberDec; } - public int colSerialNumberDec() { - return iSerialNumberDecColumn; + @Override + public int hashCode() { + int result = (enableEntryName ? 1 : 0); + result = 31 * result + (enableAlgorithm ? 1 : 0); + result = 31 * result + (enableKeySize ? 1 : 0); + result = 31 * result + (enableCertificateValidityStart ? 1 : 0); + result = 31 * result + (enableCertificateExpiry ? 1 : 0); + result = 31 * result + (enableLastModified ? 1 : 0); + result = 31 * result + (enableSKI ? 1 : 0); + result = 31 * result + (enableAKI ? 1 : 0); + result = 31 * result + (enableIssuerDN ? 1 : 0); + result = 31 * result + (enableSubjectDN ? 1 : 0); + result = 31 * result + (enableCurve ? 1 : 0); + result = 31 * result + (enableIssuerCN ? 1 : 0); + result = 31 * result + (enableSubjectCN ? 1 : 0); + result = 31 * result + (enableIssuerO ? 1 : 0); + result = 31 * result + (enableSubjectO ? 1 : 0); + result = 31 * result + (enableSerialNumberHex ? 1 : 0); + result = 31 * result + (enableSerialNumberDec ? 1 : 0); + return result; } } diff --git a/kse/src/main/java/org/kse/gui/KeyStoreTableHeadRend.java b/kse/src/main/java/org/kse/gui/KeyStoreTableHeadRend.java index 9baed51aa..966733d6d 100644 --- a/kse/src/main/java/org/kse/gui/KeyStoreTableHeadRend.java +++ b/kse/src/main/java/org/kse/gui/KeyStoreTableHeadRend.java @@ -107,35 +107,35 @@ else if (col == 2) { header.setHorizontalAlignment(LEFT); header.setIcon(null); - if (col == keyStoreTableColumns.colEntryName()) { + if (col == keyStoreTableColumns.colIndexEntryName()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.NameColumn.tooltip")); - } else if (col == keyStoreTableColumns.colAlgorithm()) { + } else if (col == keyStoreTableColumns.colIndexAlgorithm()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.AlgorithmColumn.tooltip")); - } else if (col == keyStoreTableColumns.colKeySize()) { + } else if (col == keyStoreTableColumns.colIndexKeySize()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.KeySizeColumn.tooltip")); - } else if (col == keyStoreTableColumns.colCertificateValidityStart()) { + } else if (col == keyStoreTableColumns.colIndexCertificateValidityStart()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.CertValidityStartColumn.tooltip")); - } else if (col == keyStoreTableColumns.colCertificateExpiry()) { + } else if (col == keyStoreTableColumns.colIndexCertificateExpiry()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.CertExpiryColumn.tooltip")); - } else if (col == keyStoreTableColumns.colLastModified()) { + } else if (col == keyStoreTableColumns.colIndexLastModified()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.LastModifiedColumn.tooltip")); - } else if (col == keyStoreTableColumns.colAKI()) { + } else if (col == keyStoreTableColumns.colIndexAKI()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.AKIColumn.tooltip")); - } else if (col == keyStoreTableColumns.colSKI()) { + } else if (col == keyStoreTableColumns.colIndexSKI()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.SKIColumn.tooltip")); - } else if (col == keyStoreTableColumns.colIssuerDN()) { + } else if (col == keyStoreTableColumns.colIndexIssuerDN()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.IssuerDNColumn.tooltip")); - } else if (col == keyStoreTableColumns.colSubjectDN()) { + } else if (col == keyStoreTableColumns.colIndexSubjectDN()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.SubjectDNColumn.tooltip")); - } else if (col == keyStoreTableColumns.colIssuerCN()) { + } else if (col == keyStoreTableColumns.colIndexIssuerCN()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.IssuerCNColumn.tooltip")); - } else if (col == keyStoreTableColumns.colSubjectCN()) { + } else if (col == keyStoreTableColumns.colIndexSubjectCN()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.SubjectCNColumn.tooltip")); - } else if (col == keyStoreTableColumns.colIssuerO()) { + } else if (col == keyStoreTableColumns.colIndexIssuerO()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.IssuerOColumn.tooltip")); - } else if (col == keyStoreTableColumns.colSubjectO()) { + } else if (col == keyStoreTableColumns.colIndexSubjectO()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.SubjectOColumn.tooltip")); - } else if (col == keyStoreTableColumns.colCurve()) { + } else if (col == keyStoreTableColumns.colIndexCurve()) { header.setToolTipText(res.getString("KeyStoreTableHeadRend.CurveColumn.tooltip")); } } diff --git a/kse/src/main/java/org/kse/gui/KeyStoreTableModel.java b/kse/src/main/java/org/kse/gui/KeyStoreTableModel.java index 1177c3c6f..1c61d684a 100644 --- a/kse/src/main/java/org/kse/gui/KeyStoreTableModel.java +++ b/kse/src/main/java/org/kse/gui/KeyStoreTableModel.java @@ -70,7 +70,7 @@ public class KeyStoreTableModel extends AbstractTableModel { private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/resources"); private String[] columnNames; private Class[] columnTypes; - private Object[][] data; + private Object[][] data = new Object[0][0]; private KeyStoreHistory history; /** @@ -90,7 +90,7 @@ public class KeyStoreTableModel extends AbstractTableModel { private static final int ICON_SIZE = 28; - private KeyStoreTableColumns keyStoreTableColumns = new KeyStoreTableColumns(); + private KeyStoreTableColumns keyStoreTableColumns; private int nofColumns = 5; private int[] iColWidth; @@ -119,10 +119,10 @@ public class KeyStoreTableModel extends AbstractTableModel { /** * Construct a new KeyStoreTableModel with a variable layout. */ - public KeyStoreTableModel(KeyStoreTableColumns keyStoreTableColumnsParm) { - this.keyStoreTableColumns = keyStoreTableColumnsParm; - adjustColumns(keyStoreTableColumnsParm); - data = new Object[0][0]; + public KeyStoreTableModel(KeyStoreTableColumns keyStoreTableColumns, int expiryWarnDays) { + this.keyStoreTableColumns = keyStoreTableColumns; + this.expiryWarnDays = expiryWarnDays; + adjustColumns(); } /** @@ -234,21 +234,10 @@ public void load(KeyStoreHistory history) throws GeneralSecurityException, Crypt } } if (iCertValidityStartColumn > 0) { - Date validityStart = getCertificateValidityStart(alias, keyStore); - // Validity start date column - if (validityStart != null) { - data[i][iCertValidityStartColumn] = validityStart; - } else { - data[i][iCertValidityStartColumn] = null; // No validity start date - must be a key entry - } + data[i][iCertValidityStartColumn] = getCertificateValidityStart(alias, keyStore); } if (iCertExpiryColumn > 0) { - // Expiry date column - if (expiry != null) { - data[i][iCertExpiryColumn] = expiry; - } else { - data[i][iCertExpiryColumn] = null; // No certExpiration date - must be a key entry - } + data[i][iCertExpiryColumn] = expiry; } if (iLastModifiedColumn > 0) { // Modified date column - only applies to non-PKCS #11/#12 KeyStores @@ -544,10 +533,8 @@ private X509Certificate getCertificate(String alias, KeyStore keyStore) throws K return x509Cert; } - private void adjustColumns(KeyStoreTableColumns keyStoreTableColumnsParm) { - keyStoreTableColumns = keyStoreTableColumnsParm; + private void adjustColumns() { nofColumns = 3 + keyStoreTableColumns.getNofColumns(); - expiryWarnDays = keyStoreTableColumns.getExpiryWarnDays(); iColWidth = new int[nofColumns]; // remove all columns before possibly enabling them @@ -582,95 +569,90 @@ private void adjustColumns(KeyStoreTableColumns keyStoreTableColumnsParm) { iColWidth[2] = ICON_SIZE; for (int col = 3; col < nofColumns; col++) { - if (col == keyStoreTableColumns.colEntryName()) { + if (col == keyStoreTableColumns.colIndexEntryName()) { columnNames[col] = res.getString("KeyStoreTableModel.NameColumn"); columnTypes[col] = String.class; iNameColumn = col; - } - if (col == keyStoreTableColumns.colAlgorithm()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexAlgorithm()) { columnNames[col] = res.getString("KeyStoreTableModel.AlgorithmColumn"); columnTypes[col] = String.class; iAlgorithmColumn = col; - } - if (col == keyStoreTableColumns.colKeySize()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexKeySize()) { columnNames[col] = res.getString("KeyStoreTableModel.KeySizeColumn"); columnTypes[col] = Integer.class; iKeySizeColumn = col; - } - if (col == keyStoreTableColumns.colCurve()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexCurve()) { columnNames[col] = res.getString("KeyStoreTableModel.CurveColumn"); columnTypes[col] = String.class; iCurveColumn = col; - } - if (col == keyStoreTableColumns.colCertificateValidityStart()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexCertificateValidityStart()) { columnNames[col] = res.getString("KeyStoreTableModel.CertValidityStartColumn"); columnTypes[col] = Date.class; iCertValidityStartColumn = col; iColWidth[col] = " 20.00.2000 00:00:00 MESZ ".length(); - } - if (col == keyStoreTableColumns.colCertificateExpiry()) { + } else if (col == keyStoreTableColumns.colIndexCertificateExpiry()) { columnNames[col] = res.getString("KeyStoreTableModel.CertExpiryColumn"); columnTypes[col] = Date.class; iCertExpiryColumn = col; iColWidth[col] = " 20.00.2000 00:00:00 MESZ ".length(); - } - if (col == keyStoreTableColumns.colLastModified()) { + } else if (col == keyStoreTableColumns.colIndexLastModified()) { columnNames[col] = res.getString("KeyStoreTableModel.LastModifiedColumn"); columnTypes[col] = Date.class; iLastModifiedColumn = col; iColWidth[col] = " 20.00.2000 00:00:00 MESZ ".length(); - } - if (col == keyStoreTableColumns.colAKI()) { + } else if (col == keyStoreTableColumns.colIndexAKI()) { columnNames[col] = res.getString("KeyStoreTableModel.AKIColumn"); columnTypes[col] = String.class; iAKIColumn = col; - } - if (col == keyStoreTableColumns.colSKI()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexSKI()) { columnNames[col] = res.getString("KeyStoreTableModel.SKIColumn"); columnTypes[col] = String.class; iSKIColumn = col; - } - if (col == keyStoreTableColumns.colIssuerDN()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexIssuerDN()) { columnNames[col] = res.getString("KeyStoreTableModel.IssuerDNColumn"); columnTypes[col] = String.class; iIssuerDNColumn = col; - } - if (col == keyStoreTableColumns.colSubjectDN()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexSubjectDN()) { columnNames[col] = res.getString("KeyStoreTableModel.SubjectDNColumn"); columnTypes[col] = String.class; iSubjectDNColumn = col; - } - if (col == keyStoreTableColumns.colIssuerCN()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexIssuerCN()) { columnNames[col] = res.getString("KeyStoreTableModel.IssuerCNColumn"); columnTypes[col] = String.class; iIssuerCNColumn = col; - } - if (col == keyStoreTableColumns.colSubjectCN()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexSubjectCN()) { columnNames[col] = res.getString("KeyStoreTableModel.SubjectCNColumn"); columnTypes[col] = String.class; iSubjectCNColumn = col; - } - if (col == keyStoreTableColumns.colIssuerO()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexIssuerO()) { columnNames[col] = res.getString("KeyStoreTableModel.IssuerOColumn"); columnTypes[col] = String.class; iIssuerOColumn = col; - } - if (col == keyStoreTableColumns.colSubjectO()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexSubjectO()) { columnNames[col] = res.getString("KeyStoreTableModel.SubjectOColumn"); columnTypes[col] = String.class; iSubjectOColumn = col; - } - if (col == keyStoreTableColumns.colSerialNumberHex()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexSerialNumberHex()) { columnNames[col] = res.getString("KeyStoreTableModel.SerialNumberHex"); columnTypes[col] = String.class; iSerialNumberHexColumn = col; - } - if (col == keyStoreTableColumns.colSerialNumberDec()) { + iColWidth[col] = columnNames[col].length(); + } else if (col == keyStoreTableColumns.colIndexSerialNumberDec()) { columnNames[col] = res.getString("KeyStoreTableModel.SerialNumberDec"); columnTypes[col] = String.class; iSerialNumberDecColumn = col; - } - if (iColWidth[col] < 1) { iColWidth[col] = columnNames[col].length(); } } @@ -742,15 +724,6 @@ public boolean isCellEditable(int row, int col) { return false; } - public KeyStoreTableColumns getKeyStoreTableColumns() { - return keyStoreTableColumns; - } - - public void setKeyStoreTableColumns(KeyStoreTableColumns keyStoreTableColumns) { - this.keyStoreTableColumns = keyStoreTableColumns; - adjustColumns(keyStoreTableColumns); - } - /** * Maximum width of a column * diff --git a/kse/src/main/java/org/kse/gui/KseFrame.java b/kse/src/main/java/org/kse/gui/KseFrame.java index 07ebb0bf3..ea079bba3 100644 --- a/kse/src/main/java/org/kse/gui/KseFrame.java +++ b/kse/src/main/java/org/kse/gui/KseFrame.java @@ -53,6 +53,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.ResourceBundle; import java.util.Set; @@ -88,7 +89,6 @@ import javax.swing.plaf.TabbedPaneUI; import javax.swing.table.TableRowSorter; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.KSE; import org.kse.crypto.CryptoException; import org.kse.crypto.Password; @@ -184,6 +184,8 @@ import org.kse.gui.dnd.DragTrustedCertificateEntry; import org.kse.gui.dnd.KeyStoreEntryDragGestureListener; import org.kse.gui.error.DError; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.gui.quickstart.JQuickStartPane; import org.kse.gui.statusbar.StatusBar; import org.kse.gui.statusbar.StatusBarChangeHandler; @@ -207,13 +209,10 @@ public final class KseFrame implements StatusBar { // Default KeyStores tabbed pane - dictates height of this frame public static final int DEFAULT_HEIGHT = 450; - // Maximum number of recent files to maintain in file menu - public static final int RECENT_FILES_SIZE = 9; - private ArrayList histories = new ArrayList<>(); private ArrayList keyStoreTables = new ArrayList<>(); private JFrame frame = new JFrame(); - private ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); + private KsePreferences preferences = PreferencesManager.getPreferences(); private KeyStoreTableColumns keyStoreTableColumns = new KeyStoreTableColumns(); private int autoResizeMode = JTable.AUTO_RESIZE_ALL_COLUMNS; @@ -561,14 +560,14 @@ public JFrame getUnderlyingFrame() { * * @return Application settings */ - public ApplicationSettings getApplicationSettings() { - return applicationSettings; + public KsePreferences getPreferences() { + return preferences; } void display() { frame.setVisible(true); - if (applicationSettings.getShowTipsOnStartUp()) { + if (preferences.isShowTipsOnStartUp()) { tipOfTheDayAction.showTipOfTheDay(); } } @@ -601,7 +600,7 @@ public void windowClosing(WindowEvent evt) { } private void initApplicationPosition() { - Rectangle sizeAndPosition = applicationSettings.getSizeAndPosition(); + Rectangle sizeAndPosition = preferences.getMainWindowSizeAndPosition(); int xPos = sizeAndPosition.x; int yPos = sizeAndPosition.y; @@ -729,16 +728,16 @@ private void initMenu() { jmFile.addSeparator(); - jmrfRecentFiles = new JMenuRecentFiles(res.getString("KseFrame.jmrfRecentFiles.text"), RECENT_FILES_SIZE); + jmrfRecentFiles = new JMenuRecentFiles(res.getString("KseFrame.jmrfRecentFiles.text")); jmrfRecentFiles.setIcon(new ImageIcon( Toolkit.getDefaultToolkit().createImage(getClass().getResource("images/menu/recentfiles.png")))); PlatformUtil.setMnemonic(jmrfRecentFiles, res.getString("KseFrame.jmrfRecentFiles.mnemonic").charAt(0)); jmFile.add(jmrfRecentFiles); - File[] recentFiles = applicationSettings.getRecentFiles(); + List recentFiles = preferences.getRecentFiles(); - for (int i = recentFiles.length - 1; i >= 0; i--) { - jmrfRecentFiles.add(createRecentFileMenuItem(jmrfRecentFiles, recentFiles[i])); + for (int i = recentFiles.size() - 1; i >= 0; i--) { + jmrfRecentFiles.add(createRecentFileMenuItem(jmrfRecentFiles, new File(recentFiles.get(i)))); } if (!OperatingSystem.isMacOs()) { @@ -803,7 +802,7 @@ private void initMenu() { jmView = new JMenu(res.getString("KseFrame.jmView.text")); PlatformUtil.setMnemonic(jmView, res.getString("KseFrame.jmView.mnemonic").charAt(0)); - boolean showToolBar = applicationSettings.getShowToolBar(); + boolean showToolBar = preferences.isShowToolBar(); jcbmiShowHideToolBar = new JCheckBoxMenuItem(showHideToolBarAction); jcbmiShowHideToolBar.setState(showToolBar); @@ -815,7 +814,7 @@ private void initMenu() { jmView.add(jcbmiShowHideToolBar); jcbmiShowHideStatusBar = new JCheckBoxMenuItem(showHideStatusBarAction); - jcbmiShowHideStatusBar.setState(applicationSettings.getShowStatusBar()); + jcbmiShowHideStatusBar.setState(preferences.isShowStatusBar()); PlatformUtil.setMnemonic(jcbmiShowHideStatusBar, res.getString("KseFrame.jcbmiShowHideStatusBar.mnemonic").charAt(0)); jcbmiShowHideStatusBar.setToolTipText(null); @@ -849,7 +848,7 @@ private void initMenu() { bgTabStyles.add(jrbmiTabStyleWrap); bgTabStyles.add(jrbmiTabStyleScroll); - int tabLayout = applicationSettings.getTabLayout(); + int tabLayout = preferences.getTabLayout(); if (tabLayout == JTabbedPane.WRAP_TAB_LAYOUT) { jrbmiTabStyleWrap.setSelected(true); @@ -1485,7 +1484,7 @@ public void mouseExited(MouseEvent evt) { jtbToolBar.add(jbHelp); - if (applicationSettings.getShowToolBar()) { + if (preferences.isShowToolBar()) { frame.getContentPane().add(jtbToolBar, BorderLayout.NORTH); } } @@ -1499,7 +1498,7 @@ private void initMainPane() { jkstpKeyStores = new JKeyStoreTabbedPane(this); - int tabLayout = applicationSettings.getTabLayout(); + int tabLayout = preferences.getTabLayout(); jkstpKeyStores.setTabLayoutPolicy(tabLayout); jkstpKeyStores.setBorder(new EmptyBorder(3, 3, 3, 3)); @@ -1529,7 +1528,7 @@ public void mouseClicked(MouseEvent evt) { } }); - Rectangle sizeAndPosition = applicationSettings.getSizeAndPosition(); + Rectangle sizeAndPosition = preferences.getMainWindowSizeAndPosition(); int width = sizeAndPosition.width; int height = sizeAndPosition.height; @@ -1558,8 +1557,8 @@ private JScrollPane wrapKeyStoreTableInScrollPane(JTable jtKeyStore) { } private JTable createEmptyKeyStoreTable() { - keyStoreTableColumns = applicationSettings.getKeyStoreTableColumns(); - KeyStoreTableModel ksModel = new KeyStoreTableModel(keyStoreTableColumns); + keyStoreTableColumns = preferences.getKeyStoreTableColumns(); + KeyStoreTableModel ksModel = new KeyStoreTableModel(keyStoreTableColumns, preferences.getExpiryWarnDays()); final JKseTable jtKeyStore = new JKseTable(ksModel); RowSorter sorter = new TableRowSorter<>(ksModel); @@ -1714,7 +1713,7 @@ private void initStatusBar() { setDefaultStatusBarText(); - if (applicationSettings.getShowStatusBar()) { + if (preferences.isShowStatusBar()) { frame.getContentPane().add(jlStatusBar, BorderLayout.SOUTH); } } @@ -2428,16 +2427,17 @@ public void removeKeyStore(KeyStore keyStore) { /** * Re-draw all keystore tables * - * @param applicationSettings settings + * @param preferences settings */ - public void redrawKeyStores(ApplicationSettings applicationSettings) { + public void redrawKeyStores(KsePreferences preferences) { if (keyStoreTables != null) { - keyStoreTableColumns = applicationSettings.getKeyStoreTableColumns(); + keyStoreTableColumns = preferences.getKeyStoreTableColumns(); + int expiryWarnDays = preferences.getExpiryWarnDays(); for (JTable keyStoreTable : keyStoreTables) { KeyStoreHistory history = ((KeyStoreTableModel) keyStoreTable.getModel()).getHistory(); - KeyStoreTableModel ksModel = new KeyStoreTableModel(keyStoreTableColumns); + KeyStoreTableModel ksModel = new KeyStoreTableModel(keyStoreTableColumns, expiryWarnDays); try { ksModel.load(history); keyStoreTable.setModel(ksModel); @@ -2445,9 +2445,9 @@ public void redrawKeyStores(ApplicationSettings applicationSettings) { RowSorter sorter = new TableRowSorter<>(ksModel); keyStoreTable.setRowSorter(sorter); if (keyStoreTable instanceof JKseTable) { - JKseTable keyStoreTab = (JKseTable)keyStoreTable; - keyStoreTab.setColumnsToIconSize(0, 1, 2); - keyStoreTab.colAdjust(keyStoreTableColumns, autoResizeMode); + JKseTable keyStoreTab = (JKseTable) keyStoreTable; + keyStoreTab.setColumnsToIconSize(0, 1, 2); + keyStoreTab.colAdjust(keyStoreTableColumns, autoResizeMode); } } catch (GeneralSecurityException | CryptoException e) { DError.displayError(frame, e); @@ -3096,7 +3096,7 @@ public void addRecentFile(File recentFile) { public void setKeyStoreTabLayoutPolicy(int tabLayoutPolicy) { if (tabLayoutPolicy == JTabbedPane.WRAP_TAB_LAYOUT || tabLayoutPolicy == JTabbedPane.SCROLL_TAB_LAYOUT) { jkstpKeyStores.setTabLayoutPolicy(tabLayoutPolicy); - applicationSettings.setTabLayout(tabLayoutPolicy); + preferences.setTabLayout(tabLayoutPolicy); } } @@ -3115,10 +3115,10 @@ public void showHideToolBar() { if (toolBarShown) { frame.getContentPane().remove(jtbToolBar); - applicationSettings.setShowToolBar(false); + preferences.setShowToolBar(false); } else { frame.getContentPane().add(jtbToolBar, BorderLayout.NORTH); - applicationSettings.setShowToolBar(true); + preferences.setShowToolBar(true); } } @@ -3137,10 +3137,10 @@ public void showHideStatusBar() { if (statusBarShown) { frame.getContentPane().remove(jlStatusBar); - applicationSettings.setShowStatusBar(false); + preferences.setShowStatusBar(false); } else { frame.getContentPane().add(jlStatusBar, BorderLayout.SOUTH); - applicationSettings.setShowStatusBar(true); + preferences.setShowStatusBar(true); } } } diff --git a/kse/src/main/java/org/kse/gui/actions/AuthorityCertificatesAction.java b/kse/src/main/java/org/kse/gui/actions/AuthorityCertificatesAction.java index 4f8dd35bc..0b6e5ceee 100644 --- a/kse/src/main/java/org/kse/gui/actions/AuthorityCertificatesAction.java +++ b/kse/src/main/java/org/kse/gui/actions/AuthorityCertificatesAction.java @@ -62,7 +62,7 @@ protected KeyStore getCaCertificates() { KeyStore caCertificates = null; - if (applicationSettings.getUseCaCertificates()) { + if (preferences.getCaCertsSettings().isUseCaCertificates()) { caCertificates = authorityCertificates.getCaCertificates(); if (caCertificates == null) { @@ -88,7 +88,7 @@ protected KeyStore getWindowsTrustedRootCertificates() throws CryptoException { KeyStore windowsTrustedRootCertificates = null; - if (applicationSettings.getUseWindowsTrustedRootCertificates()) { + if (preferences.getCaCertsSettings().isUseWindowsTrustedRootCertificates()) { windowsTrustedRootCertificates = authorityCertificates.getWindowsTrustedRootCertificates(); } @@ -96,7 +96,7 @@ protected KeyStore getWindowsTrustedRootCertificates() throws CryptoException { } private KeyStore loadCaCertificatesKeyStore() { - File caCertificatesFile = applicationSettings.getCaCertificatesFile(); + File caCertificatesFile = new File(preferences.getCaCertsSettings().getCaCertificatesFile()); KeyStore caCertificatesKeyStore = null; try { diff --git a/kse/src/main/java/org/kse/gui/actions/CheckUpdateAction.java b/kse/src/main/java/org/kse/gui/actions/CheckUpdateAction.java index e514d8046..a7d515137 100644 --- a/kse/src/main/java/org/kse/gui/actions/CheckUpdateAction.java +++ b/kse/src/main/java/org/kse/gui/actions/CheckUpdateAction.java @@ -26,8 +26,8 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; -import java.util.Date; -import java.util.concurrent.TimeUnit; +import java.time.LocalDate; +import java.time.Period; import javax.swing.ImageIcon; import javax.swing.JOptionPane; @@ -89,20 +89,20 @@ protected void doAction() { */ public void doAutoUpdateCheck() throws IOException { // abort auto update check if not enabled - if (!applicationSettings.isAutoUpdateCheckEnabled()) { + if (!preferences.getAutoUpdateCheckSettings().isEnabled()) { return; } - Date lastCheck = applicationSettings.getAutoUpdateCheckLastCheck(); - Date now = new Date(); - int checkInterval = applicationSettings.getAutoUpdateCheckInterval(); - if (TimeUnit.MILLISECONDS.toDays(now.getTime() - lastCheck.getTime()) < checkInterval) { + LocalDate lastCheck = preferences.getAutoUpdateCheckSettings().getLastCheck(); + LocalDate now = LocalDate.now(); + int checkInterval = preferences.getAutoUpdateCheckSettings().getCheckInterval(); + if (Period.between(lastCheck, now).getDays() < checkInterval) { return; - } else { - // save in settings when last check (this one) has happened - applicationSettings.setAutoUpdateCheckLastCheck(new Date()); } + // save in settings when last check (this one) has happened + preferences.getAutoUpdateCheckSettings().setLastCheck(now); + // Get the version number of the latest KeyStore Explorer from its website URL latestVersionUrl = new URL(URLs.LATEST_VERSION_ADDRESS); String versionString = IOUtils.toString(latestVersionUrl, StandardCharsets.US_ASCII); diff --git a/kse/src/main/java/org/kse/gui/actions/ExamineClipboardAction.java b/kse/src/main/java/org/kse/gui/actions/ExamineClipboardAction.java index 08201a56f..8fd6080e5 100644 --- a/kse/src/main/java/org/kse/gui/actions/ExamineClipboardAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ExamineClipboardAction.java @@ -208,7 +208,7 @@ private static byte[] decodeIfBase64(String data) { } return dataAsBytes; } - + private boolean isRedirect(int status) { // normally, 3xx is redirect if (status != HttpURLConnection.HTTP_OK) { @@ -218,7 +218,7 @@ private boolean isRedirect(int status) { } return false; } - + private void downloadCrl(URL url) throws IOException, CryptoException { HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); int status = urlConn.getResponseCode(); @@ -299,7 +299,7 @@ private void showPrivateKey(byte[] data, CryptoFileType fileType) throws IOExcep } DViewPrivateKey dViewPrivateKey = new DViewPrivateKey(frame, res.getString( - "ExamineClipboardAction.PrivateKeyDetails.Title"), "", privKey, applicationSettings); + "ExamineClipboardAction.PrivateKeyDetails.Title"), "", privKey, preferences); dViewPrivateKey.setLocationRelativeTo(frame); dViewPrivateKey.setVisible(true); } diff --git a/kse/src/main/java/org/kse/gui/actions/ExamineFileAction.java b/kse/src/main/java/org/kse/gui/actions/ExamineFileAction.java index fc9f07498..e7e1b7c5f 100644 --- a/kse/src/main/java/org/kse/gui/actions/ExamineFileAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ExamineFileAction.java @@ -291,7 +291,8 @@ private void openPrivateKey(File file, CryptoFileType fileType) throws IOExcepti } DViewPrivateKey dViewPrivateKey = new DViewPrivateKey(frame, MessageFormat.format( - res.getString("ExamineFileAction.PrivateKeyDetailsFile.Title"), file.getName()), FileNameUtil.removeExtension(file.getName()), privKey, applicationSettings); + res.getString("ExamineFileAction.PrivateKeyDetailsFile.Title"), file.getName()), FileNameUtil.removeExtension(file.getName()), privKey, + preferences); dViewPrivateKey.setLocationRelativeTo(frame); dViewPrivateKey.setVisible(true); } diff --git a/kse/src/main/java/org/kse/gui/actions/ExitAction.java b/kse/src/main/java/org/kse/gui/actions/ExitAction.java index f10645531..8c6ace5cb 100644 --- a/kse/src/main/java/org/kse/gui/actions/ExitAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ExitAction.java @@ -22,6 +22,9 @@ import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.io.File; +import java.util.Arrays; +import java.util.stream.Collectors; import javax.swing.ImageIcon; import javax.swing.KeyStroke; @@ -29,6 +32,7 @@ import org.kse.gui.CurrentDirectory; import org.kse.gui.KseFrame; import org.kse.gui.KseRestart; +import org.kse.gui.preferences.PreferencesManager; /** * Action to exit. @@ -81,10 +85,12 @@ public void exitApplication(boolean restart) { } // Save dynamic application settings - applicationSettings.setSizeAndPosition(kseFrame.getSizeAndPosition(keyStoresClosed)); - applicationSettings.setRecentFiles(kseFrame.getRecentFiles()); - applicationSettings.setCurrentDirectory(CurrentDirectory.get()); - applicationSettings.save(); + preferences.setMainWindowSizeAndPosition(kseFrame.getSizeAndPosition(keyStoresClosed)); + preferences.setRecentFiles(Arrays.stream(kseFrame.getRecentFiles()) + .map(File::getAbsolutePath) + .collect(Collectors.toList())); + preferences.setCurrentDirectory(CurrentDirectory.get().getAbsolutePath()); + PreferencesManager.persist(); if (restart) { KseRestart.restart(); diff --git a/kse/src/main/java/org/kse/gui/actions/ExportKeyPairAction.java b/kse/src/main/java/org/kse/gui/actions/ExportKeyPairAction.java index d79aff43d..6e57950b0 100644 --- a/kse/src/main/java/org/kse/gui/actions/ExportKeyPairAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ExportKeyPairAction.java @@ -94,8 +94,7 @@ protected void doAction() { PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray()); Certificate[] certificates = keyStore.getCertificateChain(alias); - DExportKeyPair dExportKeyPair = new DExportKeyPair(frame, alias, - applicationSettings.getPasswordQualityConfig()); + DExportKeyPair dExportKeyPair = new DExportKeyPair(frame, alias, preferences.getPasswordQualityConfig()); dExportKeyPair.setLocationRelativeTo(frame); dExportKeyPair.setVisible(true); diff --git a/kse/src/main/java/org/kse/gui/actions/ExportKeyPairPrivateKeyAction.java b/kse/src/main/java/org/kse/gui/actions/ExportKeyPairPrivateKeyAction.java index e6eee8ae4..8a1526132 100644 --- a/kse/src/main/java/org/kse/gui/actions/ExportKeyPairPrivateKeyAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ExportKeyPairPrivateKeyAction.java @@ -84,11 +84,11 @@ protected void doAction() { } if (dExportPrivateKeyType.exportPkcs8()) { - PrivateKeyUtils.exportAsPkcs8(privateKey, alias, frame, applicationSettings, res); + PrivateKeyUtils.exportAsPkcs8(privateKey, alias, frame, preferences, res); } else if (dExportPrivateKeyType.exportPvk()) { - PrivateKeyUtils.exportAsPvk(privateKey, alias, frame, applicationSettings, res); + PrivateKeyUtils.exportAsPvk(privateKey, alias, frame, preferences, res); } else { - PrivateKeyUtils.exportAsOpenSsl(privateKey, alias, frame, applicationSettings, res); + PrivateKeyUtils.exportAsOpenSsl(privateKey, alias, frame, preferences, res); } } catch (Exception ex) { DError.displayError(frame, ex); diff --git a/kse/src/main/java/org/kse/gui/actions/GenerateKeyPairAction.java b/kse/src/main/java/org/kse/gui/actions/GenerateKeyPairAction.java index 8ca0fa431..77d1b1ad6 100644 --- a/kse/src/main/java/org/kse/gui/actions/GenerateKeyPairAction.java +++ b/kse/src/main/java/org/kse/gui/actions/GenerateKeyPairAction.java @@ -104,11 +104,11 @@ public String generateKeyPair(X509Certificate issuerCert, X509Certificate[] issu String alias = ""; try { // Restore preferences regarding key type and length (or EC curve) - KeyPairType keyPairType = applicationSettings.getGenerateKeyPairType(); - int keyPairSizeRSA = applicationSettings.getGenerateKeyPairSizeRSA(); - int keyPairSizeDSA = applicationSettings.getGenerateKeyPairSizeDSA(); - String keyPairCurveSet = applicationSettings.getGenerateKeyPairCurveSet(); - String keyPairCurveName = applicationSettings.getGenerateKeyPairCurveName(); + KeyPairType keyPairType = preferences.getKeyGenerationDefaults().getKeyPairType(); + int keyPairSizeRSA = preferences.getKeyGenerationDefaults().getKeyPairSizeRSA(); + int keyPairSizeDSA = preferences.getKeyGenerationDefaults().getKeyPairSizeDSA(); + String keyPairCurveSet = preferences.getKeyGenerationDefaults().getEcCurveSet(); + String keyPairCurveName = preferences.getKeyGenerationDefaults().getEcCurveName(); KeyStore activeKeyStore = kseFrame.getActiveKeyStore(); KeyStoreType activeKeyStoreType = KeyStoreType.resolveJce(activeKeyStore.getType()); @@ -131,11 +131,11 @@ public String generateKeyPair(X509Certificate issuerCert, X509Certificate[] issu keyPairSizeDSA = dGenerateKeyPair.getKeyPairSizeDSA(); keyPairCurveSet = dGenerateKeyPair.getCurveSet(); keyPairCurveName = dGenerateKeyPair.getCurveName(); - applicationSettings.setGenerateKeyPairType(keyPairType); - applicationSettings.setGenerateKeyPairSizeRSA(keyPairSizeRSA); - applicationSettings.setGenerateKeyPairSizeDSA(keyPairSizeDSA); - applicationSettings.setGenerateKeyPairCurveSet(keyPairCurveSet); - applicationSettings.setGenerateKeyPairCurveName(keyPairCurveName); + preferences.getKeyGenerationDefaults().setKeyPairType(keyPairType); + preferences.getKeyGenerationDefaults().setKeyPairSizeRSA(keyPairSizeRSA); + preferences.getKeyGenerationDefaults().setKeyPairSizeDSA(keyPairSizeDSA); + preferences.getKeyGenerationDefaults().setEcCurveSet(keyPairCurveSet); + preferences.getKeyGenerationDefaults().setEcCurveName(keyPairCurveName); KeyPair keyPair = generateKeyPair(keyPairType, keyPairSizeRSA, keyPairSizeDSA, keyPairCurveName, provider); if (keyPair == null) { @@ -186,8 +186,7 @@ public String generateKeyPair(X509Certificate issuerCert, X509Certificate[] issu if (keyStoreType.hasEntryPasswords()) { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( - "GenerateKeyPairAction.NewKeyPairEntryPassword.Title"), - applicationSettings.getPasswordQualityConfig()); + "GenerateKeyPairAction.NewKeyPairEntryPassword.Title"), preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); password = dGetNewPassword.getPassword(); diff --git a/kse/src/main/java/org/kse/gui/actions/GenerateSecretKeyAction.java b/kse/src/main/java/org/kse/gui/actions/GenerateSecretKeyAction.java index b775116c2..b254e8ba6 100644 --- a/kse/src/main/java/org/kse/gui/actions/GenerateSecretKeyAction.java +++ b/kse/src/main/java/org/kse/gui/actions/GenerateSecretKeyAction.java @@ -84,8 +84,8 @@ protected void doAction() { */ public void generateSecret() { try { - int secretKeySize = applicationSettings.getGenerateSecretKeySize(); - SecretKeyType secretKeyType = applicationSettings.getGenerateSecretKeyType(); + int secretKeySize = preferences.getKeyGenerationDefaults().getSecretKeySize(); + SecretKeyType secretKeyType = preferences.getKeyGenerationDefaults().getSecretKeyType(); DGenerateSecretKey dGenerateSecretKey = new DGenerateSecretKey(frame, secretKeyType, secretKeySize); dGenerateSecretKey.setLocationRelativeTo(frame); @@ -98,8 +98,8 @@ public void generateSecret() { secretKeySize = dGenerateSecretKey.getSecretKeySize(); secretKeyType = dGenerateSecretKey.getSecretKeyType(); - applicationSettings.setGenerateSecretKeySize(secretKeySize); - applicationSettings.setGenerateSecretKeyType(secretKeyType); + preferences.getKeyGenerationDefaults().setSecretKeySize(secretKeySize); + preferences.getKeyGenerationDefaults().setSecretKeyType(secretKeyType); SecretKey secretKey = SecretKeyUtil.generateSecretKey(secretKeyType, secretKeySize); @@ -137,8 +137,7 @@ public void generateSecret() { if (type.hasEntryPasswords()) { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( - "GenerateSecretKeyAction.NewSecretKeyEntryPassword.Title"), - applicationSettings.getPasswordQualityConfig()); + "GenerateSecretKeyAction.NewSecretKeyEntryPassword.Title"), preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); password = dGetNewPassword.getPassword(); diff --git a/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromClipboardAction.java b/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromClipboardAction.java index d2924e0e7..f5ab9559f 100644 --- a/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromClipboardAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromClipboardAction.java @@ -116,7 +116,7 @@ protected void doAction() { // Holds the new certificate chain for the entry should the import succeed X509Certificate[] newCertChain = null; - if (!applicationSettings.getEnableImportCaReplyTrustCheck()) { + if (!preferences.getCaCertsSettings().isImportCaReplyTrustCheckEnabled()) { newCertChain = certs; } else { KeyStore caCertificates = getCaCertificates(); diff --git a/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromFileAction.java b/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromFileAction.java index 2e81f19f6..01ceba6d6 100644 --- a/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromFileAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ImportCaReplyFromFileAction.java @@ -124,7 +124,7 @@ protected void doAction() { // Holds the new certificate chain for the entry should the import succeed X509Certificate[] newCertChain = null; - if (!applicationSettings.getEnableImportCaReplyTrustCheck()) { + if (!preferences.getCaCertsSettings().isImportCaReplyTrustCheckEnabled()) { newCertChain = certs; } else { KeyStore caCertificates = getCaCertificates(); diff --git a/kse/src/main/java/org/kse/gui/actions/ImportKeyPairAction.java b/kse/src/main/java/org/kse/gui/actions/ImportKeyPairAction.java index ee4b71d24..b8f5d6e48 100644 --- a/kse/src/main/java/org/kse/gui/actions/ImportKeyPairAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ImportKeyPairAction.java @@ -146,8 +146,7 @@ private void importKeyPairPkcs12() { if (type.hasEntryPasswords()) { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( - "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), - applicationSettings.getPasswordQualityConfig()); + "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); password = dGetNewPassword.getPassword(); @@ -226,8 +225,7 @@ private void importKeyPairPkcs8() { if (type.hasEntryPasswords()) { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( - "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), - applicationSettings.getPasswordQualityConfig()); + "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); password = dGetNewPassword.getPassword(); @@ -306,8 +304,7 @@ private void importKeyPairPvk() { if (type.hasEntryPasswords()) { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( - "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), - applicationSettings.getPasswordQualityConfig()); + "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); password = dGetNewPassword.getPassword(); @@ -387,7 +384,7 @@ private void importKeyPairOpenSsl() { if (type.hasEntryPasswords()) { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( "ImportKeyPairAction.NewKeyPairEntryPassword.Title"), - applicationSettings.getPasswordQualityConfig()); + preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); password = dGetNewPassword.getPassword(); diff --git a/kse/src/main/java/org/kse/gui/actions/ImportTrustedCertificateAction.java b/kse/src/main/java/org/kse/gui/actions/ImportTrustedCertificateAction.java index 937406459..cd3fcf5f9 100644 --- a/kse/src/main/java/org/kse/gui/actions/ImportTrustedCertificateAction.java +++ b/kse/src/main/java/org/kse/gui/actions/ImportTrustedCertificateAction.java @@ -119,7 +119,7 @@ protected void doAction() { trustCert = trustCertFromConstructor; } - if (applicationSettings.getEnableImportTrustedCertTrustCheck()) { + if (preferences.getCaCertsSettings().isImportTrustedCertTrustCheckEnabled()) { String matchAlias = X509CertUtil.matchCertificate(keyStore, trustCert); if (matchAlias != null) { int selected = JOptionPane.showConfirmDialog(frame, MessageFormat.format( diff --git a/kse/src/main/java/org/kse/gui/actions/KeyDetailsAction.java b/kse/src/main/java/org/kse/gui/actions/KeyDetailsAction.java index 11a190fe9..1825d975a 100644 --- a/kse/src/main/java/org/kse/gui/actions/KeyDetailsAction.java +++ b/kse/src/main/java/org/kse/gui/actions/KeyDetailsAction.java @@ -103,7 +103,8 @@ public void showKeySelectedEntry() { PrivateKey privateKey = (PrivateKey) key; DViewPrivateKey dViewPrivateKey = new DViewPrivateKey(frame, MessageFormat.format( - res.getString("KeyDetailsAction.PrivateKeyDetailsEntry.Title"), alias), alias, privateKey, applicationSettings); + res.getString("KeyDetailsAction.PrivateKeyDetailsEntry.Title"), alias), alias, privateKey, + preferences); dViewPrivateKey.setLocationRelativeTo(frame); dViewPrivateKey.setVisible(true); } else if (key instanceof PublicKey) { diff --git a/kse/src/main/java/org/kse/gui/actions/KeyPairPrivateKeyDetailsAction.java b/kse/src/main/java/org/kse/gui/actions/KeyPairPrivateKeyDetailsAction.java index bc00e0a8d..f43a3bed6 100644 --- a/kse/src/main/java/org/kse/gui/actions/KeyPairPrivateKeyDetailsAction.java +++ b/kse/src/main/java/org/kse/gui/actions/KeyPairPrivateKeyDetailsAction.java @@ -76,7 +76,8 @@ protected void doAction() { PrivateKey privKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray()); DViewPrivateKey dViewPrivateKey = new DViewPrivateKey(frame, MessageFormat.format( - res.getString("KeyPairPrivateKeyDetailsAction.PrivKeyDetailsEntry.Title"), alias), alias, privKey, applicationSettings); + res.getString("KeyPairPrivateKeyDetailsAction.PrivKeyDetailsEntry.Title"), alias), alias, privKey, + preferences); dViewPrivateKey.setLocationRelativeTo(frame); dViewPrivateKey.setVisible(true); } catch (Exception ex) { diff --git a/kse/src/main/java/org/kse/gui/actions/KeyStoreExplorerAction.java b/kse/src/main/java/org/kse/gui/actions/KeyStoreExplorerAction.java index a413c1f15..6c5531b30 100644 --- a/kse/src/main/java/org/kse/gui/actions/KeyStoreExplorerAction.java +++ b/kse/src/main/java/org/kse/gui/actions/KeyStoreExplorerAction.java @@ -33,7 +33,6 @@ import javax.swing.JOptionPane; import org.apache.commons.io.FileUtils; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.crypto.Password; import org.kse.crypto.keystore.KeyStoreType; import org.kse.crypto.x509.X509CertUtil; @@ -44,6 +43,7 @@ import org.kse.gui.error.Problem; import org.kse.gui.password.DGetNewPassword; import org.kse.gui.password.DGetPassword; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.history.KeyStoreHistory; import org.kse.utilities.history.KeyStoreState; @@ -71,7 +71,7 @@ public abstract class KeyStoreExplorerAction extends AbstractAction { /** * Application settings */ - protected ApplicationSettings applicationSettings; + protected KsePreferences preferences; /** * Construct a KeyStoreExplorerAction. @@ -81,7 +81,7 @@ public abstract class KeyStoreExplorerAction extends AbstractAction { public KeyStoreExplorerAction(KseFrame kseFrame) { this.kseFrame = kseFrame; frame = kseFrame.getUnderlyingFrame(); - applicationSettings = kseFrame.getApplicationSettings(); + preferences = kseFrame.getPreferences(); } /** @@ -239,8 +239,7 @@ protected X509Certificate[] openCertificate(byte[] data, String name) { */ protected Password getNewKeyStorePassword() { DGetNewPassword dGetNewPassword = new DGetNewPassword(frame, res.getString( - "KeyStoreExplorerAction.SetKeyStorePassword.Title"), ApplicationSettings.getInstance() - .getPasswordQualityConfig()); + "KeyStoreExplorerAction.SetKeyStorePassword.Title"), preferences.getPasswordQualityConfig()); dGetNewPassword.setLocationRelativeTo(frame); dGetNewPassword.setVisible(true); diff --git a/kse/src/main/java/org/kse/gui/actions/OpenCaCertificatesAction.java b/kse/src/main/java/org/kse/gui/actions/OpenCaCertificatesAction.java index 6b216e82a..e0f0ea120 100644 --- a/kse/src/main/java/org/kse/gui/actions/OpenCaCertificatesAction.java +++ b/kse/src/main/java/org/kse/gui/actions/OpenCaCertificatesAction.java @@ -67,7 +67,7 @@ public OpenCaCertificatesAction(KseFrame kseFrame) { */ @Override protected void doAction() { - File caCertificatesFile = applicationSettings.getCaCertificatesFile(); + File caCertificatesFile = new File(preferences.getCaCertsSettings().getCaCertificatesFile()); if (caCertificatesFile.isFile()) { openKeyStore(caCertificatesFile, AuthorityCertificates.CACERTS_DEFAULT_PWD); diff --git a/kse/src/main/java/org/kse/gui/actions/PreferencesAction.java b/kse/src/main/java/org/kse/gui/actions/PreferencesAction.java index 4fc2df074..62af478ec 100644 --- a/kse/src/main/java/org/kse/gui/actions/PreferencesAction.java +++ b/kse/src/main/java/org/kse/gui/actions/PreferencesAction.java @@ -19,6 +19,8 @@ */ package org.kse.gui.actions; +import static org.kse.utilities.net.ProxySettingsUpdater.updateSettings; + import java.awt.Toolkit; import java.io.File; @@ -28,9 +30,8 @@ import javax.swing.KeyStroke; import javax.swing.UIManager; -import org.kse.crypto.csr.pkcs12.Pkcs12Util; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.AuthorityCertificates; +import org.kse.crypto.csr.pkcs12.Pkcs12Util; import org.kse.gui.KseFrame; import org.kse.gui.preferences.DPreferences; @@ -70,24 +71,9 @@ protected void doAction() { * Display the preferences dialog and store the user's choices. */ public void showPreferences() { - ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); - - File caCertificatesFile = applicationSettings.getCaCertificatesFile(); - - DPreferences dPreferences = new DPreferences(frame, applicationSettings.getUseCaCertificates(), - caCertificatesFile, - applicationSettings.getUseWindowsTrustedRootCertificates(), - applicationSettings.getEnableImportTrustedCertTrustCheck(), - applicationSettings.getEnableImportCaReplyTrustCheck(), - applicationSettings.getPasswordQualityConfig(), - applicationSettings.getDefaultDN(), - applicationSettings.getLanguage(), - applicationSettings.isAutoUpdateCheckEnabled(), - applicationSettings.getAutoUpdateCheckInterval(), - applicationSettings.getKeyStoreTableColumns(), - applicationSettings.isShowHiddenFilesEnabled(), - applicationSettings.getPkcs12EncryptionSetting(), - applicationSettings.getSerialNumberLengthInBytes()); + File caCertificatesFile = new File(preferences.getCaCertsSettings().getCaCertificatesFile()); + + DPreferences dPreferences = new DPreferences(frame, preferences); dPreferences.setLocationRelativeTo(frame); dPreferences.setVisible(true); @@ -104,38 +90,39 @@ public void showPreferences() { caCertificatesFile = tmpFile; - applicationSettings.setCaCertificatesFile(caCertificatesFile); - applicationSettings.setUseCaCertificates(dPreferences.getUseCaCertificates()); - applicationSettings.setUseWindowsTrustedRootCertificates(dPreferences.getUseWinTrustRootCertificates()); - applicationSettings.setEnableImportTrustedCertTrustCheck(dPreferences.getEnableImportTrustedCertTrustCheck()); - applicationSettings.setEnableImportCaReplyTrustCheck(dPreferences.getEnableImportCaReplyTrustCheck()); - applicationSettings.setPasswordQualityConfig(dPreferences.getPasswordQualityConfig()); - applicationSettings.setDefaultDN(dPreferences.getDefaultDN()); - applicationSettings.setAutoUpdateCheckEnabled(dPreferences.isAutoUpdateChecksEnabled()); - applicationSettings.setAutoUpdateCheckInterval(dPreferences.getAutoUpdateChecksInterval()); - applicationSettings.setShowHiddenFilesEnabled(dPreferences.isShowHiddenFilesEnabled()); - applicationSettings.setPkcs12EncryptionSetting(dPreferences.getPkcs12EncryptionSetting()); - applicationSettings.setSerialNumberLengthInBytes(dPreferences.getSerialNumberLengthInBytes()); + preferences.getCaCertsSettings().setCaCertificatesFile(caCertificatesFile.getAbsolutePath()); + preferences.getCaCertsSettings().setUseCaCertificates(dPreferences.getUseCaCertificates()); + preferences.getCaCertsSettings().setUseWindowsTrustedRootCertificates(dPreferences.getUseWinTrustRootCertificates()); + preferences.getCaCertsSettings().setImportTrustedCertTrustCheckEnabled(dPreferences.getEnableImportTrustedCertTrustCheck()); + preferences.getCaCertsSettings().setImportCaReplyTrustCheckEnabled(dPreferences.getEnableImportCaReplyTrustCheck()); + preferences.setPasswordQualityConfig(dPreferences.getPasswordQualityConfig()); + preferences.setDefaultSubjectDN(dPreferences.getDefaultDN()); + preferences.getAutoUpdateCheckSettings().setEnabled(dPreferences.isAutoUpdateChecksEnabled()); + preferences.getAutoUpdateCheckSettings().setCheckInterval(dPreferences.getAutoUpdateChecksInterval()); + preferences.setShowHiddenFilesEnabled(dPreferences.isShowHiddenFilesEnabled()); + preferences.setPkcs12EncryptionSetting(dPreferences.getPkcs12EncryptionSetting()); + preferences.setSerialNumberLengthInBytes(dPreferences.getSerialNumberLengthInBytes()); - Pkcs12Util.setEncryptionStrength(applicationSettings.getPkcs12EncryptionSetting()); + Pkcs12Util.setEncryptionStrength(preferences.getPkcs12EncryptionSetting()); - UIManager.LookAndFeelInfo lookFeelInfo = dPreferences.getLookFeelInfo(); - applicationSettings.setLookAndFeelClass(lookFeelInfo.getClassName()); - - boolean lookAndFeelDecorated = dPreferences.getLookFeelDecoration(); - applicationSettings.setLookAndFeelDecorated(lookAndFeelDecorated); + preferences.setLookAndFeelClass(dPreferences.getLookFeelInfo().getClassName()); + preferences.setLookAndFeelDecorated(dPreferences.getLookFeelDecoration()); String language = dPreferences.getLanguage(); - boolean languageHasChanged = !language.equals(applicationSettings.getLanguage()); - applicationSettings.setLanguage(language); + boolean languageHasChanged = !language.equals(preferences.getLanguage()); + preferences.setLanguage(language); if (dPreferences.columnsChanged()) { - applicationSettings.setKeyStoreTableColumns(dPreferences.getColumns()); - kseFrame.redrawKeyStores(applicationSettings); + preferences.setKeyStoreTableColumns(dPreferences.getColumns()); + kseFrame.redrawKeyStores(preferences); } - if ((!lookFeelInfo.getClassName().equals(UIManager.getLookAndFeel().getClass().getName())) || - (lookAndFeelDecorated != JFrame.isDefaultLookAndFeelDecorated()) || languageHasChanged) { + preferences.setExpiryWarnDays(dPreferences.getExpiryWarnDays()); + + preferences.setProxySettings(updateSettings(preferences.getProxySettings())); + + if ((!dPreferences.getLookFeelInfo().getClassName().equals(UIManager.getLookAndFeel().getClass().getName())) || + (dPreferences.getLookFeelDecoration() != JFrame.isDefaultLookAndFeelDecorated()) || languageHasChanged) { // L&F or language changed - restart required for upgrade to take effect JOptionPane.showMessageDialog(frame, res.getString("PreferencesAction.LookFeelChanged.message"), res.getString("PreferencesAction.LookFeelChanged.Title"), diff --git a/kse/src/main/java/org/kse/gui/actions/SetKeyPairPasswordAction.java b/kse/src/main/java/org/kse/gui/actions/SetKeyPairPasswordAction.java index f57563f0d..4879485e9 100644 --- a/kse/src/main/java/org/kse/gui/actions/SetKeyPairPasswordAction.java +++ b/kse/src/main/java/org/kse/gui/actions/SetKeyPairPasswordAction.java @@ -88,7 +88,7 @@ protected void doAction() { DChangePassword dChangePassword = new DChangePassword(frame, DOCUMENT_MODAL, res.getString( "SetKeyPairPasswordAction.SetKeyPairPassword.Title"), oldPassword, - applicationSettings.getPasswordQualityConfig()); + preferences.getPasswordQualityConfig()); dChangePassword.setLocationRelativeTo(frame); dChangePassword.setVisible(true); diff --git a/kse/src/main/java/org/kse/gui/actions/SetKeyPasswordAction.java b/kse/src/main/java/org/kse/gui/actions/SetKeyPasswordAction.java index 8c8b870b1..21dd685d0 100644 --- a/kse/src/main/java/org/kse/gui/actions/SetKeyPasswordAction.java +++ b/kse/src/main/java/org/kse/gui/actions/SetKeyPasswordAction.java @@ -86,7 +86,7 @@ protected void doAction() { DChangePassword dChangePassword = new DChangePassword(frame, DOCUMENT_MODAL, res.getString( "SetKeyPasswordAction.SetKeyPassword.Title"), oldPassword, - applicationSettings.getPasswordQualityConfig()); + preferences.getPasswordQualityConfig()); dChangePassword.setLocationRelativeTo(frame); dChangePassword.setVisible(true); diff --git a/kse/src/main/java/org/kse/gui/actions/TipOfTheDayAction.java b/kse/src/main/java/org/kse/gui/actions/TipOfTheDayAction.java index 3e97667e5..8c8ba9bbd 100644 --- a/kse/src/main/java/org/kse/gui/actions/TipOfTheDayAction.java +++ b/kse/src/main/java/org/kse/gui/actions/TipOfTheDayAction.java @@ -59,13 +59,13 @@ protected void doAction() { * Display the tip of the day dialog. */ public void showTipOfTheDay() { - DTipOfTheDay dTipOfTheDay = new DTipOfTheDay(frame, applicationSettings.getShowTipsOnStartUp(), res, - applicationSettings.getNextTipIndex()); + DTipOfTheDay dTipOfTheDay = new DTipOfTheDay(frame, preferences.isShowTipsOnStartUp(), res, + preferences.getNextTipIndex()); dTipOfTheDay.setLocationRelativeTo(frame); dTipOfTheDay.setVisible(true); - applicationSettings.setShowTipsOnStartUp(dTipOfTheDay.showTipsOnStartup()); - applicationSettings.setNextTipIndex(dTipOfTheDay.nextTipIndex()); + preferences.setShowTipsOnStartUp(dTipOfTheDay.showTipsOnStartup()); + preferences.setNextTipIndex(dTipOfTheDay.nextTipIndex()); } } diff --git a/kse/src/main/java/org/kse/gui/crypto/DDistinguishedNameChooser.java b/kse/src/main/java/org/kse/gui/crypto/DDistinguishedNameChooser.java index bb493e416..92eb98664 100644 --- a/kse/src/main/java/org/kse/gui/crypto/DDistinguishedNameChooser.java +++ b/kse/src/main/java/org/kse/gui/crypto/DDistinguishedNameChooser.java @@ -41,10 +41,11 @@ import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.BCStyle; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.gui.JEscDialog; import org.kse.gui.PlatformUtil; import org.kse.gui.dnchooser.DistinguishedNameChooser; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.DialogViewer; import net.miginfocom.swing.MigLayout; @@ -71,7 +72,7 @@ public class DDistinguishedNameChooser extends JEscDialog { String defaultDN; - private transient ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); + private transient KsePreferences preferences = PreferencesManager.getPreferences(); /** * Creates a new DDistinguishedNameChooser dialog. @@ -105,7 +106,7 @@ public DDistinguishedNameChooser(JDialog parent, String title, X500Name distingu private void initComponents() { - defaultDN = applicationSettings.getDefaultDN(); + defaultDN = preferences.getDefaultSubjectDN(); jbReset = new JButton(res.getString("DDistinguishedNameChooser.jbReset.text")); PlatformUtil.setMnemonic(jbReset, res.getString("DDistinguishedNameChooser.jbReset.mnemonic").charAt(0)); diff --git a/kse/src/main/java/org/kse/gui/crypto/privatekey/PrivateKeyUtils.java b/kse/src/main/java/org/kse/gui/crypto/privatekey/PrivateKeyUtils.java index cce7aeefd..94d326c0e 100644 --- a/kse/src/main/java/org/kse/gui/crypto/privatekey/PrivateKeyUtils.java +++ b/kse/src/main/java/org/kse/gui/crypto/privatekey/PrivateKeyUtils.java @@ -23,7 +23,7 @@ import org.kse.gui.dialogs.importexport.DExportPrivateKeyOpenSsl; import org.kse.gui.dialogs.importexport.DExportPrivateKeyPkcs8; import org.kse.gui.dialogs.importexport.DExportPrivateKeyPvk; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.data.KsePreferences; public class PrivateKeyUtils { @@ -33,19 +33,19 @@ public class PrivateKeyUtils { * @param privateKey Private key * @param alias Name of alias or file name * @param frame The parent frame - * @param applicationSettings Password quality configuration + * @param preferences Password quality configuration * @param res ResourceBundle * @throws CryptoException * @throws IOException */ public static void exportAsPkcs8(PrivateKey privateKey, String alias, JFrame frame, - ApplicationSettings applicationSettings, ResourceBundle res) + KsePreferences preferences, ResourceBundle res) throws CryptoException, IOException { File exportFile = null; try { DExportPrivateKeyPkcs8 dExportPrivateKeyPkcs8 = - new DExportPrivateKeyPkcs8(frame, alias, applicationSettings.getPasswordQualityConfig()); + new DExportPrivateKeyPkcs8(frame, alias, preferences.getPasswordQualityConfig()); dExportPrivateKeyPkcs8.setLocationRelativeTo(frame); dExportPrivateKeyPkcs8.setVisible(true); @@ -117,19 +117,19 @@ private static void exportEncodedPrivateKey(byte[] encoded, File exportFile) thr * @param privateKey Private key * @param alias Name of alias or file name * @param frame The parent frame - * @param applicationSettings Password quality configuration + * @param preferences Password quality configuration * @param res ResourceBundle * @throws CryptoException * @throws IOException */ public static void exportAsPvk(PrivateKey privateKey, String alias, JFrame frame, - ApplicationSettings applicationSettings, ResourceBundle res) + KsePreferences preferences, ResourceBundle res) throws CryptoException, IOException { File exportFile = null; try { DExportPrivateKeyPvk dExportPrivateKeyPvk = new DExportPrivateKeyPvk(frame, alias, privateKey, - applicationSettings.getPasswordQualityConfig()); + preferences.getPasswordQualityConfig()); dExportPrivateKeyPvk.setLocationRelativeTo(frame); dExportPrivateKeyPvk.setVisible(true); @@ -194,19 +194,19 @@ private static byte[] getPvkEncodedPrivateKey(PrivateKey privateKey, int keyType * @param privateKey Private key * @param alias Name of alias or file name * @param frame The parent frame - * @param applicationSettings Password quality configuration + * @param preferences Password quality configuration * @param res ResourceBundle * @throws CryptoException * @throws IOException */ public static void exportAsOpenSsl(PrivateKey privateKey, String alias, JFrame frame, - ApplicationSettings applicationSettings, ResourceBundle res) + KsePreferences preferences, ResourceBundle res) throws CryptoException, IOException { File exportFile = null; try { DExportPrivateKeyOpenSsl dExportPrivateKeyOpenSsl = - new DExportPrivateKeyOpenSsl(frame, alias, applicationSettings.getPasswordQualityConfig()); + new DExportPrivateKeyOpenSsl(frame, alias, preferences.getPasswordQualityConfig()); dExportPrivateKeyOpenSsl.setLocationRelativeTo(frame); dExportPrivateKeyOpenSsl.setVisible(true); diff --git a/kse/src/main/java/org/kse/gui/dialogs/DExamineSsl.java b/kse/src/main/java/org/kse/gui/dialogs/DExamineSsl.java index 2bdf4304c..eb9adec32 100644 --- a/kse/src/main/java/org/kse/gui/dialogs/DExamineSsl.java +++ b/kse/src/main/java/org/kse/gui/dialogs/DExamineSsl.java @@ -19,12 +19,15 @@ */ package org.kse.gui.dialogs; +import static org.kse.utilities.StringUtils.addToList; + import java.awt.Container; import java.awt.Dialog; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.util.List; import java.util.ResourceBundle; import javax.swing.AbstractAction; @@ -42,13 +45,14 @@ import javax.swing.JSeparator; import javax.swing.KeyStroke; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.crypto.Password; import org.kse.gui.JEscDialog; import org.kse.gui.KseFrame; import org.kse.gui.MiGUtil; import org.kse.gui.PlatformUtil; import org.kse.gui.actions.OpenAction; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.DialogViewer; import org.kse.utilities.history.KeyStoreHistory; @@ -60,7 +64,9 @@ public class DExamineSsl extends JEscDialog { private static final long serialVersionUID = 1L; private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/resources"); - private transient ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); + + private transient KsePreferences preferences = PreferencesManager.getPreferences(); + public static final int MAX_LIST_SIZE = 10; private static final String CANCEL_KEY = "CANCEL_KEY"; @@ -225,13 +231,13 @@ public boolean wasCancelled() { } private String[] getSslHosts() { - String sslHosts = applicationSettings.getSslHosts(); - return sslHosts.split(";"); + List sslHosts = preferences.getExamineSslHosts(); + return sslHosts.toArray(new String[sslHosts.size()]); } private String[] getSslPorts() { - String sslPorts = applicationSettings.getSslPorts(); - return sslPorts.split(";"); + List sslPorts = preferences.getExamineSslPorts(); + return sslPorts.toArray(new String[sslPorts.size()]); } private void updateClientAuthComponents() { @@ -295,8 +301,8 @@ private void okPressed() { } // save host/port in preferences - applicationSettings.addSslHost(sslHost); - applicationSettings.addSslPort(sslPortStr); + preferences.setExamineSslHosts(addToList(sslHost, preferences.getExamineSslHosts(), MAX_LIST_SIZE)); + preferences.setExamineSslPorts(addToList(sslPortStr, preferences.getExamineSslPorts(), MAX_LIST_SIZE)); cancelled = false; closeDialog(); diff --git a/kse/src/main/java/org/kse/gui/dialogs/DOpenPkcs11KeyStore.java b/kse/src/main/java/org/kse/gui/dialogs/DOpenPkcs11KeyStore.java index 4b1ef2ec3..b4ea0fcf5 100644 --- a/kse/src/main/java/org/kse/gui/dialogs/DOpenPkcs11KeyStore.java +++ b/kse/src/main/java/org/kse/gui/dialogs/DOpenPkcs11KeyStore.java @@ -19,6 +19,8 @@ */ package org.kse.gui.dialogs; +import static org.kse.utilities.StringUtils.addToList; + import java.awt.Container; import java.awt.Dialog; import java.awt.event.ActionEvent; @@ -31,6 +33,7 @@ import java.security.Provider; import java.security.Security; import java.text.MessageFormat; +import java.util.List; import java.util.ResourceBundle; import javax.swing.AbstractAction; @@ -59,7 +62,8 @@ import org.kse.gui.PlatformUtil; import org.kse.gui.error.DProblem; import org.kse.gui.error.Problem; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; import net.miginfocom.swing.MigLayout; @@ -71,7 +75,8 @@ public class DOpenPkcs11KeyStore extends JEscDialog { private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/resources"); - private transient ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); + private transient KsePreferences preferences = PreferencesManager.getPreferences(); + public static final int MAX_LIST_SIZE = 10; private static final String CANCEL_KEY = "CANCEL_KEY"; @@ -226,8 +231,8 @@ private String[] getPkcs11ProviderList() { } private String[] getLibraryList() { - String p11Libs = applicationSettings.getP11Libs(); - return p11Libs.split(";"); + List p11Libs = preferences.getPkcs11Libraries(); + return p11Libs.toArray(new String[p11Libs.size()]); } private void browsePressed() { @@ -295,7 +300,7 @@ private void okPressed() { selectedProvider = p11Provider; // save library in preferences - applicationSettings.addP11Lib(selectedLib); + preferences.setPkcs11Libraries(addToList(selectedLib, preferences.getPkcs11Libraries(), MAX_LIST_SIZE)); } closeDialog(); diff --git a/kse/src/main/java/org/kse/gui/dialogs/DViewCertificate.java b/kse/src/main/java/org/kse/gui/dialogs/DViewCertificate.java index fb16b9bc5..aff455de2 100644 --- a/kse/src/main/java/org/kse/gui/dialogs/DViewCertificate.java +++ b/kse/src/main/java/org/kse/gui/dialogs/DViewCertificate.java @@ -64,7 +64,6 @@ import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.util.encoders.Hex; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.KSE; import org.kse.crypto.CryptoException; import org.kse.crypto.KeyInfo; @@ -85,6 +84,8 @@ import org.kse.gui.crypto.JDistinguishedName; import org.kse.gui.dialogs.extensions.DViewExtensions; import org.kse.gui.error.DError; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.DialogViewer; import org.kse.utilities.StringUtils; import org.kse.utilities.asn1.Asn1Exception; @@ -101,6 +102,8 @@ public class DViewCertificate extends JEscDialog { private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/resources"); + private KsePreferences preferences = PreferencesManager.getPreferences(); + public static final int NONE = 0; public static final int IMPORT = 1; public static final int EXPORT = 2; @@ -610,7 +613,7 @@ private void populateDetails() { jcfFingerprint.setEncodedCertificate(encodedCertificate); - jcfFingerprint.setFingerprintAlg(ApplicationSettings.getInstance().getCertificateFingerprintType()); + jcfFingerprint.setFingerprintAlg(preferences.getCertificateFingerprintAlgorithm()); Set critExts = cert.getCriticalExtensionOIDs(); Set nonCritExts = cert.getNonCriticalExtensionOIDs(); @@ -685,7 +688,7 @@ private void exportPressed() { } private void okPressed() { - ApplicationSettings.getInstance().setCertificateFingerprintType(jcfFingerprint.getSelectedFingerprintAlg()); + preferences.setCertificateFingerprintAlgorithm(jcfFingerprint.getSelectedFingerprintAlg()); closeDialog(); } diff --git a/kse/src/main/java/org/kse/gui/dialogs/DViewDHParameters.java b/kse/src/main/java/org/kse/gui/dialogs/DViewDHParameters.java index b8b4de815..0ab2a3f51 100644 --- a/kse/src/main/java/org/kse/gui/dialogs/DViewDHParameters.java +++ b/kse/src/main/java/org/kse/gui/dialogs/DViewDHParameters.java @@ -43,7 +43,6 @@ import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; -import org.kse.gui.preferences.ApplicationSettings; import org.kse.crypto.CryptoException; import org.kse.gui.CurrentDirectory; import org.kse.gui.CursorUtil; @@ -181,7 +180,6 @@ private void writeDHParams(String filePath, byte[] DEREncodedDHParams) { * Calls the close dialogue window */ private void okPressed() { - ApplicationSettings.getInstance(); closeDialog(); } diff --git a/kse/src/main/java/org/kse/gui/dialogs/DViewPrivateKey.java b/kse/src/main/java/org/kse/gui/dialogs/DViewPrivateKey.java index 0d1027810..66c21f6a2 100644 --- a/kse/src/main/java/org/kse/gui/dialogs/DViewPrivateKey.java +++ b/kse/src/main/java/org/kse/gui/dialogs/DViewPrivateKey.java @@ -59,7 +59,7 @@ import org.kse.gui.crypto.privatekey.PrivateKeyUtils; import org.kse.gui.dialogs.importexport.DExportPrivateKeyType; import org.kse.gui.error.DError; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.DialogViewer; import org.kse.utilities.asn1.Asn1Exception; @@ -93,7 +93,7 @@ public class DViewPrivateKey extends JEscDialog { private String alias; private PrivateKey privateKey; - private ApplicationSettings applicationSettings; + private KsePreferences preferences; /** * Creates a new DViewPrivateKey dialog. @@ -103,11 +103,12 @@ public class DViewPrivateKey extends JEscDialog { * @param privateKey Private key to display * @throws CryptoException A problem was encountered getting the private key's details */ - public DViewPrivateKey(JFrame parent, String title, String alias, PrivateKey privateKey, ApplicationSettings applicationSettings) throws CryptoException { + public DViewPrivateKey(JFrame parent, String title, String alias, PrivateKey privateKey, KsePreferences preferences) + throws CryptoException { super(parent, title, Dialog.ModalityType.DOCUMENT_MODAL); this.alias = alias; this.privateKey = privateKey; - this.applicationSettings = applicationSettings; + this.preferences = preferences; initComponents(); } @@ -259,13 +260,13 @@ private void exportPressed() { } try { if (dExportPrivateKeyType.exportPkcs8()) { - PrivateKeyUtils.exportAsPkcs8(privateKey, alias, (JFrame) this.getParent(), applicationSettings, + PrivateKeyUtils.exportAsPkcs8(privateKey, alias, (JFrame) this.getParent(), preferences, resActions); } else if (dExportPrivateKeyType.exportPvk()) { - PrivateKeyUtils.exportAsPvk(privateKey, alias, (JFrame) this.getParent(), applicationSettings, + PrivateKeyUtils.exportAsPvk(privateKey, alias, (JFrame) this.getParent(), preferences, resActions); } else { - PrivateKeyUtils.exportAsOpenSsl(privateKey, alias, (JFrame) this.getParent(), applicationSettings, + PrivateKeyUtils.exportAsOpenSsl(privateKey, alias, (JFrame) this.getParent(), preferences, resActions); } } catch (Exception ex) { diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/JListCertificates.java b/kse/src/main/java/org/kse/gui/dialogs/sign/JListCertificates.java index e6d66de13..82b52cefe 100644 --- a/kse/src/main/java/org/kse/gui/dialogs/sign/JListCertificates.java +++ b/kse/src/main/java/org/kse/gui/dialogs/sign/JListCertificates.java @@ -40,7 +40,8 @@ import org.kse.gui.KeyStoreTableColumns; import org.kse.gui.KeyStoreTableModel; import org.kse.gui.PlatformUtil; -import org.kse.gui.preferences.ApplicationSettings; +import org.kse.gui.preferences.PreferencesManager; +import org.kse.gui.preferences.data.KsePreferences; import org.kse.utilities.history.KeyStoreHistory; /** @@ -52,9 +53,9 @@ public class JListCertificates extends JPanel { private JScrollPane jspListCertsTable; private JKseTable jtListCerts; - private ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); + private KsePreferences preferences = PreferencesManager.getPreferences(); - private KeyStoreTableColumns keyStoreTableColumns = new KeyStoreTableColumns(); + private KeyStoreTableColumns keyStoreTableColumns; private KeyStore keyStore; private int autoResizeMode = JTable.AUTO_RESIZE_LAST_COLUMN; /** @@ -67,8 +68,8 @@ public JListCertificates() { private void initComponents() { - keyStoreTableColumns = applicationSettings.getKeyStoreTableColumns(); - KeyStoreTableModel ksModel = new KeyStoreTableModel(keyStoreTableColumns); + keyStoreTableColumns = preferences.getKeyStoreTableColumns(); + KeyStoreTableModel ksModel = new KeyStoreTableModel(keyStoreTableColumns, preferences.getExpiryWarnDays()); jtListCerts = new JKseTable(ksModel); RowSorter sorter = new TableRowSorter<>(ksModel); diff --git a/kse/src/main/java/org/kse/gui/password/PasswordQualityConfig.java b/kse/src/main/java/org/kse/gui/password/PasswordQualityConfig.java index f4812dfed..9f6daa103 100644 --- a/kse/src/main/java/org/kse/gui/password/PasswordQualityConfig.java +++ b/kse/src/main/java/org/kse/gui/password/PasswordQualityConfig.java @@ -28,6 +28,12 @@ public class PasswordQualityConfig { private boolean enforced; private int minimumQuality; + /** + * Default c-tor to qualify as Java Bean + */ + public PasswordQualityConfig() { + } + /** * Construct password quality configuration. * diff --git a/kse/src/main/java/org/kse/gui/preferences/ApplicationSettings.java b/kse/src/main/java/org/kse/gui/preferences/ApplicationSettings.java deleted file mode 100644 index 615c335fa..000000000 --- a/kse/src/main/java/org/kse/gui/preferences/ApplicationSettings.java +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Copyright 2004 - 2013 Wayne Grant - * 2013 - 2023 Kai Kramer - * - * This file is part of KeyStore Explorer. - * - * KeyStore Explorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * KeyStore Explorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with KeyStore Explorer. If not, see . - */ -package org.kse.gui.preferences; - -import static org.kse.crypto.digest.DigestType.SHA1; -import static org.kse.crypto.keypair.KeyPairType.RSA; -import static org.kse.crypto.secretkey.SecretKeyType.AES; - -import java.awt.Rectangle; -import java.io.File; -import java.io.IOException; -import java.net.ProxySelector; -import java.net.URI; -import java.net.URISyntaxException; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.prefs.BackingStoreException; -import java.util.prefs.Preferences; - -import javax.swing.JTabbedPane; - -import org.kse.AuthorityCertificates; -import org.kse.crypto.digest.DigestType; -import org.kse.crypto.keypair.KeyPairType; -import org.kse.crypto.secretkey.SecretKeyType; -import org.kse.gui.KeyStoreTableColumns; -import org.kse.gui.KseFrame; -import org.kse.gui.password.PasswordQualityConfig; -import org.kse.utilities.StringUtils; -import org.kse.utilities.net.ManualProxySelector; -import org.kse.utilities.net.NoProxySelector; -import org.kse.utilities.net.PacProxySelector; -import org.kse.utilities.net.ProxyAddress; -import org.kse.utilities.net.ProxyConfigurationType; -import org.kse.utilities.net.SystemProxySelector; - -/** - * KSE Application settings. Load, save and provide access to the various - * application settings. Settings persist to Java preferences. - */ -public class ApplicationSettings { - - public static final String SYSTEM_LANGUAGE = "system"; - - private static final String PREFS_NODE = "/org/kse"; - private static final String PREFS_NODE_OLD = "/net/sf/keystore_explorer"; - - private static final String KSE3_DEFAULTDN = "kse3.defaultdn"; - private static final String KSE3_SSLHOSTS = "kse3.sslhosts"; - private static final String KSE3_SSLPORTS = "kse3.sslports"; - private static final String KSE3_TIPINDEX = "kse3.tipindex"; - private static final String KSE3_TIPSONSTARTUP = "kse3.tipsonstartup"; - private static final String KSE3_LICENSEAGREED = "kse3.licenseagreed"; - private static final String KSE3_LOOKFEEL = "kse3.lookfeel"; - private static final String KSE3_LOOKFEELDECOR = "kse3.lookfeeldecor"; - private static final String KSE3_CURRENTDIR = "kse3.currentdir"; - private static final String KSE3_RECENTFILE = "kse3.recentfile"; - private static final String KSE3_TABLAYOUT = "kse3.tablayout"; - private static final String KSE3_SHOWSTATUSBAR = "kse3.showstatusbar"; - private static final String KSE3_SHOWTOOLBAR = "kse3.showtoolbar"; - private static final String KSE3_WIDTH = "kse3.width"; - private static final String KSE3_HEIGHT = "kse3.height"; - private static final String KSE3_YPOS = "kse3.ypos"; - private static final String KSE3_XPOS = "kse3.xpos"; - private static final String KSE3_PROXY = "kse3.proxy"; - private static final String KSE3_SOCKSPORT = "kse3.socksport"; - private static final String KSE3_SOCKSHOST = "kse3.sockshost"; - private static final String KSE3_HTTPSPORT = "kse3.httpsport"; - private static final String KSE3_HTTPSHOST = "kse3.httpshost"; - private static final String KSE3_HTTPPORT = "kse3.httpport"; - private static final String KSE3_HTTPHOST = "kse3.httphost"; - private static final String KSE3_PACURL = "kse3.pacurl"; - private static final String KSE3_MINPWDQUALENFORCE = "kse3.minpwdqualenforce"; - private static final String KSE3_MINPWDQUAL = "kse3.minpwdqual"; - private static final String KSE3_PWDQUALENABLE = "kse3.pwdqualenable"; - private static final String KSE3_CERTFINGERTYPE = "kse3.certfingertype"; - private static final String KSE3_SECKEYSIZE = "kse3.seckeysize"; - private static final String KSE3_SECKEYTYPE = "kse3.seckeytype"; - private static final String KSE3_KEYPAIRTYPE = "kse3.keypairtype"; - private static final String KSE3_KEYPAIR_SIZE_RSA = "kse3.keypairsize"; - private static final String KSE3_KEYPAIR_SIZE_DSA = "kse3.keypairdsasize"; - private static final String KSE3_KEYPAIR_EC_SET = "kse3.keypairset"; - private static final String KSE3_KEYPAIR_EC_CURVE = "kse3.keypaircurve"; - private static final String KSE3_ENABLEIMPORTCAREPLYTRUSTCHECK = "kse3.enableimportcareplytrustcheck"; - private static final String KSE3_ENABLEIMPORTTRUSTEDCERTTRUSTCHECK = "kse3.enableimporttrustedcerttrustcheck"; - private static final String KSE3_USEWINTRUSTROOTCERTS = "kse3.usewintrustrootcerts"; - private static final String KSE3_CACERTSFILE = "kse3.cacertsfile"; - private static final String KSE3_USECACERTS = "kse3.usecacerts"; - private static final String KSE3_AUTO_UPDATE_CHECK_ENABLED = "kse3.autoupdatecheckenabled"; - private static final String KSE3_AUTO_UPDATE_CHECK_LAST_CHECK = "kse3.autoupdatechecklastcheck"; - private static final String KSE3_AUTO_UPDATE_CHECK_INTERVAL = "kse3.autoupdatecheckinterval"; - private static final String KSE3_PKCS11_LIBS = "kse3.pkcs11libs"; - private static final String KSE3_LANGUAGE = "kse3.locale"; - private static final String KSE3_EXPIRY_WARN_DAYS = "kse3.expirywarndays"; - private static final String KSE3_COLUMNS = "kse3.columns"; - private static final String KSE3_SHOW_HIDDEN_FILES = "kse3.showhiddenfiles"; - private static final String KSE3_PKCS12_ENCRYPTION = "kse3.pkcs12encryption"; - private static final String KSE3_SN_LENGTH_IN_BYTES = "kse3.snlength"; - - private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - private static ApplicationSettings applicationSettings; - private boolean useCaCertificates; - private File caCertificatesFile; - private boolean useWindowsTrustedRootCertificates; - private boolean enableImportTrustedCertTrustCheck; - private boolean enableImportCaReplyTrustCheck; - private KeyPairType generateKeyPairType; - private int generateKeyPairSizeRSA; - private int generateKeyPairSizeDSA; - private String generateKeyPairCurveSet; - private String generateKeyPairCurveName; - private SecretKeyType generateSecretKeyType; - private int generateSecretKeySize; - private DigestType certificateFingerprintType; - private PasswordQualityConfig passwordQualityConfig; - private Rectangle sizeAndPosition; - private boolean showToolBar; - private boolean showStatusBar; - private int tabLayout; - private File[] recentFiles; - private File currentDirectory; - private String lookAndFeelClass; - private boolean lookAndFeelDecorated; - private boolean licenseAgreed; - private boolean showTipsOnStartUp; - private int nextTipIndex; - private String defaultDN; - private String sslHosts; - private String sslPorts; - private boolean autoUpdateCheckEnabled; - private Date autoUpdateCheckLastCheck; - private int autoUpdateCheckInterval; - private String p11Libs; - private String language; - private KeyStoreTableColumns kstColumns = new KeyStoreTableColumns(); - private int expiryWarnDays; - private boolean showHiddenFilesEnabled; - private Pkcs12EncryptionSetting pkcs12EncryptionSetting; - private int serialNumberLengthInBytes; - - private ApplicationSettings() { - - // one-time conversion from old to new preferences location: - Preferences root = Preferences.userRoot(); - try { - // if preferences exist under /net/sf/keystore_explorer but not under /org/kse ... - if (root.nodeExists(PREFS_NODE_OLD) && !root.nodeExists(PREFS_NODE)) { - - // ... then copy settings from old to new subtree - Preferences prefsOld = root.node(PREFS_NODE_OLD); - Preferences prefsNew = root.node(PREFS_NODE); - - for (String key : prefsOld.keys()) { - prefsNew.put(key, prefsOld.get(key, "")); - } - - prefsNew.flush(); - } - } catch (BackingStoreException e) { - // ignore errors here - } - - load(); - } - - /** - * Get singleton instance of application settings. If first call the - * application settings are loaded. - * - * @return Application settings - */ - public static synchronized ApplicationSettings getInstance() { - if (applicationSettings == null) { - applicationSettings = new ApplicationSettings(); - } - - return applicationSettings; - } - - /** - * Load application settings from persistent store. - */ - public void load() { - Preferences preferences = getUnderlyingPreferences(); - - // Authority certificates - useCaCertificates = preferences.getBoolean(KSE3_USECACERTS, false); - String cacertsPath = preferences.get(KSE3_CACERTSFILE, - AuthorityCertificates.getDefaultCaCertificatesLocation().toString()); - caCertificatesFile = cleanFilePath(new File(cacertsPath)); - useWindowsTrustedRootCertificates = preferences.getBoolean(KSE3_USEWINTRUSTROOTCERTS, false); - - // Trust checks - enableImportTrustedCertTrustCheck = preferences.getBoolean(KSE3_ENABLEIMPORTTRUSTEDCERTTRUSTCHECK, false); - enableImportCaReplyTrustCheck = preferences.getBoolean(KSE3_ENABLEIMPORTCAREPLYTRUSTCHECK, false); - - // Key pair generation - algorithm - generateKeyPairType = KeyPairType.resolveJce(preferences.get(KSE3_KEYPAIRTYPE, RSA.jce())); - if (generateKeyPairType == null) { - generateKeyPairType = RSA; - } - - // Key pair generation - key size - generateKeyPairSizeRSA = preferences.getInt(KSE3_KEYPAIR_SIZE_RSA, 2048); - generateKeyPairSizeDSA = preferences.getInt(KSE3_KEYPAIR_SIZE_DSA, 1024); - - // Key pair generation - ECC curve set - generateKeyPairCurveSet = preferences.get(KSE3_KEYPAIR_EC_SET, ""); - - // Key pair generation - ECC curve - generateKeyPairCurveName = preferences.get(KSE3_KEYPAIR_EC_CURVE, ""); - - // Secret key generation - generateSecretKeyType = SecretKeyType.resolveJce(preferences.get(KSE3_SECKEYTYPE, AES.jce())); - if (generateSecretKeyType == null) { - generateSecretKeyType = AES; - } - generateSecretKeySize = preferences.getInt(KSE3_SECKEYSIZE, 192); - - // Certificate fingerprint - certificateFingerprintType = DigestType.resolveJce(preferences.get(KSE3_CERTFINGERTYPE, SHA1.jce())); - if (certificateFingerprintType == null) { - certificateFingerprintType = SHA1; - } - - // Password quality - passwordQualityConfig = new PasswordQualityConfig(preferences.getBoolean(KSE3_PWDQUALENABLE, false), - preferences.getBoolean(KSE3_MINPWDQUALENFORCE, false), - preferences.getInt(KSE3_MINPWDQUAL, 60)); - - // Internet proxy settings - ProxyConfigurationType proxyConfigurationType = ProxyConfigurationType.resolve( - preferences.get(KSE3_PROXY, ProxyConfigurationType.SYSTEM.name())); - - // default should be system settings because of "java.net.useSystemProxies=true", save it for later usage - SystemProxySelector.setSystemProxySelector(ProxySelector.getDefault()); - - switch (proxyConfigurationType) { - case NONE: - ProxySelector.setDefault(new NoProxySelector()); - break; - case PAC: - // Use PAC URL for proxy configuration - String pacUrl = preferences.get(KSE3_PACURL, null); - if (pacUrl != null) { - try { - ProxySelector.setDefault(new PacProxySelector(new URI(pacUrl))); - } catch (URISyntaxException e) { - e.printStackTrace(); - ProxySelector.setDefault(new NoProxySelector()); - } - } else { - ProxySelector.setDefault(new NoProxySelector()); - } - break; - case MANUAL: - // Use manual settings for HTTP, HTTPS and SOCKS - ProxyAddress httpProxyAddress = null; - ProxyAddress httpsProxyAddress = null; - ProxyAddress socksProxyAddress = null; - - String httpHost = preferences.get(KSE3_HTTPHOST, null); - int httpPort = preferences.getInt(KSE3_HTTPPORT, 0); - - if (httpHost != null && httpPort > 0) { - httpProxyAddress = new ProxyAddress(httpHost, httpPort); - } - - String httpsHost = preferences.get(KSE3_HTTPSHOST, null); - int httpsPort = preferences.getInt(KSE3_HTTPSPORT, 0); - - if (httpsHost != null && httpsPort > 0) { - httpsProxyAddress = new ProxyAddress(httpsHost, httpsPort); - } - - String socksHost = preferences.get(KSE3_SOCKSHOST, null); - int socksPort = preferences.getInt(KSE3_SOCKSPORT, 0); - - if (socksHost != null && socksPort > 0) { - socksProxyAddress = new ProxyAddress(socksHost, socksPort); - } - - if (httpProxyAddress != null || httpsProxyAddress != null) { - ProxySelector.setDefault( - new ManualProxySelector(httpProxyAddress, httpsProxyAddress, null, socksProxyAddress)); - } else { - // no manual settings - use no proxy to connect to the Internet - ProxySelector.setDefault(new NoProxySelector()); - } - break; - case SYSTEM: - default: - ProxySelector.setDefault(new SystemProxySelector()); - break; - } - - // Application size and position - sizeAndPosition = new Rectangle(preferences.getInt(KSE3_XPOS, 0), preferences.getInt(KSE3_YPOS, 0), - preferences.getInt(KSE3_WIDTH, KseFrame.DEFAULT_WIDTH), - preferences.getInt(KSE3_HEIGHT, KseFrame.DEFAULT_HEIGHT)); - - // User interface - showToolBar = preferences.getBoolean(KSE3_SHOWTOOLBAR, true); - showStatusBar = preferences.getBoolean(KSE3_SHOWSTATUSBAR, true); - tabLayout = preferences.getInt(KSE3_TABLAYOUT, JTabbedPane.WRAP_TAB_LAYOUT); - - // Recent files - ArrayList recentFilesList = new ArrayList<>(); - for (int i = 1; i <= KseFrame.RECENT_FILES_SIZE; i++) { - String recentFile = preferences.get(KSE3_RECENTFILE + i, null); - - if (recentFile == null) { - break; - } else { - recentFilesList.add(cleanFilePath(new File(recentFile))); - } - } - recentFiles = recentFilesList.toArray(new File[0]); - - // Current directory - String currentDirectoryStr = preferences.get(KSE3_CURRENTDIR, null); - if (currentDirectoryStr != null) { - currentDirectory = cleanFilePath(new File(currentDirectoryStr)); - } - - // Look and feel - lookAndFeelClass = preferences.get(KSE3_LOOKFEEL, null); - lookAndFeelDecorated = preferences.getBoolean(KSE3_LOOKFEELDECOR, false); - - // Licensing - licenseAgreed = preferences.getBoolean(KSE3_LICENSEAGREED, false); - - // Tip of the day - showTipsOnStartUp = preferences.getBoolean(KSE3_TIPSONSTARTUP, true); - nextTipIndex = preferences.getInt(KSE3_TIPINDEX, 0); - - // Default distinguished name - defaultDN = preferences.get(KSE3_DEFAULTDN, ""); - - // SSL host names and ports for "Examine SSL" - sslHosts = preferences.get(KSE3_SSLHOSTS, "www.google.com;www.amazon.com"); - sslPorts = preferences.get(KSE3_SSLPORTS, "443"); - - // auto update check - autoUpdateCheckEnabled = preferences.getBoolean(KSE3_AUTO_UPDATE_CHECK_ENABLED, true); - autoUpdateCheckInterval = preferences.getInt(KSE3_AUTO_UPDATE_CHECK_INTERVAL, 14); - autoUpdateCheckLastCheck = getDate(preferences, KSE3_AUTO_UPDATE_CHECK_LAST_CHECK, new Date()); - - // PKCS#11 libraries - p11Libs = preferences.get(KSE3_PKCS11_LIBS, ""); - - // language - language = preferences.get(KSE3_LANGUAGE, SYSTEM_LANGUAGE); - - // displayed columns - kstColumns.setColumns(preferences.getInt(KSE3_COLUMNS, 0x1F)); - - // number of days before expiration warning is shown - expiryWarnDays = preferences.getInt(KSE3_EXPIRY_WARN_DAYS, 0); - kstColumns.setExpiryWarnDays(expiryWarnDays); - - // show hidden files in file chooser dialogs? - showHiddenFilesEnabled = preferences.getBoolean(KSE3_SHOW_HIDDEN_FILES, true); - - // pkcs12 encryption strong or compatible? - pkcs12EncryptionSetting = Pkcs12EncryptionSetting.valueOf(preferences.get(KSE3_PKCS12_ENCRYPTION, "strong")); - - // length of auto-generated certificate serial number - serialNumberLengthInBytes = preferences.getInt(KSE3_SN_LENGTH_IN_BYTES, 20); - } - - private File cleanFilePath(File filePath) { - try { - return filePath.getCanonicalFile(); - } catch (IOException e) { - return filePath; - } - } - - private Date getDate(Preferences preferences, String name, Date def) { - try { - return dateFormat.parse(preferences.get(name, dateFormat.format(def))); - } catch (ParseException e) { - return def; - } - } - - /** - * Save application settings to persistent store. - */ - public void save() { - Preferences preferences = getUnderlyingPreferences(); - - // Authority certificates - preferences.putBoolean(KSE3_USECACERTS, useCaCertificates); - preferences.put(KSE3_CACERTSFILE, caCertificatesFile.toString()); - preferences.putBoolean(KSE3_USEWINTRUSTROOTCERTS, useWindowsTrustedRootCertificates); - - // Trust checks - preferences.putBoolean(KSE3_ENABLEIMPORTTRUSTEDCERTTRUSTCHECK, enableImportTrustedCertTrustCheck); - preferences.putBoolean(KSE3_ENABLEIMPORTCAREPLYTRUSTCHECK, enableImportCaReplyTrustCheck); - - // Key pair generation - preferences.put(KSE3_KEYPAIRTYPE, generateKeyPairType.jce()); - preferences.putInt(KSE3_KEYPAIR_SIZE_RSA, generateKeyPairSizeRSA); - preferences.putInt(KSE3_KEYPAIR_SIZE_DSA, generateKeyPairSizeDSA); - preferences.put(KSE3_KEYPAIR_EC_SET, generateKeyPairCurveSet); - preferences.put(KSE3_KEYPAIR_EC_CURVE, generateKeyPairCurveName); - - // Secret key generation - preferences.put(KSE3_SECKEYTYPE, generateSecretKeyType.jce()); - preferences.putInt(KSE3_SECKEYSIZE, generateSecretKeySize); - - // Certificate fingerprint - preferences.put(KSE3_CERTFINGERTYPE, certificateFingerprintType.jce()); - - // Password quality - preferences.putBoolean(KSE3_PWDQUALENABLE, passwordQualityConfig.getEnabled()); - preferences.putBoolean(KSE3_MINPWDQUALENFORCE, passwordQualityConfig.getEnforced()); - preferences.putInt(KSE3_MINPWDQUAL, passwordQualityConfig.getMinimumQuality()); - - // Internet proxy settings - getCurrentProxySettings(preferences); - - // Application size and position - preferences.putInt(KSE3_XPOS, sizeAndPosition.x); - preferences.putInt(KSE3_YPOS, sizeAndPosition.y); - preferences.putInt(KSE3_WIDTH, sizeAndPosition.width); - preferences.putInt(KSE3_HEIGHT, sizeAndPosition.height); - - // User interface - preferences.putBoolean(KSE3_SHOWTOOLBAR, showToolBar); - preferences.putBoolean(KSE3_SHOWSTATUSBAR, showStatusBar); - preferences.putInt(KSE3_TABLAYOUT, tabLayout); - - // Recent files - clearExistingRecentFiles(preferences); - for (int i = 1; i <= recentFiles.length; i++) { - preferences.put(KSE3_RECENTFILE + i, recentFiles[i - 1].toString()); - } - - // Current directory - preferences.put(KSE3_CURRENTDIR, currentDirectory.toString()); - - // Look and feel - preferences.put(KSE3_LOOKFEEL, lookAndFeelClass); - preferences.putBoolean(KSE3_LOOKFEELDECOR, lookAndFeelDecorated); - - // Licensing - preferences.putBoolean(KSE3_LICENSEAGREED, licenseAgreed); - - // Tip of the day - preferences.putBoolean(KSE3_TIPSONSTARTUP, showTipsOnStartUp); - preferences.putInt(KSE3_TIPINDEX, nextTipIndex); - - // Default distinguished name - preferences.put(KSE3_DEFAULTDN, defaultDN); - - // SSL host names and ports for "Examine SSL" - preferences.put(KSE3_SSLHOSTS, getSslHosts()); - preferences.put(KSE3_SSLPORTS, getSslPorts()); - - // auto update check settings - preferences.putBoolean(KSE3_AUTO_UPDATE_CHECK_ENABLED, isAutoUpdateCheckEnabled()); - preferences.putInt(KSE3_AUTO_UPDATE_CHECK_INTERVAL, getAutoUpdateCheckInterval()); - preferences.put(KSE3_AUTO_UPDATE_CHECK_LAST_CHECK, dateFormat.format(getAutoUpdateCheckLastCheck())); - - // PKCS#11 libraries - preferences.put(KSE3_PKCS11_LIBS, getP11Libs()); - - // language - preferences.put(KSE3_LANGUAGE, language); - - // table columns - preferences.putInt(KSE3_COLUMNS, kstColumns.getColumns()); - - // expiration warning - preferences.putInt(KSE3_EXPIRY_WARN_DAYS, kstColumns.getExpiryWarnDays()); - - // hide/show hidden files in file chooser - preferences.putBoolean(KSE3_SHOW_HIDDEN_FILES, isShowHiddenFilesEnabled()); - - // pkcs12 encryption strong or compatible? - preferences.put(KSE3_PKCS12_ENCRYPTION, pkcs12EncryptionSetting.name()); - - // number of random bytes in serial number generation - preferences.putInt(KSE3_SN_LENGTH_IN_BYTES, serialNumberLengthInBytes); - } - - private void clearExistingRecentFiles(Preferences preferences) { - // Clear all existing recent files (new list may be shorter than the existing one) - for (int i = 1; i <= KseFrame.RECENT_FILES_SIZE; i++) { - String recentFile = preferences.get(KSE3_RECENTFILE + i, null); - - if (recentFile == null) { - break; - } else { - preferences.remove(KSE3_RECENTFILE + i); - } - } - } - - private void getCurrentProxySettings(Preferences preferences) { - // Get current proxy settings - ProxySelector proxySelector = ProxySelector.getDefault(); - - if (proxySelector instanceof NoProxySelector) { - preferences.put(KSE3_PROXY, ProxyConfigurationType.NONE.name()); - } else if (proxySelector instanceof SystemProxySelector) { - preferences.put(KSE3_PROXY, ProxyConfigurationType.SYSTEM.name()); - } else if (proxySelector instanceof PacProxySelector) { - PacProxySelector pacProxySelector = (PacProxySelector) proxySelector; - - preferences.put(KSE3_PACURL, pacProxySelector.getPacURI().toString()); - preferences.put(KSE3_PROXY, ProxyConfigurationType.PAC.name()); - } else if (proxySelector instanceof ManualProxySelector) { - ManualProxySelector manualProxySelector = (ManualProxySelector) proxySelector; - - ProxyAddress httpProxyAddress = manualProxySelector.getHttpProxyAddress(); - if (httpProxyAddress != null) { - preferences.put(KSE3_HTTPHOST, httpProxyAddress.getHost()); - preferences.putInt(KSE3_HTTPPORT, httpProxyAddress.getPort()); - } - - ProxyAddress httpsProxyAddress = manualProxySelector.getHttpsProxyAddress(); - if (httpsProxyAddress != null) { - preferences.put(KSE3_HTTPSHOST, httpsProxyAddress.getHost()); - preferences.putInt(KSE3_HTTPSPORT, httpsProxyAddress.getPort()); - } - - ProxyAddress socksProxyAddress = manualProxySelector.getSocksProxyAddress(); - if (socksProxyAddress != null) { - preferences.put(KSE3_SOCKSHOST, socksProxyAddress.getHost()); - preferences.putInt(KSE3_SOCKSPORT, socksProxyAddress.getPort()); - } - - preferences.put(KSE3_PROXY, ProxyConfigurationType.MANUAL.name()); - } - } - - /** - * Clear application settings in persistent store. - * - * @throws BackingStoreException If a failure occurred in the backing store - */ - public void clear() throws BackingStoreException { - Preferences preferences = getUnderlyingPreferences(); - preferences.clear(); - } - - private Preferences getUnderlyingPreferences() { - // Get underlying Java preferences - return Preferences.userRoot().node(PREFS_NODE); - } - - /** - * Add a new SSL port to start of current list of ports. - *

- * Maximum number is 10. If port is already in list, it is brought to the first position. - * - * @param newSslPort New SSL port - */ - public void addSslPort(String newSslPort) { - - String newSslPorts = StringUtils.addToList(newSslPort, getSslPorts(), 10); - - setSslPorts(newSslPorts); - } - - /** - * Add a new SSL host to start of current list of hosts. - *

- * Maximum number is 10. If host is already in list, it is brought to the first position. - * - * @param newSslHost New SSL host - */ - public void addSslHost(String newSslHost) { - - String newSslHosts = StringUtils.addToList(newSslHost, getSslHosts(), 10); - - setSslHosts(newSslHosts); - } - - /** - * Add a new PKCS#11 library path host to start of current list of libraries. - *

- * Maximum number is 10. If host is already in list, it is brought to the first position. - * - * @param p11Lib New SSL host - */ - public void addP11Lib(String p11Lib) { - - String newP11Libs = StringUtils.addToList(p11Lib, getP11Libs(), 10); - - setP11Libs(newP11Libs); - } - - public boolean getUseCaCertificates() { - return useCaCertificates; - } - - public void setUseCaCertificates(boolean useCaCertificates) { - this.useCaCertificates = useCaCertificates; - } - - public File getCaCertificatesFile() { - return caCertificatesFile; - } - - public void setCaCertificatesFile(File caCertificatesFile) { - this.caCertificatesFile = caCertificatesFile; - } - - public boolean getUseWindowsTrustedRootCertificates() { - return useWindowsTrustedRootCertificates; - } - - public void setUseWindowsTrustedRootCertificates(boolean useWindowsTrustedRootCertificates) { - this.useWindowsTrustedRootCertificates = useWindowsTrustedRootCertificates; - } - - public boolean getEnableImportTrustedCertTrustCheck() { - return enableImportTrustedCertTrustCheck; - } - - public void setEnableImportTrustedCertTrustCheck(boolean enableImportTrustedCertTrustCheck) { - this.enableImportTrustedCertTrustCheck = enableImportTrustedCertTrustCheck; - } - - public boolean getEnableImportCaReplyTrustCheck() { - return enableImportCaReplyTrustCheck; - } - - public void setEnableImportCaReplyTrustCheck(boolean enableImportCaReplyTrustCheck) { - this.enableImportCaReplyTrustCheck = enableImportCaReplyTrustCheck; - } - - public KeyPairType getGenerateKeyPairType() { - return generateKeyPairType; - } - - public void setGenerateKeyPairType(KeyPairType generateKeyPairType) { - this.generateKeyPairType = generateKeyPairType; - } - - public int getGenerateKeyPairSizeRSA() { - return generateKeyPairSizeRSA; - } - - public void setGenerateKeyPairSizeRSA(int generateKeyPairSizeRSA) { - this.generateKeyPairSizeRSA = generateKeyPairSizeRSA; - } - - public int getGenerateKeyPairSizeDSA() { - return generateKeyPairSizeDSA; - } - - public void setGenerateKeyPairSizeDSA(int generateKeyPairSizeDSA) { - this.generateKeyPairSizeDSA = generateKeyPairSizeDSA; - } - - public String getGenerateKeyPairCurveSet() { - return generateKeyPairCurveSet; - } - - public void setGenerateKeyPairCurveSet(String generateKeyPairCurveSet) { - this.generateKeyPairCurveSet = generateKeyPairCurveSet; - } - - public String getGenerateKeyPairCurveName() { - return generateKeyPairCurveName; - } - - public void setGenerateKeyPairCurveName(String generateKeyPairCurveName) { - this.generateKeyPairCurveName = generateKeyPairCurveName; - } - - public SecretKeyType getGenerateSecretKeyType() { - return generateSecretKeyType; - } - - public void setGenerateSecretKeyType(SecretKeyType generateSecretKeyType) { - this.generateSecretKeyType = generateSecretKeyType; - } - - public int getGenerateSecretKeySize() { - return generateSecretKeySize; - } - - public void setGenerateSecretKeySize(int generateSecretKeySize) { - this.generateSecretKeySize = generateSecretKeySize; - } - - public DigestType getCertificateFingerprintType() { - return certificateFingerprintType; - } - - public void setCertificateFingerprintType(DigestType certificateFingerprintType) { - this.certificateFingerprintType = certificateFingerprintType; - } - - public PasswordQualityConfig getPasswordQualityConfig() { - return passwordQualityConfig; - } - - public void setPasswordQualityConfig(PasswordQualityConfig passwordQualityConfig) { - this.passwordQualityConfig = passwordQualityConfig; - } - - public Rectangle getSizeAndPosition() { - return sizeAndPosition; - } - - public void setSizeAndPosition(Rectangle sizeAndPosition) { - this.sizeAndPosition = sizeAndPosition; - } - - public boolean getShowToolBar() { - return showToolBar; - } - - public void setShowToolBar(boolean showToolBar) { - this.showToolBar = showToolBar; - } - - public boolean getShowStatusBar() { - return showStatusBar; - } - - public void setShowStatusBar(boolean showStatusBar) { - this.showStatusBar = showStatusBar; - } - - public int getTabLayout() { - return tabLayout; - } - - public void setTabLayout(int tabLayout) { - this.tabLayout = tabLayout; - } - - public File[] getRecentFiles() { - return recentFiles; - } - - public void setRecentFiles(File[] recentFiles) { - this.recentFiles = recentFiles; - } - - public File getCurrentDirectory() { - return currentDirectory; - } - - public void setCurrentDirectory(File currentDirectory) { - this.currentDirectory = currentDirectory; - } - - public String getLookAndFeelClass() { - return lookAndFeelClass; - } - - public void setLookAndFeelClass(String lookAndFeelClass) { - this.lookAndFeelClass = lookAndFeelClass; - } - - public boolean getLookAndFeelDecorated() { - return lookAndFeelDecorated; - } - - public void setLookAndFeelDecorated(boolean lookAndFeelDecorated) { - this.lookAndFeelDecorated = lookAndFeelDecorated; - } - - public boolean getShowTipsOnStartUp() { - return showTipsOnStartUp; - } - - public void setShowTipsOnStartUp(boolean showTipsOnStartUp) { - this.showTipsOnStartUp = showTipsOnStartUp; - } - - public int getNextTipIndex() { - return nextTipIndex; - } - - public void setNextTipIndex(int nextTipIndex) { - this.nextTipIndex = nextTipIndex; - } - - public String getDefaultDN() { - return defaultDN; - } - - public void setDefaultDN(String defaultDN) { - this.defaultDN = defaultDN; - } - - public String getSslHosts() { - return sslHosts; - } - - public void setSslHosts(String sslHosts) { - this.sslHosts = sslHosts; - } - - public String getSslPorts() { - return sslPorts; - } - - public void setSslPorts(String sslPorts) { - this.sslPorts = sslPorts; - } - - public boolean isAutoUpdateCheckEnabled() { - return autoUpdateCheckEnabled; - } - - public void setAutoUpdateCheckEnabled(boolean autoUpdateCheckEnabled) { - this.autoUpdateCheckEnabled = autoUpdateCheckEnabled; - } - - public Date getAutoUpdateCheckLastCheck() { - return autoUpdateCheckLastCheck; - } - - public void setAutoUpdateCheckLastCheck(Date autoUpdateCheckLastCheck) { - this.autoUpdateCheckLastCheck = autoUpdateCheckLastCheck; - } - - public int getAutoUpdateCheckInterval() { - return autoUpdateCheckInterval; - } - - public void setAutoUpdateCheckInterval(int autoUpdateCheckInterval) { - this.autoUpdateCheckInterval = autoUpdateCheckInterval; - } - - public String getP11Libs() { - return p11Libs; - } - - public void setP11Libs(String p11Libs) { - this.p11Libs = p11Libs; - } - - public String getLanguage() { - return language; - } - - public void setLanguage(String language) { - this.language = language; - } - - public KeyStoreTableColumns getKeyStoreTableColumns() { - return this.kstColumns; - } - - public void setKeyStoreTableColumns(KeyStoreTableColumns kstColumns) { - this.kstColumns = kstColumns; - } - - public int getExpiryWarndays() { - return expiryWarnDays; - } - - public void setExpiryWarndays(int expiryWarnDays) { - this.expiryWarnDays = expiryWarnDays; - } - - public boolean isShowHiddenFilesEnabled() { - return showHiddenFilesEnabled; - } - - public void setShowHiddenFilesEnabled(boolean showHiddenFilesEnabled) { - this.showHiddenFilesEnabled = showHiddenFilesEnabled; - } - - public Pkcs12EncryptionSetting getPkcs12EncryptionSetting() { - return pkcs12EncryptionSetting; - } - - public void setPkcs12EncryptionSetting(Pkcs12EncryptionSetting pkcs12EncryptionSetting) { - this.pkcs12EncryptionSetting = pkcs12EncryptionSetting; - } - - public int getSerialNumberLengthInBytes() { - return serialNumberLengthInBytes; - } - - public void setSerialNumberLengthInBytes(int serialNumberLengthInBytes) { - this.serialNumberLengthInBytes = serialNumberLengthInBytes; - } -} diff --git a/kse/src/main/java/org/kse/gui/preferences/DPreferences.java b/kse/src/main/java/org/kse/gui/preferences/DPreferences.java index 7c680151e..ffe1460bd 100644 --- a/kse/src/main/java/org/kse/gui/preferences/DPreferences.java +++ b/kse/src/main/java/org/kse/gui/preferences/DPreferences.java @@ -74,6 +74,9 @@ import org.kse.gui.PlatformUtil; import org.kse.gui.dnchooser.DistinguishedNameChooser; import org.kse.gui.password.PasswordQualityConfig; +import org.kse.gui.preferences.data.KsePreferences; +import org.kse.gui.preferences.data.LanguageItem; +import org.kse.gui.preferences.data.Pkcs12EncryptionSetting; import org.kse.utilities.DialogViewer; import org.kse.utilities.net.ManualProxySelector; import org.kse.utilities.net.NoProxySelector; @@ -177,41 +180,24 @@ public class DPreferences extends JEscDialog { private JPanel jpDisplayColumns; private JCheckBox jcbEnableEntryName; - private boolean bEnableEntryName; private JCheckBox jcbEnableAlgorithm; - private boolean bEnableAlgorithm; private JCheckBox jcbEnableKeySize; - private boolean bEnableKeySize; private JCheckBox jcbEnableCertificateValidityStart; - private boolean bEnableCertificateValidityStart; private JCheckBox jcbEnableCertificateExpiry; - private boolean bEnableCertificateExpiry; private JCheckBox jcbEnableLastModified; - private boolean bEnableLastModified; private JCheckBox jcbEnableCurve; - private boolean bEnableCurve; private JCheckBox jcbEnableSKI; - private boolean bEnableSKI; private JCheckBox jcbEnableAKI; - private boolean bEnableAKI; private JCheckBox jcbEnableIssuerDN; - private boolean bEnableIssuerDN; private JCheckBox jcbEnableIssuerCN; - private boolean bEnableIssuerCN; private JCheckBox jcbEnableSubjectDN; - private boolean bEnableSubjectDN; private JCheckBox jcbEnableSubjectCN; - private boolean bEnableSubjectCN; private JCheckBox jcbEnableIssuerO; - private boolean bEnableIssuerO; private JCheckBox jcbEnableSubjectO; - private boolean bEnableSerialNumberHex; private JCheckBox jcbEnableSerialNumberHex; - private boolean bEnableSerialNumberDec; private JCheckBox jcbEnableSerialNumberDec; - private boolean bEnableSubjectO; private JLabel jlExpirationWarnDays; - private JTextField jtfExpirationWarnDays; + private JSpinner jspExpirationWarnDays; private boolean bColumnsChanged; private JSplitPane jsPane; private JScrollPane rightScPane; @@ -221,54 +207,32 @@ public class DPreferences extends JEscDialog { private DefaultMutableTreeNode rootNode; private JTree jtree; - /** * Creates a new DPreference dialog. * - * @param parent The parent frame - * @param useCaCertificates Use CA Certificates keystore file? - * @param caCertificatesFile CA Certificates keystore file - * @param useWinTrustedRootCertificates Use Windows Trusted Root - * Certificates? - * @param enableImportTrustedCertTrustCheck Enable trust checks when importing - * Trusted Certificates? - * @param enableImportCaReplyTrustCheck Enable trust checks when importing - * CA replies? - * @param passwordQualityConfig Password quality configuration - * @param defaultDN Default subject DN for new certificates - * @param language KSE UI language - * @param autoUpdateChecksEnabled Automatic check for updates enabled or not - * @param autoUpdateChecksInterval Interval for autmatic update checks - * @param kstColumns Shown columns in the main table - * @param showHiddenFilesEnabled Show hidden files in file chooser - * @param pkcs12EncryptionSetting Strong or compatible PKCS#12 encryption? - * @param serialNumberLengthInBytes Length of serial number random bytes + * @param parent The parent frame + * @param preferences Current state of preferences, probably as loaded from config file */ - public DPreferences(JFrame parent, boolean useCaCertificates, File caCertificatesFile, - boolean useWinTrustedRootCertificates, boolean enableImportTrustedCertTrustCheck, - boolean enableImportCaReplyTrustCheck, PasswordQualityConfig passwordQualityConfig, - String defaultDN, String language, boolean autoUpdateChecksEnabled, - int autoUpdateChecksInterval, KeyStoreTableColumns kstColumns, boolean showHiddenFilesEnabled, - Pkcs12EncryptionSetting pkcs12EncryptionSetting, int serialNumberLengthInBytes) { + public DPreferences(JFrame parent, KsePreferences preferences) { super(parent, Dialog.ModalityType.DOCUMENT_MODAL); setResizable(true); Dimension d = new Dimension(900, 500); setMinimumSize(d); - this.useCaCertificates = useCaCertificates; - this.caCertificatesFile = caCertificatesFile; - this.useWinTrustRootCertificates = useWinTrustedRootCertificates; - this.enableImportTrustedCertTrustCheck = enableImportTrustedCertTrustCheck; - this.enableImportCaReplyTrustCheck = enableImportCaReplyTrustCheck; - this.passwordQualityConfig = passwordQualityConfig; - this.defaultDN = defaultDN; - this.language = language; - this.autoUpdateChecksEnabled = autoUpdateChecksEnabled; - this.autoUpdateChecksInterval = autoUpdateChecksInterval; - this.kstColumns = kstColumns; - this.expiryWarnDays = kstColumns.getExpiryWarnDays(); - this.showHiddenFilesEnabled = showHiddenFilesEnabled; - this.pkcs12EncryptionSetting = pkcs12EncryptionSetting; - this.serialNumberLengthInBytes = serialNumberLengthInBytes; + this.useCaCertificates = preferences.getCaCertsSettings().isUseCaCertificates(); + this.caCertificatesFile = new File(preferences.getCaCertsSettings().getCaCertificatesFile()); + this.useWinTrustRootCertificates = preferences.getCaCertsSettings().isUseWindowsTrustedRootCertificates(); + this.enableImportTrustedCertTrustCheck = preferences.getCaCertsSettings().isImportTrustedCertTrustCheckEnabled(); + this.enableImportCaReplyTrustCheck = preferences.getCaCertsSettings().isImportCaReplyTrustCheckEnabled(); + this.passwordQualityConfig = preferences.getPasswordQualityConfig(); + this.defaultDN = preferences.getDefaultSubjectDN(); + this.language = preferences.getLanguage(); + this.autoUpdateChecksEnabled = preferences.getAutoUpdateCheckSettings().isEnabled(); + this.autoUpdateChecksInterval = preferences.getAutoUpdateCheckSettings().getCheckInterval(); + this.kstColumns = preferences.getKeyStoreTableColumns(); + this.expiryWarnDays = preferences.getExpiryWarnDays(); + this.showHiddenFilesEnabled = preferences.isShowHiddenFilesEnabled(); + this.pkcs12EncryptionSetting = preferences.getPkcs12EncryptionSetting(); + this.serialNumberLengthInBytes = preferences.getSerialNumberLengthInBytes(); initComponents(); } @@ -746,84 +710,85 @@ private void initDefaultNameCard() { private void initDisplayColumnsCard() { bColumnsChanged = false; - bEnableEntryName = kstColumns.getEnableEntryName(); + boolean bEnableEntryName = kstColumns.getEnableEntryName(); jcbEnableEntryName = new JCheckBox(res.getString("DPreferences.jcbEnableEntryName.text"), bEnableEntryName); // fix for problem that without entry name a lot of things do not work jcbEnableEntryName.setSelected(true); jcbEnableEntryName.setEnabled(false); - bEnableAlgorithm = kstColumns.getEnableAlgorithm(); + boolean bEnableAlgorithm = kstColumns.getEnableAlgorithm(); jcbEnableAlgorithm = new JCheckBox(res.getString("DPreferences.jcbEnableAlgorithm.text"), bEnableAlgorithm); - bEnableKeySize = kstColumns.getEnableKeySize(); + boolean bEnableKeySize = kstColumns.getEnableKeySize(); jcbEnableKeySize = new JCheckBox(res.getString("DPreferences.jcbEnableKeySize.text"), bEnableKeySize); jcbEnableKeySize.setSelected(bEnableKeySize); - bEnableCurve = kstColumns.getEnableCurve(); + boolean bEnableCurve = kstColumns.getEnableCurve(); jcbEnableCurve = new JCheckBox(res.getString("DPreferences.jcbEnableCurve.text"), bEnableCurve); jcbEnableCurve.setSelected(bEnableCurve); - bEnableCertificateValidityStart = kstColumns.getEnableCertificateValidityStart(); + boolean bEnableCertificateValidityStart = kstColumns.getEnableCertificateValidityStart(); jcbEnableCertificateValidityStart = new JCheckBox(res.getString( "DPreferences.jcbEnableCertificateValidityStart.text"), bEnableCertificateValidityStart); jcbEnableCertificateValidityStart.setSelected(bEnableCertificateValidityStart); - bEnableCertificateExpiry = kstColumns.getEnableCertificateExpiry(); + boolean bEnableCertificateExpiry = kstColumns.getEnableCertificateExpiry(); jcbEnableCertificateExpiry = new JCheckBox(res.getString("DPreferences.jcbEnableCertificateExpiry.text"), bEnableCertificateExpiry); jcbEnableCertificateExpiry.setSelected(bEnableCertificateExpiry); - bEnableLastModified = kstColumns.getEnableLastModified(); + boolean bEnableLastModified = kstColumns.getEnableLastModified(); jcbEnableLastModified = new JCheckBox(res.getString("DPreferences.jcbEnableLastModified.text"), bEnableLastModified); jcbEnableLastModified.setSelected(bEnableLastModified); - bEnableSKI = kstColumns.getEnableSKI(); + boolean bEnableSKI = kstColumns.getEnableSKI(); jcbEnableSKI = new JCheckBox(res.getString("DPreferences.jcbEnableSKI.text"), bEnableSKI); jcbEnableSKI.setSelected(bEnableSKI); - bEnableAKI = kstColumns.getEnableAKI(); + boolean bEnableAKI = kstColumns.getEnableAKI(); jcbEnableAKI = new JCheckBox(res.getString("DPreferences.jcbEnableAKI.text"), bEnableAKI); jcbEnableAKI.setSelected(bEnableAKI); - bEnableIssuerDN = kstColumns.getEnableIssuerDN(); + boolean bEnableIssuerDN = kstColumns.getEnableIssuerDN(); jcbEnableIssuerDN = new JCheckBox(res.getString("DPreferences.jcbEnableIssuerDN.text"), bEnableIssuerDN); jcbEnableIssuerDN.setSelected(bEnableIssuerDN); - bEnableSubjectDN = kstColumns.getEnableSubjectDN(); + boolean bEnableSubjectDN = kstColumns.getEnableSubjectDN(); jcbEnableSubjectDN = new JCheckBox(res.getString("DPreferences.jcbEnableSubjectDN.text"), bEnableSubjectDN); jcbEnableSubjectDN.setSelected(bEnableSubjectDN); - bEnableIssuerCN = kstColumns.getEnableIssuerCN(); + boolean bEnableIssuerCN = kstColumns.getEnableIssuerCN(); jcbEnableIssuerCN = new JCheckBox(res.getString("DPreferences.jcbEnableIssuerCN.text"), bEnableIssuerCN); jcbEnableIssuerCN.setSelected(bEnableIssuerCN); - bEnableSubjectCN = kstColumns.getEnableSubjectCN(); + boolean bEnableSubjectCN = kstColumns.getEnableSubjectCN(); jcbEnableSubjectCN = new JCheckBox(res.getString("DPreferences.jcbEnableSubjectCN.text"), bEnableSubjectCN); jcbEnableSubjectCN.setSelected(bEnableSubjectCN); - bEnableIssuerO = kstColumns.getEnableIssuerO(); + boolean bEnableIssuerO = kstColumns.getEnableIssuerO(); jcbEnableIssuerO = new JCheckBox(res.getString("DPreferences.jcbEnableIssuerO.text"), bEnableIssuerO); jcbEnableIssuerO.setSelected(bEnableIssuerO); - bEnableSubjectO = kstColumns.getEnableSubjectO(); + boolean bEnableSubjectO = kstColumns.getEnableSubjectO(); jcbEnableSubjectO = new JCheckBox(res.getString("DPreferences.jcbEnableSubjectO.text"), bEnableSubjectO); jcbEnableSubjectO.setSelected(bEnableSubjectO); - bEnableSerialNumberHex = kstColumns.getbEnableSerialNumberHex(); + boolean bEnableSerialNumberHex = kstColumns.getEnableSerialNumberHex(); jcbEnableSerialNumberHex = new JCheckBox(res.getString("DPreferences.jcbEnableSerialNumberHex.text"), bEnableSerialNumberHex); jcbEnableSerialNumberHex.setSelected(bEnableSerialNumberHex); - bEnableSerialNumberDec = kstColumns.getbEnableSerialNumberDec(); + boolean bEnableSerialNumberDec = kstColumns.getEnableSerialNumberDec(); jcbEnableSerialNumberDec = new JCheckBox(res.getString("DPreferences.jcbEnableSerialNumberDec.text"), bEnableSerialNumberDec); jcbEnableSerialNumberDec.setSelected(bEnableSerialNumberDec); jlExpirationWarnDays = new JLabel(res.getString("DPreferences.jlExpiryWarning.text")); - jtfExpirationWarnDays = new JTextField(); - jtfExpirationWarnDays.setColumns(3); - jtfExpirationWarnDays.setText(Integer.toString(expiryWarnDays)); + jspExpirationWarnDays = new JSpinner(new SpinnerNumberModel(expiryWarnDays, 0, 90, 1)); + JSpinner.DefaultEditor editor = ( JSpinner.DefaultEditor ) jspExpirationWarnDays.getEditor(); + editor.getTextField().setEnabled(true); + editor.getTextField().setEditable(false); // layout jpDisplayColumns = new JPanel(); @@ -847,7 +812,7 @@ private void initDisplayColumnsCard() { jpDisplayColumns.add(jcbEnableSerialNumberHex, "left, wrap"); jpDisplayColumns.add(jcbEnableSerialNumberDec, "left, wrap para"); jpDisplayColumns.add(jlExpirationWarnDays, "left, spanx, split"); - jpDisplayColumns.add(jtfExpirationWarnDays, "wrap"); + jpDisplayColumns.add(jspExpirationWarnDays, "wrap"); } private void initLookAndFeelSelection() { @@ -1223,6 +1188,14 @@ public KeyStoreTableColumns getColumns() { return kstColumns; } + /** + * Get number of days before certificate expiration warnings in the main table are shown in advance + * @return Expiry warn + */ + public int getExpiryWarnDays() { + return expiryWarnDays; + } + /** * Get PKCS12 encryption settings * @return P12 encryption settings @@ -1250,34 +1223,28 @@ public boolean columnsChanged() { } private void storeColumns() { - int ist = kstColumns.getColumns(); - bEnableEntryName = jcbEnableEntryName.isSelected(); - bEnableAlgorithm = jcbEnableAlgorithm.isSelected(); - bEnableKeySize = jcbEnableKeySize.isSelected(); - bEnableCertificateValidityStart = jcbEnableCertificateValidityStart.isSelected(); - bEnableCertificateExpiry = jcbEnableCertificateExpiry.isSelected(); - bEnableLastModified = jcbEnableLastModified.isSelected(); - bEnableCurve = jcbEnableCurve.isSelected(); - bEnableSKI = jcbEnableSKI.isSelected(); - bEnableAKI = jcbEnableAKI.isSelected(); - bEnableIssuerDN = jcbEnableIssuerDN.isSelected(); - bEnableSubjectDN = jcbEnableSubjectDN.isSelected(); - bEnableIssuerCN = jcbEnableIssuerCN.isSelected(); - bEnableSubjectCN = jcbEnableSubjectCN.isSelected(); - bEnableIssuerO = jcbEnableIssuerO.isSelected(); - bEnableSubjectO = jcbEnableSubjectO.isSelected(); - bEnableSerialNumberHex = jcbEnableSerialNumberHex.isSelected(); - bEnableSerialNumberDec = jcbEnableSerialNumberDec.isSelected(); - try { - expiryWarnDays = Integer.parseInt(jtfExpirationWarnDays.getText()); - } catch (Exception e) { - expiryWarnDays = 0; - } - kstColumns.setColumns(bEnableEntryName, bEnableAlgorithm, bEnableKeySize, bEnableCertificateValidityStart, - bEnableCertificateExpiry, bEnableLastModified, bEnableSKI, bEnableAKI, bEnableIssuerDN, - bEnableSubjectDN, bEnableIssuerCN, bEnableSubjectCN, bEnableIssuerO, bEnableSubjectO, bEnableCurve, - bEnableSerialNumberHex, bEnableSerialNumberDec, expiryWarnDays); - bColumnsChanged = (kstColumns.getColumns() != ist); + var newKstColumns = new KeyStoreTableColumns(); + newKstColumns.setEnableEntryName(jcbEnableEntryName.isSelected()); + newKstColumns.setEnableAlgorithm(jcbEnableAlgorithm.isSelected()); + newKstColumns.setEnableKeySize(jcbEnableKeySize.isSelected()); + newKstColumns.setEnableCertificateValidityStart(jcbEnableCertificateValidityStart.isSelected()); + newKstColumns.setEnableCertificateExpiry(jcbEnableCertificateExpiry.isSelected()); + newKstColumns.setEnableLastModified(jcbEnableLastModified.isSelected()); + newKstColumns.setEnableCurve(jcbEnableCurve.isSelected()); + newKstColumns.setEnableSKI(jcbEnableSKI.isSelected()); + newKstColumns.setEnableAKI(jcbEnableAKI.isSelected()); + newKstColumns.setEnableIssuerDN(jcbEnableIssuerDN.isSelected()); + newKstColumns.setEnableSubjectDN(jcbEnableSubjectDN.isSelected()); + newKstColumns.setEnableIssuerCN(jcbEnableIssuerCN.isSelected()); + newKstColumns.setEnableSubjectCN(jcbEnableSubjectCN.isSelected()); + newKstColumns.setEnableIssuerO(jcbEnableIssuerO.isSelected()); + newKstColumns.setEnableSubjectO(jcbEnableSubjectO.isSelected()); + newKstColumns.setEnableSerialNumberHex(jcbEnableSerialNumberHex.isSelected()); + newKstColumns.setEnableSerialNumberDec(jcbEnableSerialNumberDec.isSelected()); + bColumnsChanged = !kstColumns.equals(newKstColumns); + kstColumns = newKstColumns; + + expiryWarnDays = ((Number) jspExpirationWarnDays.getValue()).intValue(); } /** @@ -1339,8 +1306,10 @@ private void closeDialog() { private void initLanguageSelection() { LanguageItem[] languageItems = new LanguageItem[] { - new LanguageItem("System", ApplicationSettings.SYSTEM_LANGUAGE), new LanguageItem("English", "en"), - new LanguageItem("German", "de"), new LanguageItem("French", "fr") }; + new LanguageItem("System", LanguageItem.SYSTEM_LANGUAGE), + new LanguageItem("English", "en"), + new LanguageItem("German", "de"), + new LanguageItem("French", "fr") }; for (LanguageItem languageItem : languageItems) { jcbLanguage.addItem(languageItem); @@ -1354,9 +1323,7 @@ private void initLanguageSelection() { * Quick UI testing */ public static void main(String[] args) throws Exception { - DPreferences dialog = new DPreferences(new javax.swing.JFrame(), true, new File(""), true, true, true, - new PasswordQualityConfig(true, true, 100), "", "en", true, 14, - new KeyStoreTableColumns(), true, Pkcs12EncryptionSetting.strong, 8); + DPreferences dialog = new DPreferences(new JFrame(), new KsePreferences()); DialogViewer.run(dialog); } } \ No newline at end of file diff --git a/kse/src/main/java/org/kse/gui/preferences/PreferencesManager.java b/kse/src/main/java/org/kse/gui/preferences/PreferencesManager.java new file mode 100644 index 000000000..31b4cfb7a --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/PreferencesManager.java @@ -0,0 +1,129 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.kse.gui.JEscFrame; +import org.kse.gui.error.DError; +import org.kse.gui.preferences.data.KsePreferences; +import org.kse.gui.preferences.json.KseJacksonJrExtension; +import org.kse.utilities.os.OperatingSystem; + +import com.fasterxml.jackson.jr.annotationsupport.JacksonAnnotationExtension; +import com.fasterxml.jackson.jr.ob.JSON; + +/** + * Load, provide access and store the application preferences. + *

+ * The base directory for the config files is selected depending on the operating system: + *

    + *
  1. On Windows %APPDATA% is used:
    c:\Users\\AppData\Roaming\kse\
  2. + *
  3. On Linux XDG_CONFIG_HOME or its default value is used:
    ~/.config/kse
  4. + *
  5. On MacOS "~/.config" is used for now, as other applications do this as well, but maybe switch later to + * ~/Library/Preferences or ~/Library/Application Support/
  6. TODO + *
+ *

+ * + */ +public class PreferencesManager { + + private static final String CONFIG_BASE_DIR = "kse"; + private static final String CONFIG_DOTTED_BASE_DIR = ".kse"; + private static final String CONFIG_FILE_NAME = "config.json"; + + private static KsePreferences ksePreferences; + + // configure jackson-jr + private static JSON json = JSON.builder() + .register(JacksonAnnotationExtension.std) + .register(new KseJacksonJrExtension()) + .build() + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .with(JSON.Feature.WRITE_NULL_PROPERTIES) + .with(JSON.Feature.FAIL_ON_DUPLICATE_MAP_KEYS); + + /** + * Returns a singleton object of the application preferences. + */ + public static KsePreferences getPreferences() { + if (ksePreferences == null) { + ksePreferences = load(); + } + return ksePreferences; + } + + private static KsePreferences load() { + try { + return json.beanFrom(KsePreferences.class, determineConfigFilePath()); + } catch (FileNotFoundException e) { + // ignore + return new KsePreferences(); + } catch (Exception e) { + DError.displayError(new JEscFrame(), e); + return new KsePreferences(); + } + } + + private static File determineConfigFilePath() { + if (OperatingSystem.isWindows()) { + return new File(getAppDataConfigDir(), CONFIG_FILE_NAME); + } else if (OperatingSystem.isLinux()) { + return new File(getXdgConfigDir(), CONFIG_FILE_NAME); + } else if (OperatingSystem.isMacOs()){ + return new File(getXdgConfigDir(), CONFIG_FILE_NAME); + } + return new File(System.getProperty("user.home"), ".kse" + File.separator + CONFIG_FILE_NAME); + } + + + private static String getAppDataConfigDir() { + String dir = System.getenv("APPDATA"); + if (dir == null || dir.trim().isEmpty()) { + dir = System.getProperty("user.home") + File.separator + CONFIG_DOTTED_BASE_DIR; + } else { + dir += File.separator + CONFIG_BASE_DIR; + } + return dir; + } + + private static String getXdgConfigDir() { + String dir = System.getenv().get("XDG_CONFIG_HOME"); + // XDG spec: "If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used." + if (dir == null || dir.trim().isEmpty()) { + dir = System.getProperty("user.home") + File.separator + ".config"; + } + dir += File.separator + CONFIG_BASE_DIR; + return dir; + } + + public static void persist() { + try { + File configFile = determineConfigFilePath(); + configFile.getParentFile().mkdirs(); + json.write(ksePreferences, configFile); + } catch (IOException e) { + DError.displayError(new JEscFrame(), e); + } + } +} diff --git a/kse/src/main/java/org/kse/gui/preferences/data/AutoUpdateCheckSettings.java b/kse/src/main/java/org/kse/gui/preferences/data/AutoUpdateCheckSettings.java new file mode 100644 index 000000000..71eafedbf --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/data/AutoUpdateCheckSettings.java @@ -0,0 +1,58 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.data; + +import java.time.LocalDate; + +/** + * Config bean for storing settings for automatic update check + */ +public class AutoUpdateCheckSettings { + + private boolean enabled = true; + private LocalDate lastCheck = LocalDate.now(); + private int checkInterval = 14; + + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public LocalDate getLastCheck() { + return lastCheck; + } + + public void setLastCheck(LocalDate lastCheck) { + this.lastCheck = lastCheck; + } + + public int getCheckInterval() { + return checkInterval; + } + + public void setCheckInterval(int checkInterval) { + this.checkInterval = checkInterval; + } +} diff --git a/kse/src/main/java/org/kse/gui/preferences/data/CaCertsSettings.java b/kse/src/main/java/org/kse/gui/preferences/data/CaCertsSettings.java new file mode 100644 index 000000000..2e3fdb2a5 --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/data/CaCertsSettings.java @@ -0,0 +1,76 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.data; + +import org.kse.AuthorityCertificates; + +/** + * Config bean for storing settings for cacerts (trust anchors) related options + */ +public class CaCertsSettings { + + private boolean useCaCertificates = false; + private String caCertificatesFile = AuthorityCertificates.getDefaultCaCertificatesLocation().toString(); + private boolean useWindowsTrustedRootCertificates = false; + private boolean importTrustedCertTrustCheckEnabled = false; + private boolean importCaReplyTrustCheckEnabled = false; + + + public boolean isUseCaCertificates() { + return useCaCertificates; + } + + public void setUseCaCertificates(boolean useCaCertificates) { + this.useCaCertificates = useCaCertificates; + } + + public String getCaCertificatesFile() { + return caCertificatesFile; + } + + public void setCaCertificatesFile(String caCertificatesFile) { + this.caCertificatesFile = caCertificatesFile; + } + + public boolean isUseWindowsTrustedRootCertificates() { + return useWindowsTrustedRootCertificates; + } + + public void setUseWindowsTrustedRootCertificates(boolean useWindowsTrustedRootCertificates) { + this.useWindowsTrustedRootCertificates = useWindowsTrustedRootCertificates; + } + + public boolean isImportTrustedCertTrustCheckEnabled() { + return importTrustedCertTrustCheckEnabled; + } + + public void setImportTrustedCertTrustCheckEnabled(boolean importTrustedCertTrustCheckEnabled) { + this.importTrustedCertTrustCheckEnabled = importTrustedCertTrustCheckEnabled; + } + + public boolean isImportCaReplyTrustCheckEnabled() { + return importCaReplyTrustCheckEnabled; + } + + public void setImportCaReplyTrustCheckEnabled(boolean importCaReplyTrustCheckEnabled) { + this.importCaReplyTrustCheckEnabled = importCaReplyTrustCheckEnabled; + } +} diff --git a/kse/src/main/java/org/kse/gui/preferences/data/KeyGenerationSettings.java b/kse/src/main/java/org/kse/gui/preferences/data/KeyGenerationSettings.java new file mode 100644 index 000000000..3330cc2bc --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/data/KeyGenerationSettings.java @@ -0,0 +1,96 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.data; + +import org.kse.crypto.keypair.KeyPairType; +import org.kse.crypto.secretkey.SecretKeyType; + +/** + * Config bean for storing settings for key generation + */ +public class KeyGenerationSettings { + + private KeyPairType keyPairType = KeyPairType.RSA; + private int keyPairSizeRSA = 2048; + private int keyPairSizeDSA = 1024; + private String ecCurveSet = ""; + private String ecCurveName = ""; + + private SecretKeyType secretKeyType = SecretKeyType.AES; + private int secretKeySize = 128; + + + public KeyPairType getKeyPairType() { + return keyPairType; + } + + public void setKeyPairType(KeyPairType keyPairType) { + this.keyPairType = keyPairType; + } + + public int getKeyPairSizeRSA() { + return keyPairSizeRSA; + } + + public void setKeyPairSizeRSA(int keyPairSizeRSA) { + this.keyPairSizeRSA = keyPairSizeRSA; + } + + public int getKeyPairSizeDSA() { + return keyPairSizeDSA; + } + + public void setKeyPairSizeDSA(int keyPairSizeDSA) { + this.keyPairSizeDSA = keyPairSizeDSA; + } + + public String getEcCurveSet() { + return ecCurveSet; + } + + public void setEcCurveSet(String ecCurveSet) { + this.ecCurveSet = ecCurveSet; + } + + public String getEcCurveName() { + return ecCurveName; + } + + public void setEcCurveName(String ecCurveName) { + this.ecCurveName = ecCurveName; + } + + public SecretKeyType getSecretKeyType() { + return secretKeyType; + } + + public void setSecretKeyType(SecretKeyType secretKeyType) { + this.secretKeyType = secretKeyType; + } + + public int getSecretKeySize() { + return secretKeySize; + } + + public void setSecretKeySize(int secretKeySize) { + this.secretKeySize = secretKeySize; + } +} diff --git a/kse/src/main/java/org/kse/gui/preferences/data/KsePreferences.java b/kse/src/main/java/org/kse/gui/preferences/data/KsePreferences.java new file mode 100644 index 000000000..0d1b57845 --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/data/KsePreferences.java @@ -0,0 +1,275 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.data; + +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JTabbedPane; + +import org.kse.crypto.digest.DigestType; +import org.kse.gui.KeyStoreTableColumns; +import org.kse.gui.KseFrame; +import org.kse.gui.password.PasswordQualityConfig; + +/** + * Bean for storing application preferences + */ +public class KsePreferences { + + private CaCertsSettings caCertsSettings = new CaCertsSettings(); + private KeyGenerationSettings keyGenerationDefaults = new KeyGenerationSettings(); + private DigestType certificateFingerprintAlgorithm = DigestType.SHA1; + private PasswordQualityConfig passwordQualityConfig = new PasswordQualityConfig(false, false, 60); + private ProxySettings proxySettings = new ProxySettings(); // TODO convert back from ProxySelector.getDefault()?!? + private Rectangle mainWindowSizeAndPosition = new Rectangle(0, 0, KseFrame.DEFAULT_WIDTH, KseFrame.DEFAULT_HEIGHT); + private boolean showToolBar = true; + private boolean showStatusBar = true; + private int tabLayout = JTabbedPane.WRAP_TAB_LAYOUT; + private List recentFiles = new ArrayList<>(); + private String currentDirectory = null; + private String lookAndFeelClass = null; + private boolean lookAndFeelDecorated = false; + private boolean showTipsOnStartUp = true; + private int nextTipIndex = 0; + private String defaultSubjectDN = ""; + private List examineSslHosts = List.of("www.google.com", "www.amazon.com"); + private List examineSslPorts = List.of("443"); + private AutoUpdateCheckSettings autoUpdateCheckSettings = new AutoUpdateCheckSettings(); + private List pkcs11Libraries = new ArrayList<>(); + private String language = LanguageItem.SYSTEM_LANGUAGE; + private KeyStoreTableColumns keyStoreTableColumns = new KeyStoreTableColumns(); + private int expiryWarnDays = 0; + private boolean showHiddenFilesEnabled = true; + private Pkcs12EncryptionSetting pkcs12EncryptionSetting = Pkcs12EncryptionSetting.strong; + private int serialNumberLengthInBytes = 20; + + // auto-generated getters/setters + + public DigestType getCertificateFingerprintAlgorithm() { + return certificateFingerprintAlgorithm; + } + + public void setCertificateFingerprintAlgorithm(DigestType certificateFingerprintAlgorithm) { + this.certificateFingerprintAlgorithm = certificateFingerprintAlgorithm; + } + + public PasswordQualityConfig getPasswordQualityConfig() { + return passwordQualityConfig; + } + + public void setPasswordQualityConfig(PasswordQualityConfig passwordQualityConfig) { + this.passwordQualityConfig = passwordQualityConfig; + } + + public Rectangle getMainWindowSizeAndPosition() { + return mainWindowSizeAndPosition; + } + + public void setMainWindowSizeAndPosition(Rectangle mainWindowSizeAndPosition) { + this.mainWindowSizeAndPosition = mainWindowSizeAndPosition; + } + + public boolean isShowToolBar() { + return showToolBar; + } + + public void setShowToolBar(boolean showToolBar) { + this.showToolBar = showToolBar; + } + + public boolean isShowStatusBar() { + return showStatusBar; + } + + public void setShowStatusBar(boolean showStatusBar) { + this.showStatusBar = showStatusBar; + } + + public int getTabLayout() { + return tabLayout; + } + + public void setTabLayout(int tabLayout) { + this.tabLayout = tabLayout; + } + + public List getRecentFiles() { + return recentFiles; + } + + public void setRecentFiles(List recentFiles) { + this.recentFiles = recentFiles; + } + + public String getCurrentDirectory() { + return currentDirectory; + } + + public void setCurrentDirectory(String currentDirectory) { + this.currentDirectory = currentDirectory; + } + + public String getLookAndFeelClass() { + return lookAndFeelClass; + } + + public void setLookAndFeelClass(String lookAndFeelClass) { + this.lookAndFeelClass = lookAndFeelClass; + } + + public boolean isLookAndFeelDecorated() { + return lookAndFeelDecorated; + } + + public void setLookAndFeelDecorated(boolean lookAndFeelDecorated) { + this.lookAndFeelDecorated = lookAndFeelDecorated; + } + + public boolean isShowTipsOnStartUp() { + return showTipsOnStartUp; + } + + public void setShowTipsOnStartUp(boolean showTipsOnStartUp) { + this.showTipsOnStartUp = showTipsOnStartUp; + } + + public int getNextTipIndex() { + return nextTipIndex; + } + + public void setNextTipIndex(int nextTipIndex) { + this.nextTipIndex = nextTipIndex; + } + + public String getDefaultSubjectDN() { + return defaultSubjectDN; + } + + public void setDefaultSubjectDN(String defaultSubjectDN) { + this.defaultSubjectDN = defaultSubjectDN; + } + + public List getExamineSslHosts() { + return examineSslHosts; + } + + public void setExamineSslHosts(List examineSslHosts) { + this.examineSslHosts = examineSslHosts; + } + + public List getExamineSslPorts() { + return examineSslPorts; + } + + public void setExamineSslPorts(List examineSslPorts) { + this.examineSslPorts = examineSslPorts; + } + + public List getPkcs11Libraries() { + return pkcs11Libraries; + } + + public void setPkcs11Libraries(List pkcs11Libraries) { + this.pkcs11Libraries = pkcs11Libraries; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public KeyStoreTableColumns getKeyStoreTableColumns() { + return keyStoreTableColumns; + } + + public void setKeyStoreTableColumns(KeyStoreTableColumns keyStoreTableColumns) { + this.keyStoreTableColumns = keyStoreTableColumns; + } + + public int getExpiryWarnDays() { + return expiryWarnDays; + } + + public void setExpiryWarnDays(int expiryWarnDays) { + this.expiryWarnDays = expiryWarnDays; + } + + public boolean isShowHiddenFilesEnabled() { + return showHiddenFilesEnabled; + } + + public void setShowHiddenFilesEnabled(boolean showHiddenFilesEnabled) { + this.showHiddenFilesEnabled = showHiddenFilesEnabled; + } + + public Pkcs12EncryptionSetting getPkcs12EncryptionSetting() { + return pkcs12EncryptionSetting; + } + + public void setPkcs12EncryptionSetting(Pkcs12EncryptionSetting pkcs12EncryptionSetting) { + this.pkcs12EncryptionSetting = pkcs12EncryptionSetting; + } + + public int getSerialNumberLengthInBytes() { + return serialNumberLengthInBytes; + } + + public void setSerialNumberLengthInBytes(int serialNumberLengthInBytes) { + this.serialNumberLengthInBytes = serialNumberLengthInBytes; + } + + public ProxySettings getProxySettings() { + return proxySettings; + } + + public void setProxySettings(ProxySettings proxySettings) { + this.proxySettings = proxySettings; + } + + public AutoUpdateCheckSettings getAutoUpdateCheckSettings() { + return autoUpdateCheckSettings; + } + + public void setAutoUpdateCheckSettings(AutoUpdateCheckSettings autoUpdateCheckSettings) { + this.autoUpdateCheckSettings = autoUpdateCheckSettings; + } + + public CaCertsSettings getCaCertsSettings() { + return caCertsSettings; + } + + public void setCaCertsSettings(CaCertsSettings caCertsSettings) { + this.caCertsSettings = caCertsSettings; + } + + public KeyGenerationSettings getKeyGenerationDefaults() { + return keyGenerationDefaults; + } + + public void setKeyGenerationDefaults(KeyGenerationSettings keyGenerationDefaults) { + this.keyGenerationDefaults = keyGenerationDefaults; + } +} diff --git a/kse/src/main/java/org/kse/gui/preferences/LanguageItem.java b/kse/src/main/java/org/kse/gui/preferences/data/LanguageItem.java similarity index 90% rename from kse/src/main/java/org/kse/gui/preferences/LanguageItem.java rename to kse/src/main/java/org/kse/gui/preferences/data/LanguageItem.java index bb102f37e..27ff902c1 100644 --- a/kse/src/main/java/org/kse/gui/preferences/LanguageItem.java +++ b/kse/src/main/java/org/kse/gui/preferences/data/LanguageItem.java @@ -18,12 +18,14 @@ * along with KeyStore Explorer. If not, see . */ -package org.kse.gui.preferences; +package org.kse.gui.preferences.data; /** * Language class for supporting language text. */ -class LanguageItem { +public class LanguageItem { + public static final String SYSTEM_LANGUAGE = "system"; + private String displayName; private String isoCode; diff --git a/kse/src/main/java/org/kse/gui/preferences/Pkcs12EncryptionSetting.java b/kse/src/main/java/org/kse/gui/preferences/data/Pkcs12EncryptionSetting.java similarity index 92% rename from kse/src/main/java/org/kse/gui/preferences/Pkcs12EncryptionSetting.java rename to kse/src/main/java/org/kse/gui/preferences/data/Pkcs12EncryptionSetting.java index 6e1cc2e82..5ac8b0fb6 100644 --- a/kse/src/main/java/org/kse/gui/preferences/Pkcs12EncryptionSetting.java +++ b/kse/src/main/java/org/kse/gui/preferences/data/Pkcs12EncryptionSetting.java @@ -18,10 +18,13 @@ * along with KeyStore Explorer. If not, see . */ -package org.kse.gui.preferences; +package org.kse.gui.preferences.data; import java.util.ResourceBundle; +/** + * Options for PKCS#12 encryption (currently only strong/legacy) + */ public enum Pkcs12EncryptionSetting { strong("Pkcs12EncryptionSetting.strong"), legacy("Pkcs12EncryptionSetting.legacy"); @@ -34,7 +37,7 @@ public enum Pkcs12EncryptionSetting { } /** - * Allows to pass a resource bundle (which unfortunately cannot be intialized in this enum) + * Allows to pass a resource bundle (which unfortunately cannot be initialized in this enum) * that is then used to translate the result of the {@code toString()} method. * @param resourceBundle An initialized resource bundle */ diff --git a/kse/src/main/java/org/kse/gui/preferences/data/ProxySettings.java b/kse/src/main/java/org/kse/gui/preferences/data/ProxySettings.java new file mode 100644 index 000000000..e6a65aaff --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/data/ProxySettings.java @@ -0,0 +1,105 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.data; + +import org.kse.utilities.net.ProxyConfigurationType; + +/** + * Config bean for storing settings for proxy access + */ +public class ProxySettings { + private ProxyConfigurationType activeConfigurationType = ProxyConfigurationType.SYSTEM; + + // PAC + private String pacUrl = ""; + + // manual + private String httpHost = null; + private int httpPort = 0; + private String httpsHost = null; + private int httpsPort = 0; + private String socksHost = null; + private int socksPort = 0; + + public String getPacUrl() { + return pacUrl; + } + + public void setPacUrl(String pacUrl) { + this.pacUrl = pacUrl; + } + + public String getHttpHost() { + return httpHost; + } + + public void setHttpHost(String httpHost) { + this.httpHost = httpHost; + } + + public int getHttpPort() { + return httpPort; + } + + public void setHttpPort(int httpPort) { + this.httpPort = httpPort; + } + + public String getHttpsHost() { + return httpsHost; + } + + public void setHttpsHost(String httpsHost) { + this.httpsHost = httpsHost; + } + + public int getHttpsPort() { + return httpsPort; + } + + public void setHttpsPort(int httpsPort) { + this.httpsPort = httpsPort; + } + + public String getSocksHost() { + return socksHost; + } + + public void setSocksHost(String socksHost) { + this.socksHost = socksHost; + } + + public int getSocksPort() { + return socksPort; + } + + public void setSocksPort(int socksPort) { + this.socksPort = socksPort; + } + + public ProxyConfigurationType getActiveConfigurationType() { + return activeConfigurationType; + } + + public void setActiveConfigurationType(ProxyConfigurationType activeConfigurationType) { + this.activeConfigurationType = activeConfigurationType; + } +} diff --git a/kse/src/main/java/PurgePreferences.java b/kse/src/main/java/org/kse/gui/preferences/json/KseJacksonJrExtension.java similarity index 62% rename from kse/src/main/java/PurgePreferences.java rename to kse/src/main/java/org/kse/gui/preferences/json/KseJacksonJrExtension.java index 7dd3cf363..383d7946f 100644 --- a/kse/src/main/java/PurgePreferences.java +++ b/kse/src/main/java/org/kse/gui/preferences/json/KseJacksonJrExtension.java @@ -18,23 +18,17 @@ * along with KeyStore Explorer. If not, see . */ -import org.kse.gui.preferences.ApplicationSettings; +package org.kse.gui.preferences.json; + +import com.fasterxml.jackson.jr.ob.JacksonJrExtension; +import com.fasterxml.jackson.jr.ob.api.ExtensionContext; /** - * Erase all KSE application preferences. + * Register custom converters for jackson-jr */ -public class PurgePreferences { - /** - * Erase all KSE application preferences. - * - * @param args Arguments - */ - public static void main(String[] args) { - try { - ApplicationSettings applicationSettings = ApplicationSettings.getInstance(); - applicationSettings.clear(); - } catch (Exception ex) { - ex.printStackTrace(); - } +public class KseJacksonJrExtension extends JacksonJrExtension { + @Override + protected void register(ExtensionContext ctxt) { + ctxt.appendProvider(new KseReaderWriterProvider()); } } diff --git a/kse/src/main/java/org/kse/gui/preferences/json/KseReaderWriterProvider.java b/kse/src/main/java/org/kse/gui/preferences/json/KseReaderWriterProvider.java new file mode 100644 index 000000000..f41a135ee --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/json/KseReaderWriterProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.json; + +import java.awt.Rectangle; +import java.time.LocalDate; + +import com.fasterxml.jackson.jr.ob.api.ReaderWriterProvider; +import com.fasterxml.jackson.jr.ob.api.ValueReader; +import com.fasterxml.jackson.jr.ob.api.ValueWriter; +import com.fasterxml.jackson.jr.ob.impl.JSONReader; +import com.fasterxml.jackson.jr.ob.impl.JSONWriter; + +/** + * Provide custom JSON converters for jackson-jr + */ +public class KseReaderWriterProvider extends ReaderWriterProvider { + + @Override + public ValueReader findValueReader(JSONReader readContext, Class type) { + if (type == Rectangle.class) return new RectangleConverter(); + if (type == LocalDate.class) return new LocalDateConverter(); + return null; + } + + @Override + public ValueWriter findValueWriter(JSONWriter writeContext, Class type) { + if (type == Rectangle.class) return new RectangleConverter(); + if (type == LocalDate.class) return new LocalDateConverter(); + return null; + } +} diff --git a/kse/src/main/java/org/kse/gui/preferences/json/LocalDateConverter.java b/kse/src/main/java/org/kse/gui/preferences/json/LocalDateConverter.java new file mode 100644 index 000000000..a490e1cd2 --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/json/LocalDateConverter.java @@ -0,0 +1,58 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.json; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.jr.ob.api.ValueReader; +import com.fasterxml.jackson.jr.ob.api.ValueWriter; +import com.fasterxml.jackson.jr.ob.impl.JSONReader; +import com.fasterxml.jackson.jr.ob.impl.JSONWriter; + +/** + * Custom JSON reader/writer because jackson-jr still has no support for Java 8 Date/Time API in 2023 + */ +public class LocalDateConverter extends ValueReader implements ValueWriter { + + protected LocalDateConverter() { + super(LocalDate.class); + } + + @Override + public void writeValue (JSONWriter context, JsonGenerator g, Object value) throws IOException { + context.writeValue(((LocalDate) value).format(DateTimeFormatter.ISO_LOCAL_DATE)); + } + + @Override + public Object read(JSONReader reader, JsonParser p) throws IOException { + return LocalDate.parse(p.getText(), DateTimeFormatter.ISO_LOCAL_DATE); + } + + @Override + public Class valueType () { + return LocalDate.class; + } + +} diff --git a/kse/src/main/java/org/kse/gui/preferences/json/RectangleConverter.java b/kse/src/main/java/org/kse/gui/preferences/json/RectangleConverter.java new file mode 100644 index 000000000..cdab57098 --- /dev/null +++ b/kse/src/main/java/org/kse/gui/preferences/json/RectangleConverter.java @@ -0,0 +1,65 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.gui.preferences.json; + +import java.awt.Rectangle; +import java.io.IOException; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.jr.ob.api.ValueReader; +import com.fasterxml.jackson.jr.ob.api.ValueWriter; +import com.fasterxml.jackson.jr.ob.impl.JSONReader; +import com.fasterxml.jackson.jr.ob.impl.JSONWriter; + +/** + * Custom JSON reader/writer because java.awt.Rectangle causes issues with jackson + */ +public class RectangleConverter extends ValueReader implements ValueWriter { + + protected RectangleConverter() { + super(Rectangle.class); + } + + @Override + public void writeValue(JSONWriter context, JsonGenerator g, Object value) throws IOException { + Rectangle rectangle = (Rectangle) value; + g.writeStartObject(); + g.writeNumberField("x", rectangle.x); + g.writeNumberField("y", rectangle.y); + g.writeNumberField("width", rectangle.width); + g.writeNumberField("height", rectangle.height); + g.writeEndObject(); + } + + @Override + public Object read(JSONReader reader, JsonParser p) throws IOException { + Map map = reader.readMap(); + return new Rectangle((Integer) map.get("x"), + (Integer) map.get("y"), + (Integer) map.get("width"), + (Integer) map.get("height")); + } + + @Override + public Class valueType() { return Rectangle.class; } +} diff --git a/kse/src/main/java/org/kse/utilities/StringUtils.java b/kse/src/main/java/org/kse/utilities/StringUtils.java index 8a7abf4f4..3cd9114fc 100644 --- a/kse/src/main/java/org/kse/utilities/StringUtils.java +++ b/kse/src/main/java/org/kse/utilities/StringUtils.java @@ -22,6 +22,8 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.LinkedList; +import java.util.List; public class StringUtils { @@ -62,32 +64,33 @@ public static boolean isBlank(String str) { } /** - * Add a new item to a semicolon separated list of strings. + * Add given string to list. The string is put at the first position of the new list. If the list already + * contains this value, it is moved to the first position instead. If maxSize is exceeded after adding the value, + * the last item in the list is removed. + *

+ * Note: This does not modify the input list (as it is probably immutable), but returns a new list instead. + *

* - * @param newItem The new item to be added. - * @param semicolonSepList Current semicolon separated list of strings. - * @param maxItems Maximum number of items to keep in list. - * @return New semicolon separated list of strings with new item at the first position. + * @param value The new item to be added. + * @param list Current list of strings. + * @param maxSize Maximum number of items to keep in list. + * @return New list of strings with new item at the first position. */ - public static String addToList(String newItem, String semicolonSepList, int maxItems) { + public static List addToList(String value, List list, int maxSize) { + LinkedList newList = new LinkedList<>(list); - // add new item at first position of the list - StringBuilder sb = new StringBuilder(newItem); - String[] items = semicolonSepList.split(";"); - for (int i = 0; i < items.length && i < maxItems; i++) { - - String port = items[i]; + if (newList.contains(value)) { + newList.remove(value); + newList.addFirst(value); + return newList; + } - // if saved list already contains new item, bring it to first position - if (port.equals(newItem)) { - continue; - } + newList.addFirst(value); - sb.append(";"); - sb.append(port); + if (newList.size() > maxSize) { + newList.removeLast(); } - - return sb.toString(); + return newList; } /** diff --git a/kse/src/main/java/org/kse/utilities/net/ProxySettingsUpdater.java b/kse/src/main/java/org/kse/utilities/net/ProxySettingsUpdater.java new file mode 100644 index 000000000..5df4cdf75 --- /dev/null +++ b/kse/src/main/java/org/kse/utilities/net/ProxySettingsUpdater.java @@ -0,0 +1,150 @@ +/* + * Copyright 2004 - 2013 Wayne Grant + * 2013 - 2023 Kai Kramer + * + * This file is part of KeyStore Explorer. + * + * KeyStore Explorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * KeyStore Explorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeyStore Explorer. If not, see . + */ + +package org.kse.utilities.net; + +import java.net.ProxySelector; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.swing.JFrame; + +import org.kse.gui.error.DError; +import org.kse.gui.preferences.data.ProxySettings; + +/** + * This class translates between the ProxySettings in the KsePreferences and the currently active proxy settings. + */ +public class ProxySettingsUpdater { + + /** + * Updates system proxy settings + * @param proxySettings Proxy settings from config + */ + public static void updateSystem(ProxySettings proxySettings) { + + // default should be system settings because of "java.net.useSystemProxies=true", save it for later usage + SystemProxySelector.setSystemProxySelector(ProxySelector.getDefault()); + + switch (proxySettings.getActiveConfigurationType()) { + case NONE: + ProxySelector.setDefault(new NoProxySelector()); + break; + case PAC: + // Use PAC URL for proxy configuration + String pacUrl = proxySettings.getPacUrl(); + if (pacUrl != null) { + try { + ProxySelector.setDefault(new PacProxySelector(new URI(pacUrl))); + } catch (URISyntaxException e) { + DError.displayError(new JFrame(), e); + ProxySelector.setDefault(new NoProxySelector()); + } + } else { + ProxySelector.setDefault(new NoProxySelector()); + } + break; + case MANUAL: + // Use manual settings for HTTP, HTTPS and SOCKS + ProxyAddress httpProxyAddress = null; + ProxyAddress httpsProxyAddress = null; + ProxyAddress socksProxyAddress = null; + + String httpHost = proxySettings.getHttpHost(); + int httpPort = proxySettings.getHttpPort(); + + if (httpHost != null && httpPort > 0) { + httpProxyAddress = new ProxyAddress(httpHost, httpPort); + } + + String httpsHost = proxySettings.getHttpsHost(); + int httpsPort = proxySettings.getHttpsPort(); + + if (httpsHost != null && httpsPort > 0) { + httpsProxyAddress = new ProxyAddress(httpsHost, httpsPort); + } + + String socksHost = proxySettings.getSocksHost(); + int socksPort = proxySettings.getSocksPort(); + + if (socksHost != null && socksPort > 0) { + socksProxyAddress = new ProxyAddress(socksHost, socksPort); + } + + if (httpProxyAddress != null || httpsProxyAddress != null) { + ProxySelector.setDefault( + new ManualProxySelector(httpProxyAddress, httpsProxyAddress, null, socksProxyAddress)); + } else { + // no manual settings - use no proxy to connect to the Internet + ProxySelector.setDefault(new NoProxySelector()); + } + break; + case SYSTEM: + default: + ProxySelector.setDefault(new SystemProxySelector()); + break; + } + } + + /** + * Updates settings from active system + * @param proxySettings Proxy settings to be updated + */ + public static ProxySettings updateSettings(ProxySettings proxySettings) { + + // Get current proxy settings + ProxySelector proxySelector = ProxySelector.getDefault(); + + if (proxySelector instanceof NoProxySelector) { + proxySettings.setActiveConfigurationType(ProxyConfigurationType.NONE); + } else if (proxySelector instanceof SystemProxySelector) { + proxySettings.setActiveConfigurationType(ProxyConfigurationType.SYSTEM); + } else if (proxySelector instanceof PacProxySelector) { + PacProxySelector pacProxySelector = (PacProxySelector) proxySelector; + + proxySettings.setPacUrl(pacProxySelector.getPacURI().toString()); + proxySettings.setActiveConfigurationType(ProxyConfigurationType.PAC); + } else if (proxySelector instanceof ManualProxySelector) { + ManualProxySelector manualProxySelector = (ManualProxySelector) proxySelector; + + ProxyAddress httpProxyAddress = manualProxySelector.getHttpProxyAddress(); + if (httpProxyAddress != null) { + proxySettings.setHttpHost(httpProxyAddress.getHost()); + proxySettings.setHttpPort(httpProxyAddress.getPort()); + } + + ProxyAddress httpsProxyAddress = manualProxySelector.getHttpsProxyAddress(); + if (httpsProxyAddress != null) { + proxySettings.setHttpsHost(httpsProxyAddress.getHost()); + proxySettings.setHttpsPort(httpsProxyAddress.getPort()); + } + + ProxyAddress socksProxyAddress = manualProxySelector.getSocksProxyAddress(); + if (socksProxyAddress != null) { + proxySettings.setSocksHost(socksProxyAddress.getHost()); + proxySettings.setSocksPort(socksProxyAddress.getPort()); + } + + proxySettings.setActiveConfigurationType(ProxyConfigurationType.MANUAL); + } + + return proxySettings; + } +}