]> WPIA git - gigi.git/blobdiff - src/org/cacert/gigi/pages/account/IssueCertificateForm.java
UPD: moved getUser up
[gigi.git] / src / org / cacert / gigi / pages / account / IssueCertificateForm.java
index da57bec3a2e235244ef9b22ee5d0ee436c368468..cf10c612fdcc61a1efa9525005e89a3c13ca90dd 100644 (file)
@@ -15,19 +15,26 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 
 import org.cacert.gigi.Certificate;
+import org.cacert.gigi.Certificate.CSRType;
 import org.cacert.gigi.Digest;
 import org.cacert.gigi.EmailAddress;
+import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.Language;
 import org.cacert.gigi.User;
-import org.cacert.gigi.Certificate.CSRType;
+import org.cacert.gigi.crypto.SPKAC;
 import org.cacert.gigi.output.Form;
 import org.cacert.gigi.output.template.HashAlgorithms;
 import org.cacert.gigi.output.template.IterableDataset;
 import org.cacert.gigi.output.template.Template;
 import org.cacert.gigi.pages.LoginPage;
+import org.cacert.gigi.pages.Page;
+import org.cacert.gigi.util.PEM;
 import org.cacert.gigi.util.RandomToken;
 
 import sun.security.pkcs10.PKCS10;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerValue;
