add: initial class for performing arbitrary checks to validate public keys
authorBenny Baumann <BenBE1987@gmx.net>
Wed, 18 Oct 2017 23:25:59 +0000 (01:25 +0200)
committerBenny Baumann <BenBE1987@gmx.net>
Wed, 1 Nov 2017 23:12:09 +0000 (00:12 +0100)
Change-Id: Ia7813913b1f5922747ddba4af9a21e4fbaf07c9e

src/club/wpia/gigi/crypto/key/KeyCheck.java [new file with mode: 0644]
src/club/wpia/gigi/pages/account/certs/CertificateRequest.java
tests/club/wpia/gigi/crypto/key/KeyCheckTest.java [new file with mode: 0644]

diff --git a/src/club/wpia/gigi/crypto/key/KeyCheck.java b/src/club/wpia/gigi/crypto/key/KeyCheck.java
new file mode 100644 (file)
index 0000000..7c1ed82
--- /dev/null
@@ -0,0 +1,59 @@
+package club.wpia.gigi.crypto.key;
+
+import java.security.PublicKey;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import club.wpia.gigi.GigiApiException;
+
+public abstract class KeyCheck {
+
+    protected static final Set<KeyCheck> checks = new LinkedHashSet<KeyCheck>();
+
+    public static List<KeyCheck> getChecks() {
+        return Collections.list(Collections.enumeration(checks));
+    }
+
+    public static void register(KeyCheck check) {
+        checks.add(check);
+    }
+
+    public abstract void check(PublicKey key) throws GigiApiException;
+
+    public static void checkKey(PublicKey key) throws GigiApiException {
+
+        if (checks.isEmpty()) {
+            // Mandatory checks are registered here
+        }
+
+        if (key == null) {
+            throw new GigiApiException("Failed key sanity check: No key given!");
+        }
+
+        for (KeyCheck kc : checks) {
+            kc.check(key);
+        }
+
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+
+        if (o == this) {
+            return true;
+        }
+
+        return getClass().equals(o.getClass());
+    }
+
+    @Override
+    public int hashCode() {
+        return getClass().hashCode();
+    }
+
+}
index 4158e9b..8a1bc59 100644 (file)
@@ -16,6 +16,7 @@ import java.util.TreeSet;
 
 import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.crypto.SPKAC;
+import club.wpia.gigi.crypto.key.KeyCheck;
 import club.wpia.gigi.dbObjects.Certificate;
 import club.wpia.gigi.dbObjects.Certificate.CSRType;
 import club.wpia.gigi.dbObjects.Certificate.SANType;
@@ -108,7 +109,7 @@ public class CertificateRequest {
         this(c, csr, (CertificateProfile) null);
     }
 
-    public CertificateRequest(AuthorizationContext ctx, String csr, CertificateProfile cp) throws GeneralSecurityException, IOException, IOException {
+    public CertificateRequest(AuthorizationContext ctx, String csr, CertificateProfile cp) throws GeneralSecurityException, IOException, IOException, GigiApiException {
         this.ctx = ctx;
         if (cp != null) {
             profile = cp;
@@ -190,6 +191,8 @@ public class CertificateRequest {
         }
         this.SANs = SANs;
         pk = parsed.getSubjectPublicKeyInfo();
+        KeyCheck.checkKey(pk);
+
         String sign = getSignatureAlgorithm(data);
         guessDigest(sign);
 
@@ -206,12 +209,13 @@ public class CertificateRequest {
             throw new GigiApiException("Challenge mismatch");
         }
         pk = parsed.getPubkey();
+        KeyCheck.checkKey(pk);
+
         String sign = getSignatureAlgorithm(data);
         guessDigest(sign);
         this.SANs = new HashSet<>();
         this.csr = "SPKAC=" + cleanedSPKAC;
         this.csrType = CSRType.SPKAC;
-
     }
 
     private static String getSignatureAlgorithm(byte[] data) throws IOException {
diff --git a/tests/club/wpia/gigi/crypto/key/KeyCheckTest.java b/tests/club/wpia/gigi/crypto/key/KeyCheckTest.java
new file mode 100644 (file)
index 0000000..203e830
--- /dev/null
@@ -0,0 +1,36 @@
+package club.wpia.gigi.crypto.key;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.PublicKey;
+
+import org.junit.Test;
+
+import sun.security.util.DerValue;
+import sun.security.x509.X509Key;
+import club.wpia.gigi.GigiApiException;
+import club.wpia.gigi.util.PEM;
+
+public class KeyCheckTest {
+
+    public static PublicKey pkFromString(String pub) throws GeneralSecurityException, IOException {
+        byte[] data = PEM.decode("PUBLIC KEY", pub);
+        DerValue der = new DerValue(data);
+        PublicKey key = X509Key.parse(der);
+
+        return key;
+    }
+
+    @Test
+    public void testNullKey() {
+        try {
+            KeyCheck.checkKey(null);
+            fail("Providing a null key should fail!");
+        } catch (GigiApiException gae) {
+            assertTrue(true);
+        }
+    }
+
+}