Skip to content

Commit

Permalink
Add export certificate functionality
Browse files Browse the repository at this point in the history
Added the ability to export certificates from the JKS store. Updated the plugin.xml to include the export action and implemented relevant methods in JKSView and CertificateHelper to handle the export process.
  • Loading branch information
cortiz committed Sep 13, 2024
1 parent 5ab1691 commit d11a6a1
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 7 deletions.
21 changes: 16 additions & 5 deletions src/main/java/com/jmpeax/ssltoolbox/jks/JKSView.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.jmpeax.ssltoolbox.jks;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;

Expand All @@ -10,7 +9,6 @@
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBPasswordField;
import com.intellij.util.ui.JBUI;
import com.jmpeax.ssltoolbox.jks.actions.ImportCert;
import com.jmpeax.ssltoolbox.pem.PemView;
import com.jmpeax.ssltoolbox.svc.CertificateHelper;
import org.jetbrains.annotations.NotNull;
Expand All @@ -28,6 +26,7 @@
import java.util.Set;

public class JKSView extends JPanel {

private JBList<String> list;
private PemView pemView;
private final VirtualFile file;
Expand Down Expand Up @@ -141,7 +140,7 @@ private JPanel createUnlockButton() {
try {
var certificateHelper = ApplicationManager.getApplication().getService(CertificateHelper.class);
this.certs = certificateHelper.getKeyStoreCerts(file.getInputStream(), password);
updateView(certs);
addCertificate(certs);
panel.removeAll();
panel.add(buildToolBar());
revalidate();
Expand Down Expand Up @@ -174,7 +173,7 @@ private JPanel buildToolBar() {

}

private void updateView(Map<String, X509Certificate> certs) {
private void addCertificate(Map<String, X509Certificate> certs) {
certs.keySet().forEach(listModel::addElement);
list = new JBList<>(listModel);
list.setCellRenderer(new IconListRenderer());
Expand All @@ -189,7 +188,6 @@ private void updateView(Map<String, X509Certificate> certs) {
});
listPanel.removeAll();
listPanel.add(new JScrollPane(list), BorderLayout.CENTER);

}

public @Nullable JComponent getUnlockText() {
Expand All @@ -204,4 +202,17 @@ public Component getListCellRendererComponent(JList<?> list, Object value, int i
return label;
}
}

public void addCertificate(String alias, X509Certificate certificate) {
listModel.addElement(alias);
certs.put(alias, certificate);
}

public String getSelectedCertificate() {
return list.getSelectedValue();
}
public void removeCertificate(String alias) {
listModel.remove(listModel.indexOf(alias));
certs.remove(alias);
}
}
58 changes: 58 additions & 0 deletions src/main/java/com/jmpeax/ssltoolbox/jks/actions/ExportCert.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.jmpeax.ssltoolbox.jks.actions;


import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.jmpeax.ssltoolbox.jks.JKSView;
import com.jmpeax.ssltoolbox.svc.CertificateHelper;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.Objects;

public class ExportCert extends AnAction {


@Override
public void actionPerformed(@NotNull AnActionEvent e) {

var certificateHelper = ApplicationManager.getApplication().getService(CertificateHelper.class);
var ksVirtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
var view = getViewComponent(e);
if (view == null) {
Messages.showErrorDialog("No JKS view found", "No JKS View");
}
var selectedAlias = view.getSelectedCertificate();
if (selectedAlias == null) {
Messages.showErrorDialog("No certificate selected", "No Certificate Selected");
}
var descriptor = new FileChooserDescriptor(
false, // Choose Files
true,
false,
false,
false,
false
);
var pwd = Messages.showPasswordDialog("Keystore password", "KeyStore Password");
if (pwd != null && !pwd.isBlank()) {
certificateHelper.exportCertificate(ksVirtualFile, selectedAlias, pwd.toCharArray());
Messages.showInfoMessage("Certificate exported", "Certificate Exported");
view.removeCertificate(selectedAlias);
}
}

private JKSView getViewComponent(@NotNull AnActionEvent e) {
// Retrieve your view component from context, e.g., using the data context from the event
return e.getData(PlatformDataKeys.CONTEXT_COMPONENT) instanceof JKSView
? (JKSView) e.getData(PlatformDataKeys.CONTEXT_COMPONENT)
: null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.Objects;

public class ImportCert extends AnAction {

Expand Down Expand Up @@ -53,7 +54,8 @@ public void actionPerformed(@NotNull AnActionEvent e) {
if (pwd != null && !pwd.isBlank()) {
certificateHelper.importCertificate(ksVirtualFile, file,selectedAlias.getInput(), pwd.toCharArray());
Messages.showInfoMessage("Certificate imported", "Certificate Imported");
getViewComponent(e);
Objects.requireNonNull(getViewComponent(e)).addCertificate(selectedAlias.getInput(),
certificateHelper.getCertificate(file).stream().findFirst().orElseThrow());
}

} catch (IOException ex) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/jmpeax/ssltoolbox/svc/CertificateHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.security.auth.x500.X500Principal;
import java.io.*;
Expand Down Expand Up @@ -156,6 +157,18 @@ public void importCertificate(@NotNull VirtualFile keyStoreFile, @NotNull Virtua
} catch (Exception e) {
LOGGER.error("Error importing certificate", e);
}
}

public @Nullable X509Certificate exportCertificate(VirtualFile ksVirtualFile,
String selectedAlias,
char[] password) {
try(var is = ksVirtualFile.getInputStream()) {
var keystore = openKeyStore(is, password);
var cert = keystore.getCertificate(selectedAlias);
return (X509Certificate) cert;
} catch (Exception e) {
LOGGER.error("Error exporting certificate", e);
return null;
}
}
}
6 changes: 5 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@
popup="true" icon="AllIcons.Ide.ConfigFile">
<action id="import-cert-jks" class="com.jmpeax.ssltoolbox.jks.actions.ImportCert"
text="Import" description="Import certificate"
icon="AllIcons.Actions.Refresh">
icon="AllIcons.Ide.IncomingChangesOn">
</action>
<action id="export-cert-jks" class="com.jmpeax.ssltoolbox.jks.actions.ExportCert"
text="Export" description="Export certificate"
icon="AllIcons.Ide.OutgoingChangesOn">
</action>
</group>

Expand Down

0 comments on commit d11a6a1

Please sign in to comment.