+import sun.security.x509.AlgorithmId;
 
 /**
  * This class represents a form that is used for issuing certificates. This
@@ -51,7 +58,7 @@ public class IssueCertificateForm extends Form {
 
     public IssueCertificateForm(HttpServletRequest hsr) {
         super(hsr);
-        u = LoginPage.getUser(hsr);
+        u = Page.getUser(hsr);
         spkacChallange = RandomToken.generateToken(16);
     }
 
@@ -68,70 +75,93 @@ public class IssueCertificateForm extends Form {
         String csr = req.getParameter("CSR");
         String spkac = req.getParameter("SPKAC");
         try {
-            if (csr != null) {
-                PKCS10 parsed = parseCSR(csr);
-                out.println(parsed.getSubjectName().getCommonName());
-                out.println(parsed.getSubjectName().getCountry());
-                out.println("CSR DN: " + parsed.getSubjectName() + "<br/>");
-                PublicKey pk = parsed.getSubjectPublicKeyInfo();
-                out.println("Type: " + pk.getAlgorithm() + "<br/>");
-                if (pk instanceof RSAPublicKey) {
-                    out.println("Exponent: " + ((RSAPublicKey) pk).getPublicExponent() + "<br/>");
-                    out.println("Length: " + ((RSAPublicKey) pk).getModulus().bitLength());
-                } else if (pk instanceof DSAPublicKey) {
-                    DSAPublicKey dpk = (DSAPublicKey) pk;
-                    out.println("Length: " + dpk.getY().bitLength() + "<br/>");
-                    out.println(dpk.getParams());
-                } else if (pk instanceof ECPublicKey) {
-                    ECPublicKey epk = (ECPublicKey) pk;
-                    out.println("Length-x: " + epk.getW().getAffineX().bitLength() + "<br/>");
-                    out.println("Length-y: " + epk.getW().getAffineY().bitLength() + "<br/>");
-                    out.println(epk.getParams().getCurve());
-                }
-                out.println("<br/>digest: sha256<br/>");
-                this.csr = csr;
-                this.csrType = CSRType.CSR;
-            } else if (spkac != null) {
-                this.csr = "SPKAC=" + spkac.replaceAll("[\r\n]", "");
-                this.csrType = CSRType.SPKAC;
-            } else {
-                login = "1".equals(req.getParameter("login"));
-                String hashAlg = req.getParameter("hash_alg");
-                if (hashAlg != null) {
-                    selectedDigest = Digest.valueOf(hashAlg);
-                }
-                if (req.getParameter("CCA") == null) {
-                    outputError(out, req, "You need to accept the CCA.");
-                    return false;
-                }
-                System.out.println("issuing " + selectedDigest);
-                result = new Certificate(LoginPage.getUser(req).getId(), "/commonName=CAcert WoT User", selectedDigest.toString(), this.csr, this.csrType);
-                try {
+            try {
+                if (csr != null) {
+                    byte[] data = PEM.decode("(NEW )?CERTIFICATE REQUEST", csr);
+                    PKCS10 parsed = new PKCS10(data);
+
+                    out.println(parsed.getSubjectName().getCommonName());
+                    out.println(parsed.getSubjectName().getCountry());
+                    out.println("CSR DN: " + parsed.getSubjectName() + "<br/>");
+                    PublicKey pk = parsed.getSubjectPublicKeyInfo();
+                    checkKeyStrength(pk, out);
+                    String sign = getSignatureAlgorithm(data);
+                    out.println("<br/>digest: " + sign + "<br/>");
+
+                    this.csr = csr;
+                    this.csrType = CSRType.CSR;
+                } else if (spkac != null) {
+                    String cleanedSPKAC = spkac.replaceAll("[\r\n]", "");
+                    byte[] data = Base64.getDecoder().decode(cleanedSPKAC);
+                    SPKAC parsed = new SPKAC(data);
+                    if ( !parsed.getChallenge().equals(spkacChallange)) {
+                        throw new GigiApiException("Challange mismatch");
+                    }
+                    checkKeyStrength(parsed.getPubkey(), out);
+                    String sign = getSignatureAlgorithm(data);
+                    out.println("<br/>digest: " + sign + "<br/>");
+
+                    // spkacChallange
+                    this.csr = "SPKAC=" + cleanedSPKAC;
+                    this.csrType = CSRType.SPKAC;
+
+                } else {
+                    login = "1".equals(req.getParameter("login"));
+                    String hashAlg = req.getParameter("hash_alg");
+                    if (hashAlg != null) {
+                        selectedDigest = Digest.valueOf(hashAlg);
+                    }
+                    if (req.getParameter("CCA") == null) {
+                        outputError(out, req, "You need to accept the CCA.");
+                        return false;
+                    }
+                    System.out.println("issuing " + selectedDigest);
+                    result = new Certificate(LoginPage.getUser(req).getId(), "/commonName=CAcert WoT User", selectedDigest.toString(), this.csr, this.csrType);
                     result.issue().waitFor(60000);
                     return true;
-                } catch (SQLException e) {
-                    e.printStackTrace();
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
                 }
-                return false;
+            } catch (IOException e) {
+                e.printStackTrace();
+            } catch (IllegalArgumentException e) {
+                throw new GigiApiException("Certificate Request format is invalid.");
+            } catch (GeneralSecurityException e) {
+                throw new GigiApiException("Certificate Request format is invalid.");
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (SQLException e) {
+                throw new GigiApiException(e);
             }
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (GeneralSecurityException e) {
-            e.printStackTrace();
+        } catch (GigiApiException e) {
+            e.format(out, Page.getLanguage(req));
         }
         return false;
     }
 
-    private PKCS10 parseCSR(String csr) throws IOException, GeneralSecurityException {
-        csr = csr.replaceFirst("-----BEGIN (NEW )?CERTIFICATE REQUEST-----", "");
-        csr = csr.replaceFirst("-----END (NEW )?CERTIFICATE REQUEST-----", "");
-        csr = csr.replace("\r", "");
-        csr = csr.replace("\n", "");
-        byte[] b = Base64.getDecoder().decode(csr);
-        // Also checks signature validity
-        return new PKCS10(b);
+    private void checkKeyStrength(PublicKey pk, PrintWriter out) {
+        out.println("Type: " + pk.getAlgorithm() + "<br/>");
+        if (pk instanceof RSAPublicKey) {
+            out.println("Exponent: " + ((RSAPublicKey) pk).getPublicExponent() + "<br/>");
+            out.println("Length: " + ((RSAPublicKey) pk).getModulus().bitLength());
+        } else if (pk instanceof DSAPublicKey) {
+            DSAPublicKey dpk = (DSAPublicKey) pk;
+            out.println("Length: " + dpk.getY().bitLength() + "<br/>");
+            out.println(dpk.getParams());
+        } else if (pk instanceof ECPublicKey) {
+            ECPublicKey epk = (ECPublicKey) pk;
+            out.println("Length-x: " + epk.getW().getAffineX().bitLength() + "<br/>");
+            out.println("Length-y: " + epk.getW().getAffineY().bitLength() + "<br/>");
+            out.println(epk.getParams().getCurve());
+        }
+    }
+
+    private static PKCS10 parseCSR(String csr) throws IOException, GeneralSecurityException {
+        return new PKCS10(PEM.decode("(NEW )?CERTIFICATE REQUEST", csr));
+    }
+
+    private static String getSignatureAlgorithm(byte[] data) throws IOException {
+        DerInputStream in = new DerInputStream(data);
+        DerValue[] seq = in.getSequence(3);
+        return AlgorithmId.parse(seq[1]).getName();
     }
 
     @Override