Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option to resolve root ca and simplify Examine SSL option #466

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions kse/build.gradle
Expand Up @@ -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('io.github.hakky54:sslcontext-kickstart:8.2.0')
implementation('org.slf4j:slf4j-simple:2.0.9')

testImplementation('org.assertj:assertj-core:3.23.1')
testImplementation('org.junit.jupiter:junit-jupiter-api:5.9.0')
Expand Down
14 changes: 6 additions & 8 deletions kse/src/main/java/org/kse/gui/actions/ExamineSslAction.java
Expand Up @@ -21,7 +21,9 @@

import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.KeyStroke;
Expand All @@ -31,8 +33,6 @@
import org.kse.gui.dialogs.DExaminingSsl;
import org.kse.gui.dialogs.DViewCertificate;
import org.kse.gui.error.DError;
import org.kse.utilities.history.KeyStoreHistory;
import org.kse.utilities.ssl.SslConnectionInfos;

/**
* Action to examine an SSL connection's certificates.
Expand Down Expand Up @@ -70,27 +70,25 @@ protected void doAction() {

String sslHost = dExamineSsl.getSslHost();
int sslPort = dExamineSsl.getSslPort();
boolean useClientAuth = dExamineSsl.useClientAuth();
KeyStoreHistory ksh = dExamineSsl.getKeyStore();

if (dExamineSsl.wasCancelled()) {
return;
}

DExaminingSsl dExaminingSsl = new DExaminingSsl(frame, sslHost, sslPort, useClientAuth, ksh);
DExaminingSsl dExaminingSsl = new DExaminingSsl(frame, sslHost, sslPort);
dExaminingSsl.setLocationRelativeTo(frame);
dExaminingSsl.startExamination();
dExaminingSsl.setVisible(true);

SslConnectionInfos sslInfos = dExaminingSsl.getSSLConnectionInfos();
List<X509Certificate> certificates = dExaminingSsl.getServerCertificates();

if (sslInfos == null || sslInfos.getServerCertificates() == null) {
if (certificates.isEmpty()) {
return;
}

DViewCertificate dViewCertificate = new DViewCertificate(frame, MessageFormat.format(
res.getString("ExamineSslAction.CertDetailsSsl.Title"), sslHost, Integer.toString(sslPort)),
sslInfos.getServerCertificates(), kseFrame,
certificates.toArray(new X509Certificate[0]), kseFrame,
DViewCertificate.IMPORT_EXPORT);
dViewCertificate.setLocationRelativeTo(frame);
dViewCertificate.setVisible(true);
Expand Down
73 changes: 0 additions & 73 deletions kse/src/main/java/org/kse/gui/dialogs/DExamineSsl.java
Expand Up @@ -30,25 +30,20 @@
import javax.swing.AbstractAction;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
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.utilities.DialogViewer;
import org.kse.utilities.history.KeyStoreHistory;

Expand All @@ -68,9 +63,6 @@ public class DExamineSsl extends JEscDialog {
private JComboBox<String> jcbSslHost;
private JLabel jlSslPort;
private JComboBox<String> jcbSslPort;
private JCheckBox jcbClientAuth;
private JComboBox<KeyStoreHistory> jcbKeyStore;
private JButton jbLoadKeystore;
private JPanel jpButtons;
private JButton jbOK;
private JButton jbCancel;
Expand Down Expand Up @@ -108,15 +100,6 @@ private void initComponents() {
jcbSslPort.setToolTipText(res.getString("DExamineSsl.jtfSslPort.tooltip"));
jcbSslPort.setModel(new DefaultComboBoxModel<>(getSslPorts()));

jcbClientAuth = new JCheckBox(res.getString("DExamineSsl.jlEnableClientAuth.text"));

jcbKeyStore = new JComboBox<>(getKeystoreNames());
jcbKeyStore.setToolTipText(res.getString("DExamineSsl.jcbKeyStore.tooltip"));

jbLoadKeystore = new JButton();
jbLoadKeystore.setIcon(new ImageIcon(getClass().getResource("images/open.png")));
jbLoadKeystore.setToolTipText(res.getString("DExamineSsl.jbLoadKeystore.tooltip"));

jbOK = new JButton(res.getString("DExamineSsl.jbOK.text"));

jbCancel = new JButton(res.getString("DExamineSsl.jbCancel.text"));
Expand All @@ -132,20 +115,8 @@ private void initComponents() {
pane.add(jcbSslHost, "sgx, growx, wrap");
pane.add(jlSslPort, "skip");
pane.add(jcbSslPort, "sgx, growx, wrap para");
MiGUtil.addSeparator(pane, res.getString("DExamineSsl.jlClientAuth.text"));
pane.add(jcbClientAuth, "left, spanx, wrap");
pane.add(new JLabel(res.getString("DExamineSsl.jlKeyStore.text")), "skip");
pane.add(jcbKeyStore, "sgx, growx");
pane.add(jbLoadKeystore, "growx, wrap para");
pane.add(new JSeparator(), "spanx, growx, wrap");
pane.add(jpButtons, "right, spanx");

jcbClientAuth.addActionListener(evt -> updateClientAuthComponents());
jbLoadKeystore.addActionListener(evt -> {
OpenAction openAction = new OpenAction(kseFrame);
openAction.actionPerformed(evt);
updateClientAuthComponents();
});
jbOK.addActionListener(evt -> okPressed());
jbCancel.addActionListener(evt -> cancelPressed());

Expand All @@ -165,8 +136,6 @@ public void windowClosing(WindowEvent evt) {
}
});

updateClientAuthComponents();

getRootPane().setDefaultButton(jbOK);

setResizable(false);
Expand Down Expand Up @@ -197,24 +166,6 @@ public int getSslPort() {
return sslPort;
}

/**
* User wants to use SSL client authentication?
*
* @return True if user wants to use SSL client authentication
*/
public boolean useClientAuth() {
return jcbClientAuth.isSelected();
}

