X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Forg%2Fcacert%2Fgigi%2Fpages%2Faccount%2FIssueCertificateForm.java;h=cf10c612fdcc61a1efa9525005e89a3c13ca90dd;hb=c330d2ce37cf4959f2281621f1af097be8c1a48b;hp=29565e0ee038a4c5e61de7fa9c80d6f1035e93df;hpb=b93a39014fe39b0b3527849acc0e57e5b7772f1b;p=gigi.git
diff --git a/src/org/cacert/gigi/pages/account/IssueCertificateForm.java b/src/org/cacert/gigi/pages/account/IssueCertificateForm.java
index 29565e0e..cf10c612 100644
--- a/src/org/cacert/gigi/pages/account/IssueCertificateForm.java
+++ b/src/org/cacert/gigi/pages/account/IssueCertificateForm.java
@@ -7,154 +7,199 @@ import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;
import java.util.HashMap;
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.database.DatabaseConnection;
+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 class uses "sun.security" and therefore needs "-XDignore.symbol.file"
- *
+ * This class represents a form that is used for issuing certificates. This
+ * class uses "sun.security" and therefore needs "-XDignore.symbol.file"
*/
public class IssueCertificateForm extends Form {
- User u;
- Digest selectedDigest = Digest.getDefault();
- boolean login;
- String csr;
-
- private final static Template t = new Template(IssueCertificateForm.class.getResource("IssueCertificateForm.templ"));
-
- public IssueCertificateForm(HttpServletRequest hsr) {
- super(hsr);
- u = LoginPage.getUser(hsr);
- }
-
- Certificate result;
-
- public Certificate getResult() {
- return result;
- }
-
- @Override
- public boolean submit(PrintWriter out, HttpServletRequest req) {
- 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() + "
");
- PublicKey pk = parsed.getSubjectPublicKeyInfo();
- out.println("Type: " + pk.getAlgorithm() + "
");
- if (pk instanceof RSAPublicKey) {
- out.println("Exponent: " + ((RSAPublicKey) pk).getPublicExponent() + "
");
- out.println("Length: " + ((RSAPublicKey) pk).getModulus().bitLength());
- } else if (pk instanceof DSAPublicKey) {
- DSAPublicKey dpk = (DSAPublicKey) pk;
- out.println("Length: " + dpk.getY().bitLength() + "
");
- out.println(dpk.getParams());
- } else if (pk instanceof ECPublicKey) {
- ECPublicKey epk = (ECPublicKey) pk;
- out.println("Length-x: " + epk.getW().getAffineX().bitLength() + "
");
- out.println("Length-y: " + epk.getW().getAffineY().bitLength() + "
");
- out.println(epk.getParams().getCurve());
- }
- out.println("
digest: sha256
");
- this.csr = csr;
- } else if (spkac != null) {
-
- } 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);
- try {
- result.issue().waitFor(60000);
- return true;
- } catch (SQLException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return false;
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (GeneralSecurityException e) {
- e.printStackTrace();
- }
- 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);
- }
-
- @Override
- protected void outputContent(PrintWriter out, Language l, Map vars) {
- HashMap vars2 = new HashMap(vars);
- vars2.put("CCA", "CCA");
-
- try {
- PreparedStatement ps = DatabaseConnection.getInstance().prepare(
- "SELECT `id`,`email` from `email` WHERE `memid`=? AND `deleted`=0");
- ps.setInt(1, u.getId());
- final ResultSet rs = ps.executeQuery();
- vars2.put("emails", new IterableDataset() {
-
- @Override
- public boolean next(Language l, Map vars) {
- try {
- if (!rs.next()) {
- return false;
- }
- vars.put("id", rs.getString(1));
- vars.put("value", rs.getString(2));
- return true;
- } catch (SQLException e) {
- e.printStackTrace();
- }
- return false;
- }
- });
- vars2.put("hashs", new HashAlgorithms(selectedDigest));
- t.output(out, l, vars2);
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
+ User u;
+
+ Digest selectedDigest = Digest.getDefault();
+
+ boolean login;
+
+ String csr;
+
+ private final static Template t = new Template(IssueCertificateForm.class.getResource("IssueCertificateForm.templ"));
+
+ private final static Template tIni = new Template(MailCertificateAdd.class.getResource("RequestCertificate.templ"));
+
+ String spkacChallange;
+
+ public IssueCertificateForm(HttpServletRequest hsr) {
+ super(hsr);
+ u = Page.getUser(hsr);
+ spkacChallange = RandomToken.generateToken(16);
+ }
+
+ Certificate result;
+
+ private CSRType csrType;
+
+ public Certificate getResult() {
+ return result;
+ }
+
+ @Override
+ public boolean submit(PrintWriter out, HttpServletRequest req) {
+ String csr = req.getParameter("CSR");
+ String spkac = req.getParameter("SPKAC");
+ 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() + "
");
+ PublicKey pk = parsed.getSubjectPublicKeyInfo();
+ checkKeyStrength(pk, out);
+ String sign = getSignatureAlgorithm(data);
+ out.println("
digest: " + sign + "
");
+
+ 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("
digest: " + sign + "
");
+
+ // 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 (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 (GigiApiException e) {
+ e.format(out, Page.getLanguage(req));
+ }
+ return false;
+ }
+
+ private void checkKeyStrength(PublicKey pk, PrintWriter out) {
+ out.println("Type: " + pk.getAlgorithm() + "
");
+ if (pk instanceof RSAPublicKey) {
+ out.println("Exponent: " + ((RSAPublicKey) pk).getPublicExponent() + "
");
+ out.println("Length: " + ((RSAPublicKey) pk).getModulus().bitLength());
+ } else if (pk instanceof DSAPublicKey) {
+ DSAPublicKey dpk = (DSAPublicKey) pk;
+ out.println("Length: " + dpk.getY().bitLength() + "
");
+ out.println(dpk.getParams());
+ } else if (pk instanceof ECPublicKey) {
+ ECPublicKey epk = (ECPublicKey) pk;
+ out.println("Length-x: " + epk.getW().getAffineX().bitLength() + "
");
+ out.println("Length-y: " + epk.getW().getAffineY().bitLength() + "
");
+ 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
+ public void output(PrintWriter out, Language l, Map vars) {
+ if (csr == null) {
+ HashMap vars2 = new HashMap(vars);
+ vars2.put("csrf", getCSRFToken());
+ vars2.put("csrf_name", getCsrfFieldName());
+ vars2.put("spkacChallange", spkacChallange);
+ tIni.output(out, l, vars2);
+ return;
+ } else {
+ super.output(out, l, vars);
+ }
+ }
+
+ @Override
+ protected void outputContent(PrintWriter out, Language l, Map vars) {
+ HashMap vars2 = new HashMap(vars);
+ vars2.put("CCA", "CCA");
+
+ final EmailAddress[] ea = u.getEmails();
+ vars2.put("emails", new IterableDataset() {
+
+ int count;
+
+ @Override
+ public boolean next(Language l, Map vars) {
+ if (count >= ea.length) {
+ return false;
+ }
+ vars.put("id", ea[count].getId());
+ vars.put("value", ea[count].getAddress());
+ count++;
+ return true;
+ }
+ });
+ vars2.put("hashs", new HashAlgorithms(selectedDigest));
+ t.output(out, l, vars2);
+ }
}