]> WPIA git - gigi.git/commitdiff
Add tests for certificate data pre-fillin:
authorFelix Dörre <felix@dogcraft.de>
Fri, 15 Aug 2014 23:18:39 +0000 (01:18 +0200)
committerFelix Dörre <felix@dogcraft.de>
Fri, 15 Aug 2014 23:18:39 +0000 (01:18 +0200)
- message digests: sha256/384/512
- cn is dns und cn is real name
- mail/ssl-client/ssl-server EKU
- SANs with dns, mail
- SANs where email from dn is already included.

src/org/cacert/gigi/pages/account/CertificateIssueForm.java
tests/org/cacert/gigi/pages/account/TestCertificateAdd.java [new file with mode: 0644]

index 4332a39142f630acf7986e7292b2186cda98b05a..184b87860ca8a0388a1ea36ddc52f02237f6767f 100644 (file)
@@ -64,7 +64,7 @@ import sun.security.x509.X500Name;
  */
 public class CertificateIssueForm extends Form {
 
  */
 public class CertificateIssueForm extends Form {
 
-    private static final String DEFAULT_CN = "CAcert WoT User";
+    public static final String DEFAULT_CN = "CAcert WoT User";
 
     private final static Template t = new Template(CertificateIssueForm.class.getResource("CertificateIssueForm.templ"));
 
 
     private final static Template t = new Template(CertificateIssueForm.class.getResource("CertificateIssueForm.templ"));
 
diff --git a/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java b/tests/org/cacert/gigi/pages/account/TestCertificateAdd.java
new file mode 100644 (file)
index 0000000..9888b6a
--- /dev/null
@@ -0,0 +1,180 @@
+package org.cacert.gigi.pages.account;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.Signature;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.cacert.gigi.Digest;
+import org.cacert.gigi.User;
+import org.cacert.gigi.crypto.SPKAC;
+import org.cacert.gigi.testUtils.IOUtils;
+import org.cacert.gigi.testUtils.ManagedTest;
+import org.junit.Test;
+
+import sun.security.pkcs.PKCS9Attribute;
+import sun.security.pkcs10.PKCS10Attribute;
+import sun.security.pkcs10.PKCS10Attributes;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.CertificateExtensions;
+import sun.security.x509.DNSName;
+import sun.security.x509.ExtendedKeyUsageExtension;
+import sun.security.x509.GeneralName;
+import sun.security.x509.GeneralNameInterface;
+import sun.security.x509.GeneralNames;
+import sun.security.x509.RFC822Name;
+import sun.security.x509.SubjectAlternativeNameExtension;
+import sun.security.x509.X509Key;
+
+public class TestCertificateAdd extends ManagedTest {
+
+    KeyPair kp = generateKeypair();
+
+    User u = User.getById(createVerifiedUser("testuser", "testname", uniq + "@testdom.com", TEST_PASSWORD));
+
+    String session = login(uniq + "@testdom.com", TEST_PASSWORD);
+
+    public TestCertificateAdd() throws GeneralSecurityException, IOException {
+        TestDomain.addDomain(session, uniq + ".tld");
+
+    }
+
+    @Test
+    public void testSimpleServer() throws IOException, GeneralSecurityException {
+        PKCS10Attributes atts = buildAtts(new ObjectIdentifier[] {
+            CertificateIssueForm.OID_KEY_USAGE_SSL_SERVER
+        }, new DNSName(uniq + ".tld"));
+
+        String pem = generatePEMCSR(kp, "CN=a." + uniq + ".tld", atts);
+
+        String[] res = fillOutForm("CSR=" + URLEncoder.encode(pem, "UTF-8"));
+        assertArrayEquals(new String[] {
+                "server", "CAcert WoT User", "dns:a." + uniq + ".tld\ndns:" + uniq + ".tld\n", Digest.SHA256.toString()
+        }, res);
+    }
+
+    @Test
+    public void testSimpleMail() throws IOException, GeneralSecurityException {
+        PKCS10Attributes atts = buildAtts(new ObjectIdentifier[] {
+            CertificateIssueForm.OID_KEY_USAGE_EMAIL_PROTECTION
+        }, new DNSName("a." + uniq + ".tld"), new DNSName("b." + uniq + ".tld"), new RFC822Name(uniq + "@testdom.com"));
+
+        String pem = generatePEMCSR(kp, "CN=testuser testname", atts, "SHA384WithRSA");
+
+        String[] res = fillOutForm("CSR=" + URLEncoder.encode(pem, "UTF-8"));
+        assertArrayEquals(new String[] {
+                "mail", "testuser testname", "dns:a." + uniq + ".tld\ndns:b." + uniq + ".tld\nemail:" + uniq + "@testdom.com\n", Digest.SHA384.toString()
+        }, res);
+    }
+
+    @Test
+    public void testSimpleClient() throws IOException, GeneralSecurityException {
+        PKCS10Attributes atts = buildAtts(new ObjectIdentifier[] {
+            CertificateIssueForm.OID_KEY_USAGE_SSL_CLIENT
+        }, new RFC822Name(uniq + "@testdom.com"));
+
+        String pem = generatePEMCSR(kp, "CN=testuser testname,email=" + uniq + "@testdom.com", atts, "SHA512WithRSA");
+
+        String[] res = fillOutForm("CSR=" + URLEncoder.encode(pem, "UTF-8"));
+        assertArrayEquals(new String[] {
+                "client", "testuser testname", "email:" + uniq + "@testdom.com\n", Digest.SHA512.toString()
+        }, res);
+    }
+
+    @Test
+    public void testSPKAC() throws GeneralSecurityException, IOException {
+        testSPKAC(false);
+        testSPKAC(true);
+    }
+
+    protected void testSPKAC(boolean correctChallange) throws GeneralSecurityException, IOException {
+        HttpURLConnection uc = (HttpURLConnection) ncert.openConnection();
+        uc.setRequestProperty("Cookie", session);
+        String s = IOUtils.readURL(uc);
+
+        String csrf = extractPattern(s, Pattern.compile("<input [^>]*name='csrf' [^>]*value='([^']*)'>"));
+        String challenge = extractPattern(s, Pattern.compile("<keygen [^>]*name=\"SPKAC\" [^>]*challenge=\"([^\"]*)\"/>"));
+
+        SPKAC spk = new SPKAC((X509Key) kp.getPublic(), challenge + (correctChallange ? "" : "b"));
+        Signature sign = Signature.getInstance("SHA512WithRSA");
+        sign.initSign(kp.getPrivate());
+        try {
+            String[] res = fillOutForm(csrf, "SPKAC=" + URLEncoder.encode(Base64.getEncoder().encodeToString(spk.getEncoded(sign)), "UTF-8"));
+            if ( !correctChallange) {
+                fail("Should not succeed with wrong challange.");
+            }
+            assertArrayEquals(new String[] {
+                    "client", CertificateIssueForm.DEFAULT_CN, "", Digest.SHA512.toString()
+            }, res);
+        } catch (Error e) {
+            assertTrue(e.getMessage().startsWith("<div>Challenge mismatch"));
+        }
+    }
+
+    private PKCS10Attributes buildAtts(ObjectIdentifier[] ekuOIDs, GeneralNameInterface... SANs) throws IOException {
+        CertificateExtensions attributeValue = new CertificateExtensions();
+        GeneralNames names = new GeneralNames();
+
+        for (GeneralNameInterface name : SANs) {
+            names.add(new GeneralName(name));
+        }
+        attributeValue.set("SANs", new SubjectAlternativeNameExtension(names));
+        PKCS10Attributes atts = new PKCS10Attributes(new PKCS10Attribute[] {
+            new PKCS10Attribute(PKCS9Attribute.EXTENSION_REQUEST_OID, attributeValue)
+        });
+        ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension(//
+                new Vector<>(Arrays.<ObjectIdentifier>asList(ekuOIDs)));
+        attributeValue.set("eku", eku);
+        return atts;
+    }
+
+    private final URL ncert = new URL("https://" + getServerName() + CertificateAdd.PATH);
+
+    private String[] fillOutForm(String pem) throws IOException {
+        HttpURLConnection uc = (HttpURLConnection) ncert.openConnection();
+        uc.setRequestProperty("Cookie", session);
+        String csrf = getCSRF(uc);
+        return fillOutForm(csrf, pem);
+
+    }
+
+    private String[] fillOutForm(String csrf, String pem) throws IOException {
+
+        HttpURLConnection uc = (HttpURLConnection) ncert.openConnection();
+        uc.setRequestProperty("Cookie", session);
+        uc.setDoOutput(true);
+        uc.getOutputStream().write(("csrf=" + URLEncoder.encode(csrf, "UTF-8") + "&" + pem).getBytes());
+        uc.getOutputStream().flush();
+
+        String result = IOUtils.readURL(uc);
+        if (result.contains("<div class='formError'>")) {
+            String s = fetchStartErrorMessage(result);
+            throw new Error(s);
+        }
+
+        String profileKey = extractPattern(result, Pattern.compile("<option value=\"([^\"]*)\" selected>"));
+        String resultingCN = extractPattern(result, Pattern.compile("<input [^>]*name='CN' [^>]*value='([^']*)'>"));
+        String txt = extractPattern(result, Pattern.compile("<textarea [^>]*name='SANs' [^>]*>([^<]*)</textarea>"));
+        String md = extractPattern(result, Pattern.compile("<input type=\"radio\" [^>]*name=\"hash_alg\" value=\"([^\"]*)\" checked='checked'/>"));
+        return new String[] {
+                profileKey, resultingCN, txt, md
+        };
+    }
+
+    private String extractPattern(String result, Pattern p) {
+        Matcher m = p.matcher(result);
+        assertTrue(m.find());
+        String resultingCN = m.group(1);
+        return resultingCN;
+    }
+}