/**
* Get selected key store
*
* @return KeyStore (wrapped in a history object)
*/
public KeyStoreHistory getKeyStore() {
return (KeyStoreHistory) jcbKeyStore.getSelectedItem();
}

/**
* Was the dialog cancelled?
*
Expand All @@ -234,13 +185,6 @@ private String[] getSslPorts() {
return sslPorts.split(";");
}

private void updateClientAuthComponents() {
jcbKeyStore.setEnabled(jcbClientAuth.isSelected());
jbLoadKeystore.setEnabled(jcbClientAuth.isSelected());

jcbKeyStore.setModel(getKeystoreNames());
}

private void okPressed() {
String sslHost = ((String) jcbSslHost.getSelectedItem()).trim();

Expand Down Expand Up @@ -277,23 +221,6 @@ private void okPressed() {
this.sslHost = sslHost;
this.sslPort = sslPort;

// check selected key store
if (useClientAuth()) {
KeyStoreHistory ksh = (KeyStoreHistory) jcbKeyStore.getSelectedItem();
if (ksh == null) {
JOptionPane.showMessageDialog(this, res.getString("DExamineSsl.NoKeyStoreSelected.message"), getTitle(),
JOptionPane.WARNING_MESSAGE);
return;
}

Password keyStorePassword = ksh.getCurrentState().getPassword();
if (keyStorePassword == null && ksh.getCurrentState().getType().hasEntryPasswords()) {
JOptionPane.showMessageDialog(this, res.getString("DExamineSsl.NoPasswordSetForKeyStore.message"),
getTitle(), JOptionPane.WARNING_MESSAGE);
return;
}
}

// save host/port in preferences
applicationSettings.addSslHost(sslHost);
applicationSettings.addSslPort(sslPortStr);
Expand Down
39 changes: 10 additions & 29 deletions kse/src/main/java/org/kse/gui/dialogs/DExaminingSsl.java
Expand Up @@ -26,8 +26,10 @@
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.security.KeyStore;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.util.List;
import java.util.ResourceBundle;

import javax.swing.AbstractAction;
Expand All @@ -43,14 +45,11 @@
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import org.kse.crypto.Password;
import nl.altindag.ssl.util.CertificateUtils;
import org.kse.gui.JEscDialog;
import org.kse.gui.PlatformUtil;
import org.kse.gui.error.DProblem;
import org.kse.gui.error.Problem;
import org.kse.utilities.history.KeyStoreHistory;
import org.kse.utilities.ssl.SslConnectionInfos;
import org.kse.utilities.ssl.SslUtils;

/**
* Examines an SSL connection's certificates - a process which the user may
Expand All @@ -72,9 +71,7 @@ public class DExaminingSsl extends JEscDialog {

private String sslHost;
private int sslPort;
private KeyStore keyStore;
private char[] password;
private SslConnectionInfos sslInfos;
private List<X509Certificate> serverCertificates;
private Thread examiner;

/**
Expand All @@ -83,24 +80,13 @@ public class DExaminingSsl extends JEscDialog {
* @param parent The parent frame
* @param sslHost SSL connection's host name
* @param sslPort SSL connection's port number
* @param useClientAuth Try to connect with client certificate
* @param ksh KeyStore with client certificate
*/
public DExaminingSsl(JFrame parent, String sslHost, int sslPort, boolean useClientAuth, KeyStoreHistory ksh) {
public DExaminingSsl(JFrame parent, String sslHost, int sslPort) {
super(parent, Dialog.ModalityType.DOCUMENT_MODAL);

this.sslHost = sslHost;
this.sslPort = sslPort;

if (useClientAuth) {
this.keyStore = ksh.getCurrentState().getKeyStore();

// some keystore types like MSCAPI and PKCS#11 have no password stored in their state
Password pwd = ksh.getCurrentState().getPassword();
if (pwd != null) {
this.password = pwd.toCharArray();
}
}
initComponents();
}

Expand Down Expand Up @@ -166,14 +152,8 @@ public void startExamination() {
examiner.start();
}

/**
* Get the SSL connection's certificates and some details like protocol version or cipher suite.
*
* @return The SSL connection's details or null if the user cancelled
* the dialog or an error occurred
*/
public SslConnectionInfos getSSLConnectionInfos() {
return sslInfos;
public List<X509Certificate> getServerCertificates() {
return serverCertificates;
}

private void cancelPressed() {
Expand All @@ -192,7 +172,8 @@ private class ExamineSsl implements Runnable {
@Override
public void run() {
try {
sslInfos = SslUtils.readSSLConnectionInfos(sslHost, sslPort, keyStore, password);
URL url = new URL(MessageFormat.format("https://{0}:{1}/", sslHost, "" + sslPort));
serverCertificates = CertificateUtils.getCertificatesFromExternalSource(url.toString());

SwingUtilities.invokeLater(() -> {
if (DExaminingSsl.this.isShowing()) {
Expand Down