add: show more certificates on the "roots" page
authorFelix Dörre <felix@dogcraft.de>
Sun, 8 Oct 2017 15:22:05 +0000 (17:22 +0200)
committerFelix Dörre <felix@dogcraft.de>
Thu, 19 Oct 2017 21:20:43 +0000 (23:20 +0200)
Change-Id: I2a2acbba4636bc54b93d4f3022543a66a296ec6c

src/club/wpia/gigi/dbObjects/CACertificate.java
src/club/wpia/gigi/pages/RootCertPage.java
src/club/wpia/gigi/pages/RootCertPage.templ

index 5953059..1240cd8 100644 (file)
@@ -8,6 +8,7 @@ import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayDeque;
+import java.util.Arrays;
 import java.util.Deque;
 import java.util.HashMap;
 
@@ -30,6 +31,10 @@ public class CACertificate implements IdCachable {
 
     private final String link;
 
+    private static final CACertificate[] instances;
+
+    private static ObjectCache<CACertificate> myCache = new ObjectCache<>();
+
     private CACertificate(int id) {
         this.id = id;
         int parentRoot;
@@ -78,6 +83,17 @@ public class CACertificate implements IdCachable {
     static {
         try {
             update();
+            try (GigiPreparedStatement q = new GigiPreparedStatement("SELECT `id` FROM `cacerts`", true)) {
+                GigiResultSet res = q.executeQuery();
+                res.last();
+                CACertificate[] certs = new CACertificate[res.getRow()];
+                res.beforeFirst();
+                int i = 0;
+                while (res.next()) {
+                    certs[i++] = getById(res.getInt(1));
+                }
+                instances = certs;
+            }
         } catch (CertificateException e) {
             throw new Error(e);
         } catch (FileNotFoundException e) {
@@ -161,8 +177,6 @@ public class CACertificate implements IdCachable {
         return id;
     }
 
-    private static ObjectCache<CACertificate> myCache = new ObjectCache<>();
-
     public String getKeyname() {
         return keyname;
     }
@@ -183,4 +197,8 @@ public class CACertificate implements IdCachable {
         return this == getParent();
     }
 
+    public static synchronized CACertificate[] getAll() {
+        return Arrays.copyOf(instances, instances.length);
+    }
+
 }
index c821e7c..9d1d9c9 100644 (file)
@@ -1,29 +1,96 @@
 package club.wpia.gigi.pages;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import club.wpia.gigi.dbObjects.CACertificate;
+import club.wpia.gigi.localisation.Language;
+import club.wpia.gigi.output.template.Outputable;
+import club.wpia.gigi.util.HTMLEncoder;
 import club.wpia.gigi.util.PEM;
 
 public class RootCertPage extends Page {
 
-    private Certificate root;
+    private final Certificate root;
+
+    private final CACertificate[] cs;
+
+    private final OutputableCertificate rootP;
+
+    private class OutputableCertificate implements Outputable {
+
+        private final CACertificate target;
+
+        private final OutputableCertificate[] children;
+
+        public OutputableCertificate(CACertificate c) {
+            target = c;
+            LinkedList<OutputableCertificate> children = new LinkedList<>();
+            for (CACertificate c0 : cs) {
+                if (c0.getParent() == c && c0 != c) {
+                    children.add(new OutputableCertificate(c0));
+                }
+            }
+
+            Collections.sort(children, new Comparator<OutputableCertificate>() {
+
+                @Override
+                public int compare(OutputableCertificate o1, OutputableCertificate o2) {
+                    return o1.target.getKeyname().compareTo(o2.target.getKeyname());
+                }
+            });
+            this.children = children.toArray(new OutputableCertificate[children.size()]);
+        }
+
+        @Override
+        public void output(PrintWriter out, Language l, Map<String, Object> vars) {
+            out.println("<a href='" + HTMLEncoder.encodeHTML(target.getLink()) + "'>");
+            out.println(HTMLEncoder.encodeHTML(target.getKeyname()));
+            out.println("</a>");
+            out.println(HTMLEncoder.encodeHTML(target.getCertificate().getSubjectX500Principal().toString()));
+            out.println("<ul>");
+            for (OutputableCertificate c : children) {
+                out.print("<li>");
+                c.output(out, l, vars);
+                out.print("</li>");
+            }
+            out.println("</ul>");
+        }
+
+    }
 
     public RootCertPage(KeyStore ks) {
         super("Root Certificates");
         try {
             root = ks.getCertificate("root");
         } catch (KeyStoreException e) {
-            e.printStackTrace();
+            throw new Error(e);
+        }
+        cs = CACertificate.getAll();
+        CACertificate rootC = null;
+        for (CACertificate c : cs) {
+            if (c.isSelfsigned()) {
+                rootC = c;
+                break;
+            }
+        }
+        if (rootC == null) {
+            throw new Error();
         }
+        rootP = new OutputableCertificate(rootC);
     }
 
     @Override
@@ -52,7 +119,9 @@ public class RootCertPage extends Page {
 
     @Override
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
-        getDefaultTemplate().output(resp.getWriter(), getLanguage(req), new HashMap<String, Object>());
+        HashMap<String, Object> map = new HashMap<String, Object>();
+        map.put("root", rootP);
+        getDefaultTemplate().output(resp.getWriter(), getLanguage(req), map);
 
     }
 
index cd65445..060fdfd 100644 (file)
@@ -1,2 +1,8 @@
 <?=_The Root certificates are available for download here. Choose your preferred format:?><br/>
-<a href="?pem">PEM</a> <a href="?cer">CER</a>
+<a href="?pem">PEM</a> <a href="?cer">DER</a>
+<p>
+<?=_A full list of DER-encoded certificates is also provided below.?>
+</p>
+<div>
+<?=$root?>
+</div>