Merge "add: show sha-1 and sha-256 fingerprint on certificate page "
authorLucas Werkmeister <mail@lucaswerkmeister.de>
Sun, 23 Dec 2018 10:34:50 +0000 (11:34 +0100)
committerGerrit Code Review <gigi-system@dogcraft.de>
Sun, 23 Dec 2018 10:34:50 +0000 (11:34 +0100)
src/club/wpia/gigi/dbObjects/Certificate.java
src/club/wpia/gigi/pages/account/certs/CertificateDisplay.templ
src/club/wpia/gigi/pages/account/certs/Certificates.java
tests/club/wpia/gigi/dbObjects/TestCertificate.java

index 61fd7d3..a97ed15 100644 (file)
@@ -4,6 +4,9 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -16,6 +19,8 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map.Entry;
 
+import javax.xml.bind.DatatypeConverter;
+
 import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.database.DBEnum;
 import club.wpia.gigi.database.GigiPreparedStatement;
@@ -662,4 +667,18 @@ public class Certificate implements IdCachable {
         }
         return new BigInteger(serial, 16);
     }
+
+    public String getFingerprint(String algorithm) throws IOException, GeneralSecurityException, GigiApiException {
+        X509Certificate certx = cert();
+        return getFingerprint(certx, algorithm);
+    }
+
+    private static String getFingerprint(X509Certificate cert, String algorithm) throws NoSuchAlgorithmException, CertificateEncodingException {
+        MessageDigest md = MessageDigest.getInstance(algorithm);
+        byte[] der = cert.getEncoded();
+        md.update(der);
+        byte[] digest = md.digest();
+        String digestHex = DatatypeConverter.printHexBinary(digest);
+        return digestHex.toLowerCase();
+    }
 }
index 9aad7bc..f2aaf87 100644 (file)
   </tr>
 
   <tr>
-    <td><?=_Fingerprint?>:</td>
-    <td><?=$fingerprint?></td>
+    <td><?=_Fingerprint SHA-1?>:</td>
+    <td><?=$fingerprintSHA1?></td>
+  </tr>
+  <tr>
+    <td><?=_Fingerprint SHA-256?>:</td>
+    <td><?=$fingerprintSHA256?></td>
   </tr>
-
   <tr>
     <td valign="top"><?=_Certificate (PEM)?>:</td>
     <td><pre><?=$cert?></pre></td>
index 40faa1f..9c0dafd 100644 (file)
@@ -183,8 +183,15 @@ public class Certificates extends Page implements HandlesMixedRequest {
             vars.put("DN", c.getDistinguishedName());
             vars.put("digest", c.getMessageDigest());
             vars.put("profile", c.getProfile().getVisibleName());
-            vars.put("fingerprint", "TBD"); // TODO function needs to be
-                                            // implemented in Certificate.java
+            try {
+                vars.put("fingerprintSHA1", c.getFingerprint("sha-1"));
+                vars.put("fingerprintSHA256", c.getFingerprint("sha-256"));
+            } catch (GeneralSecurityException e) {
+                e.printStackTrace();
+            } catch (GigiApiException e) {
+                e.format(out, l, getDefaultVars(req));
+            }
+
             try {
 
                 if (st == CertificateStatus.ISSUED || st == CertificateStatus.REVOKED) {
index 0b4d654..5321ba1 100644 (file)
@@ -9,6 +9,7 @@ import java.security.KeyPair;
 import org.junit.Test;
 
 import club.wpia.gigi.GigiApiException;
+import club.wpia.gigi.database.GigiPreparedStatement;
 import club.wpia.gigi.dbObjects.Certificate.AttachmentType;
 import club.wpia.gigi.dbObjects.Certificate.CSRType;
 import club.wpia.gigi.testUtils.ClientBusinessTest;
@@ -77,4 +78,36 @@ public class TestCertificate extends ClientBusinessTest {
         assertEquals(u, c.getActor());
         assertEquals("AB", c.getActor().getInitials());
     }
+
+    @Test
+    public void testFingerprint() throws IOException, GeneralSecurityException, GigiApiException {
+        Certificate c = importCertificate();
+        assertEquals("fa6175b369627d47a52b9fd73e87ccf087afbd10", c.getFingerprint("sha-1"));
+        assertEquals("98c3f2a5424d2404e0b2ccdae17d8cbc949ea36bddb0c3f152a931f88c17c3d3", c.getFingerprint("sha-256"));
+    }
+
+    private Certificate importCertificate() throws GigiApiException {
+        int certID;
+        try (GigiPreparedStatement inserter = new GigiPreparedStatement("INSERT INTO certs SET md=?::`mdType`, csr_type=?::`csrType`, memid=?, profile=?, actorid=?, created=NOW(), caid=?, expire=NOW()")) {
+            inserter.setString(1, Digest.SHA512.toString().toLowerCase());
+            inserter.setString(2, CSRType.CSR.toString());
+            inserter.setInt(3, u.getId());
+            inserter.setInt(4, 10);
+            inserter.setInt(5, u.getId());
+            inserter.setInt(6, 4);
+            inserter.execute();
+            certID = inserter.lastInsertId();
+        }
+
+        try (GigiPreparedStatement insertAVA = new GigiPreparedStatement("INSERT INTO `certAvas` SET `certId`=?, name=?, value=?")) {
+            insertAVA.setInt(1, certID);
+            insertAVA.setString(2, "EMAIL");
+            insertAVA.setString(3, u.getEmail());
+            insertAVA.execute();
+        }
+        Certificate c = Certificate.getById(certID);
+        String pem = "-----BEGIN CERTIFICATE-----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-----END CERTIFICATE-----";
+        c.addAttachment(AttachmentType.CRT, pem);
+        return c;
+    }
 }