diff --git a/apps/routerconsole/java/src/net/i2p/router/web/CertHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/CertHelper.java
new file mode 100644
index 0000000000..f476c1dfed
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/CertHelper.java
@@ -0,0 +1,81 @@
+package net.i2p.router.web;
+
+import java.io.File;
+import java.io.IOException;
+
+import net.i2p.util.FileUtil;
+
+
+/**
+ * Dump out our local SSL certs, if any
+ *
+ * @since 0.9.23
+ */
+public class CertHelper extends HelperBase {
+
+ private static final String DIR = "certificates";
+ private static final String I2CP = "i2cp/i2cp.local.crt";
+ private static final String CONSOLE = "console/console.local.crt";
+ private static final String I2PTUNNEL_DIR = "i2ptunnel";
+
+ public String getSummary() {
+ File dir = new File(_context.getConfigDir(), DIR);
+ try {
+ _out.write("
");
+ _out.write(_t("Local SSL Certificates"));
+ _out.write("
\n");
+ // console
+ output("Console", new File(dir, CONSOLE));
+ // I2CP
+ output("I2CP", new File(dir, I2CP));
+ // i2ptunnel clients
+ File tunnelDir = new File(_context.getConfigDir(), I2PTUNNEL_DIR);
+ boolean hasTunnels = false;
+ File[] tunnels = tunnelDir.listFiles();
+ if (tunnels != null) {
+ for (int i = 0; i < tunnels.length; i++) {
+ File f = tunnels[i];
+ if (!f.isFile())
+ continue;
+ String name = f.getName();
+ if (!name.endsWith(".local.crt"))
+ continue;
+ if (!name.startsWith("i2ptunnel-"))
+ continue;
+ String b32 = name.substring(10, name.length() - 10);
+ output(_t("I2PTunnel") + ' ' + b32, f);
+ hasTunnels = true;
+ }
+ }
+ if (!hasTunnels)
+ output(_t("I2PTunnel"), null);
+ // anything else? plugins?
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ return "";
+ }
+
+ /**
+ * @param file may be null
+ */
+ private void output(String name, File file) throws IOException {
+ _out.write("");
+ _out.write("
");
+ _out.write(name);
+ if (file != null && file.exists()) {
+ String cert = FileUtil.readTextFile(file.toString(), -1, true);
+ if (cert != null) {
+ _out.write("\n\n");
+ } else {
+ _out.write(": read failure");
+ }
+ } else {
+ _out.write(": ");
+ _out.write(_t("none"));
+ }
+ _out.write("\n");
+ }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
index 35e96b6eab..91483b97fc 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java
@@ -760,6 +760,13 @@ public class RouterConsoleRunner implements RouterApp {
changes.put(PROP_KEY_PASSWORD, keyPassword);
_context.router().saveConfig(changes, null);
} catch (Exception e) {} // class cast exception
+ // export cert, fails silently
+ File dir = new SecureDirectory(_context.getConfigDir(), "certificates");
+ dir.mkdir();
+ dir = new SecureDirectory(dir, "console");
+ dir.mkdir();
+ File certFile = new File(dir, "console.local.crt");
+ KeyStoreUtil.exportCert(ks, DEFAULT_KEYSTORE_PASSWORD, "console", certFile);
}
}
if (success) {
diff --git a/apps/routerconsole/jsp/certs.jsp b/apps/routerconsole/jsp/certs.jsp
new file mode 100644
index 0000000000..3c4e59cf62
--- /dev/null
+++ b/apps/routerconsole/jsp/certs.jsp
@@ -0,0 +1,17 @@
+<%@page contentType="text/html"%>
+<%@page trimDirectiveWhitespaces="true"%>
+<%@page pageEncoding="UTF-8"%>
+
+
+<%@include file="css.jsi" %>
+<%=intl.title("Certificates")%>
+
+<%@include file="summaryajax.jsi" %>
+
+<%@include file="summary.jsi" %><%=intl._t("Certificates")%>
+
+
+" />
+<% certhelper.storeWriter(out); %>
+
+