]> WPIA git - gigi.git/blobdiff - tests/club/wpia/gigi/testUtils/ConfiguredTest.java
add: functionality check for rejection of broken keys
[gigi.git] / tests / club / wpia / gigi / testUtils / ConfiguredTest.java
index bf50d6112af53ce1565eadf1b0c8cc7dd3266f0e..16abb06cf2623c36de562da1dbbba8b354e51419 100644 (file)
@@ -8,10 +8,17 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.math.BigInteger;
 import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
 import java.security.Signature;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
 import java.sql.SQLException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
@@ -27,14 +34,14 @@ import org.junit.BeforeClass;
 
 import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.database.DatabaseConnection;
-import club.wpia.gigi.database.GigiPreparedStatement;
 import club.wpia.gigi.database.DatabaseConnection.Link;
+import club.wpia.gigi.database.GigiPreparedStatement;
 import club.wpia.gigi.database.SQLFileManager.ImportType;
+import club.wpia.gigi.dbObjects.CATS.CATSType;
 import club.wpia.gigi.dbObjects.CertificateProfile;
 import club.wpia.gigi.dbObjects.Domain;
 import club.wpia.gigi.dbObjects.DomainPingType;
 import club.wpia.gigi.dbObjects.User;
-import club.wpia.gigi.dbObjects.CATS.CATSType;
 import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail;
 import club.wpia.gigi.util.DatabaseManager;
 import club.wpia.gigi.util.DomainAssessment;
@@ -78,6 +85,15 @@ public abstract class ConfiguredTest {
     public static Properties initEnvironment() throws IOException {
         TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
         if (envInited) {
+            try {
+                synchronized (ConfiguredTest.class) {
+                    if (l == null) {
+                        l = DatabaseConnection.newLink(false);
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new Error(e);
+            }
             return generateProps();
         }
         envInited = true;
@@ -93,7 +109,11 @@ public abstract class ConfiguredTest {
         if ( !DatabaseConnection.isInited()) {
             DatabaseConnection.init(testProps);
             try {
-                l = DatabaseConnection.newLink(false);
+                synchronized (ConfiguredTest.class) {
+                    if (l == null) {
+                        l = DatabaseConnection.newLink(false);
+                    }
+                }
             } catch (InterruptedException e) {
                 throw new Error(e);
             }
@@ -104,9 +124,11 @@ public abstract class ConfiguredTest {
 
     @AfterClass
     public static void closeDBLink() {
-        if (l != null) {
-            l.close();
-            l = null;
+        synchronized (ConfiguredTest.class) {
+            if (l != null) {
+                l.close();
+                l = null;
+            }
         }
     }
 
@@ -116,6 +138,10 @@ public abstract class ConfiguredTest {
         mainProps.setProperty("name.www", testProps.getProperty("name.www"));
         mainProps.setProperty("name.static", testProps.getProperty("name.static"));
         mainProps.setProperty("name.api", testProps.getProperty("name.api"));
+        mainProps.setProperty("name.suffix", testProps.getProperty("name.suffix"));
+
+        mainProps.setProperty("appName", "SomeCA");
+        mainProps.setProperty("appIdentifier", "someca");
 
         mainProps.setProperty("https.port", testProps.getProperty("serverPort.https"));
         mainProps.setProperty("http.port", testProps.getProperty("serverPort.http"));
@@ -158,6 +184,96 @@ public abstract class ConfiguredTest {
         return keyPair;
     }
 
+    public static KeyPair generateBrokenKeypair() throws GeneralSecurityException {
+        KeyPair keyPair = null;
+        File f = new File("testBrokenKeypair");
+        if (f.exists()) {
+            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f))) {
+                keyPair = (KeyPair) ois.readObject();
+            } catch (ClassNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } else {
+            // -----BEGIN SHAMELESSLY ADAPTED BLOCK-----
+            /**
+             * Modified original RSA key generator to use three primes with one
+             * prime set to fixed value to allow simple checking for such faulty
+             * keys.
+             *
+             * @link sun.security.rsa.RSAKeyPairGenerator#generateKeyPair
+             */
+
+            KeyFactory factory = KeyFactory.getInstance("RSA");
+            Random random = new SecureRandom();
+            int keySize = 4096;
+            long r_lv = 7331;
+
+            int lp = (keySize + 1) >> 1;
+            int lr = BigInteger.valueOf(r_lv).bitLength();
+            int lq = keySize - lp - lr;
+
+            BigInteger e = BigInteger.valueOf(7331);
+
+            keyPair = null;
+            while (keyPair == null) {
+                // generate two random primes of size lp/lq
+                BigInteger p, q, r, n;
+
+                p = BigInteger.probablePrime(lp, random);
+                r = BigInteger.valueOf(r_lv);
+                do {
+                    q = BigInteger.probablePrime(lq, random);
+
+                    // convention is for p > q > r
+                    if (p.compareTo(q) < 0) {
+                        BigInteger tmp = p;
+                        p = q;
+                        q = tmp;
+                    }
+
+                    // modulus n = p * q * r
+                    n = p.multiply(q).multiply(r);
+
+                    // even with correctly sized p, q and r, there is a chance
+                    // that n will be one bit short. re-generate the smaller
+                    // prime if so.
+                } while (n.bitLength() < keySize);
+
+                // phi = (p - 1) * (q - 1) * (r - 1) must be relative prime to e
+                // otherwise RSA just won't work ;-)
+                BigInteger p1 = p.subtract(BigInteger.ONE);
+                BigInteger q1 = q.subtract(BigInteger.ONE);
+                BigInteger r1 = r.subtract(BigInteger.ONE);
+                BigInteger phi = p1.multiply(q1).multiply(r1);
+
+                // generate new p and q until they work. typically
+                if (e.gcd(phi).equals(BigInteger.ONE) == false) {
+                    continue;
+                }
+
+                // private exponent d is the inverse of e mod phi
+                BigInteger d = e.modInverse(phi);
+
+                RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(n, e);
+                RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(n, d);
+                PublicKey publicKey = factory.generatePublic(publicSpec);
+                PrivateKey privateKey = factory.generatePrivate(privateSpec);
+                keyPair = new KeyPair(publicKey, privateKey);
+            }
+            // -----END SHAMELESSLY ADAPTED BLOCK-----
+
+            try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f))) {
+                oos.writeObject(keyPair);
+                oos.close();
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+            }
+        }
+        return keyPair;
+    }
+
     public static String generatePEMCSR(KeyPair kp, String dn) throws GeneralSecurityException, IOException {
         return generatePEMCSR(kp, dn, new PKCS10Attributes());
     }
@@ -209,10 +325,10 @@ public abstract class ConfiguredTest {
         return i;
     }
 
-    public static void makeAssurer(int uid) {
+    public static void makeAgent(int uid) {
         try (GigiPreparedStatement ps1 = new GigiPreparedStatement("INSERT INTO cats_passed SET user_id=?, variant_id=?, language='en_EN', version='1'")) {
             ps1.setInt(1, uid);
-            ps1.setInt(2, CATSType.ASSURER_CHALLENGE.getId());
+            ps1.setInt(2, CATSType.AGENT_CHALLENGE.getId());
             ps1.execute();
         }
 
@@ -230,7 +346,7 @@ public abstract class ConfiguredTest {
     public void verify(Domain d) {
         try {
             d.addPing(DomainPingType.EMAIL, "admin");
-            TestMail testMail = getMailReceiver().receive();
+            TestMail testMail = getMailReceiver().receive("admin@" + d.getSuffix());
             testMail.verify();
             assertTrue(d.isVerified());
         } catch (GigiApiException e) {