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

SPARK-1926, SPARK-1927, SPARK-1928, SPARK-1929, SPARK-1938 and SPARK-1937 #344

Merged
merged 8 commits into from
Jun 7, 2017
1 change: 1 addition & 0 deletions core/src/main/java/org/jivesoftware/resource/Default.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public class Default {
public static final String SSO_DISABLED = "SSO_DISABLED";
public static final String PROXY_DISABLED = "PROXY_DISABLED";
public static final String PKI_DISABLED = "PKI_DISABLED";
public static final String CERTIFICATES_MANAGER_DISABLED = "CERTIFICATES_MANAGER_DISABLED";
public static final String HELP_USER_GUIDE = "HELP_USER_GUIDE";
public static final String BROADCAST_IN_CHATWINDOW = "BROADCAST_IN_CHATWINDOW";
public static final String MENUBAR_TEXT = "MENUBAR_TEXT";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.jivesoftware.spark.ui.login;

import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.WEST;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import org.jivesoftware.resource.Res;
import org.jivesoftware.spark.util.ResourceUtils;
import org.jivesoftware.sparkimpl.certificates.CertificateController;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;

/**
* This class serve as visual in implementation of manageable list of
* certificates.
*
* @author Paweł Ścibiorski
*
*/
public class CertificatesManagerSettingsPanel extends JPanel implements ActionListener {

private final static Insets DEFAULT_INSETS = new Insets(5, 5, 5, 5);
private final LocalPreferences localPreferences;
private JDialog optionsDialog;
private CertificateController certControll;
private JTable certTable = new JTable();
private JCheckBox acceptAll = new JCheckBox();
private JCheckBox acceptExpired = new JCheckBox();
private JCheckBox acceptRevoked = new JCheckBox();
private JCheckBox acceptSelfSigned = new JCheckBox();
private JCheckBox checkCRL = new JCheckBox();
private JCheckBox checkOCSP = new JCheckBox();
private JScrollPane scrollPane;

public CertificatesManagerSettingsPanel(LocalPreferences localPreferences, JDialog optionsDialog) {

this.localPreferences = localPreferences;
this.optionsDialog = optionsDialog;
certControll = new CertificateController(localPreferences);
setLayout(new GridBagLayout());

certTable.setModel(certControll.getTableModel());
scrollPane = new JScrollPane(certTable);
certTable.setFillsViewportHeight(true);

ResourceUtils.resButton(acceptAll, Res.getString("checkbox.accept.all"));
ResourceUtils.resButton(acceptExpired, Res.getString("checkbox.accept.expired"));
ResourceUtils.resButton(acceptRevoked, Res.getString("checkbox.accept.invalid"));
ResourceUtils.resButton(acceptSelfSigned, Res.getString("checkbox.accept.self.signed"));
ResourceUtils.resButton(checkCRL, Res.getString("checkbox.check.crl"));
ResourceUtils.resButton(checkOCSP, Res.getString("checkbox.check.ocsp"));

acceptAll.addActionListener(this);

add(scrollPane, new GridBagConstraints(0, 0, 6, 1, 0.0, 1.0, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
add(acceptAll, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.5, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
add(acceptSelfSigned, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.5, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
add(acceptExpired, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.5, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
add(acceptRevoked, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.5, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
add(checkCRL, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.5, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
add(checkOCSP, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.5, WEST, HORIZONTAL, DEFAULT_INSETS, 0, 0));
}

@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == acceptAll && acceptAll.isSelected()) {
acceptSelfSigned.setSelected(true);
acceptExpired.setSelected(true);
acceptRevoked.setSelected(true);

acceptSelfSigned.setEnabled(false);
acceptExpired.setEnabled(false);
acceptRevoked.setEnabled(false);
} else if (e.getSource() == acceptAll && !acceptAll.isSelected()) {
acceptSelfSigned.setEnabled(true);
acceptExpired.setEnabled(true);
acceptRevoked.setEnabled(true);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class LoginSettingDialog implements PropertyChangeListener
private ProxyLoginSettingsPanel proxyPanel;
private PkiLoginSettingsPanel pkiPanel;
private SsoLoginSettingsPanel ssoPanel;
private CertificatesManagerSettingsPanel certManager;

/**
* Empty Constructor.
Expand All @@ -53,6 +54,7 @@ public LoginSettingDialog()
proxyPanel = new ProxyLoginSettingsPanel( localPreferences, optionsDialog );
ssoPanel = new SsoLoginSettingsPanel( localPreferences, optionsDialog );
pkiPanel = new PkiLoginSettingsPanel( localPreferences, optionsDialog );
certManager = new CertificatesManagerSettingsPanel(localPreferences, optionsDialog);
}

/**
Expand Down Expand Up @@ -82,7 +84,10 @@ public boolean invoke( JFrame owner )
{
tabbedPane.addTab( Res.getString( "tab.pki" ), pkiPanel );
}

if ( !Default.getBoolean(Default.CERTIFICATES_MANAGER_DISABLED))
{
tabbedPane.addTab( Res.getString( "tab.certificates" ), certManager );
}
// Construct main panel w/ layout.
final JPanel mainPanel = new JPanel();
mainPanel.setLayout( new BorderLayout() );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.jivesoftware.sparkimpl.certificates;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.table.DefaultTableModel;

import org.jivesoftware.resource.Res;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;

/**
* This class serve to extract certificates, storage them during runtime and
* format them and support management of them.
*
* @author Paweł Ścibiorski
*
*/

public class CertificateController {
List<CertificateModel> certificates;
DefaultTableModel tableModel;
Object[] certEntry;
LocalPreferences localPreferences;
private static final String[] COLUMN_NAMES = { Res.getString("table.column.certificate.certificate"),
Res.getString("table.column.certificate.subject"), Res.getString("table.column.certificate.valid"),
Res.getString("table.column.certificate.exempted") };
private static final int NUMBER_OF_COLUMNS = COLUMN_NAMES.length;
KeyStore trustStore;

public CertificateController(LocalPreferences localPreferences) {

this.localPreferences = localPreferences;
certificates = new ArrayList<>();
tableModel = new DefaultTableModel() {
// return adequate classes for columns so last column is Boolean
// displayed as checkbox
public Class<?> getColumnClass(int column) {
switch (column) {

case 0:
return String.class;
case 1:
return String.class;
case 2:
return String.class;
case 3:
return Boolean.class;
default:
return String.class;

}
}
};

tableModel.setColumnIdentifiers(COLUMN_NAMES);
certEntry = new Object[NUMBER_OF_COLUMNS];
// some certificates to fill table until creating extraction of
// certificates
try {
FileInputStream input = new FileInputStream(localPreferences.getTrustStorePath());
trustStore = KeyStore.getInstance(localPreferences.getPKIStore().toString());
trustStore.load(input, localPreferences.getTrustStorePassword().toCharArray());

Enumeration store = trustStore.aliases();
while (store.hasMoreElements()) {
String alias = (String) store.nextElement();
X509Certificate certificate = (X509Certificate) trustStore.getCertificate(alias);
certificates.add(new CertificateModel(certificate));
}

// put certificate from arrayList into rows with chosen columns
for (CertificateModel cert : certificates) {
certEntry[0] = cert.getIssuer();
certEntry[1] = cert.getSubject();
certEntry[2] = cert.isValid();
certEntry[3] = cert.isExempted();
tableModel.addRow(certEntry);
}
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
Log.warning("Cannot acces Truststore, it might be not set up", e);
}
}

public DefaultTableModel getTableModel() {
return tableModel;
}

public void setTableModel(DefaultTableModel tableModel) {
this.tableModel = tableModel;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.jivesoftware.sparkimpl.certificates;

import java.security.cert.X509Certificate;
import java.util.List;

/**
* Model that keep certificate fields as String values.
*/
public class CertificateModel {

private int version;
private String serialNumber;
private String signatureValue;
private String signatureAlgorithm;
private String issuer;
private String subject;
private String notBefore;
private String notAfter;
private String publicKey;
private String publicKeyAlgorithm;
private String issuerUniqueID;

private boolean valid;
private boolean exempted;
// List<String> extensionList;

/**
* Creates certificate model.
*
* @param version
* @param serialNumber
* @param signatureValue
* @param signatureAlgorithm
* @param issuer
* @param issuerUniqueID
* @param subject
* @param notBefore
* @param notAfter
* @param publickKeyInfo
*/
public CertificateModel(int version, String serialNumber, String signatureValue, String signatureAlgorithm,
String issuer, String subject, String notBefore, String notAfter, String publicKey,
String publicKeyAlgorithm, String issuerUniqueID, boolean valid, Boolean exempted) {
this.version = version;
this.serialNumber = serialNumber;
this.signatureValue = signatureValue;
this.signatureAlgorithm = signatureAlgorithm;
this.issuer = issuer;
this.subject = subject;
this.notBefore = notBefore;
this.notAfter = notAfter;
this.publicKey = publicKey;
this.publicKeyAlgorithm = publicKeyAlgorithm;
this.issuerUniqueID = issuerUniqueID;

this.valid = valid;
this.exempted = exempted;
// this.extensionList = extensionList;
}

public CertificateModel(X509Certificate certificate) {
this.version = certificate.getVersion();
this.serialNumber = certificate.getSerialNumber().toString();
this.signatureValue = certificate.getSignature().toString();
this.signatureAlgorithm = certificate.getSigAlgName();
this.issuer = certificate.getIssuerX500Principal().toString();
this.subject = certificate.getSubjectX500Principal().getName().toString();
this.notBefore = certificate.getNotBefore().toString();
this.notAfter = certificate.getNotAfter().toString();
this.publicKey = certificate.getPublicKey().toString();
this.publicKeyAlgorithm = certificate.getPublicKey().getAlgorithm().toString();
// this.issuerUniqueID = certificate.getIssuerUniqueID().toString();

this.valid = valid;
this.exempted = exempted;
}

public int getVersion() {
return version;
}

public String getSerialNumber() {
return serialNumber;
}

public String getSignatureValue() {
return signatureValue;
}

public String getSignatureAlgorithm() {
return signatureAlgorithm;
}

public String getIssuer() {
return issuer;
}

public String getSubject() {
return subject;
}

public String getNotBefore() {
return notBefore;
}

public String getNotAfter() {
return notAfter;
}

public String getPublicKey() {
return publicKey;
}

public String getPublicKeyAlgorithm() {
return publicKeyAlgorithm;
}

public String getIssuerUniqueID() {
return issuerUniqueID;
}

public boolean isValid() {
return valid;
}

public boolean isExempted() {
return exempted;
}

}
2 changes: 2 additions & 0 deletions core/src/main/resources/default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ SSO_DISABLED = false
PKI_DISABLED = false
#Removes Proxy Tab
PROXY_DISABLED = false
#Removes Certificates Tab
CERTIFICATES_MANAGER_DISABLED = false


# Show Password Reset Button on LoginDialog.
Expand Down
Loading