--- /dev/null
+#!/bin/bash
+openssl ecparam -out ec.pem -name secp521r1 -genkey
+openssl req -new -key ec.pem -out ec.csr -subj "/CN=bla"
+
+openssl dsaparam -genkey 1024 -out dsa.pem
+openssl req -new -key dsa.pem -out dsa.csr -subj "/CN=bla"
+
--- /dev/null
+package org.cacert.gigi;
+
+public enum Digest {
+ SHA256("Currently recommended, because the other algorithms"
+ + " might break on some older versions of the GnuTLS library"
+ + " (older than 3.x) still shipped in Debian for example."), SHA384(null), SHA512(
+ "Highest protection against hash collision attacks of the algorithms offered here.");
+ final String exp;
+
+ private Digest(String explanation) {
+ exp = explanation;
+ }
+
+ public String getExp() {
+ return exp;
+ }
+
+ public static Digest getDefault() {
+ return SHA256;
+ }
+}
import org.cacert.gigi.util.RandomToken;
public abstract class Form implements Outputable {
+ public static final String CSRF_FIELD = "csrf";
String csrf;
public Form(HttpServletRequest hsr) {
public final void output(PrintWriter out, Language l, Map<String, Object> vars) {
out.println("<form method='POST' autocomplete='off'>");
outputContent(out, l, vars);
- out.print("<input type='hidden' name='csrf' value='");
+ out.print("<input type='hidden' name='" + CSRF_FIELD + "' value='");
out.print(getCSRFToken());
out.println("'></form>");
}
}
protected void checkCSRF(HttpServletRequest req) {
- if (!csrf.equals(req.getParameter("csrf"))) {
+ if (!csrf.equals(req.getParameter(CSRF_FIELD))) {
throw new CSRFError();
}
}
public static <T extends Form> T getForm(HttpServletRequest req, Class<T> target) {
- String csrf = req.getParameter("csrf");
+ String csrf = req.getParameter(CSRF_FIELD);
if (csrf == null) {
throw new CSRFError();
}
--- /dev/null
+package org.cacert.gigi.output.template;
+
+import java.util.Map;
+
+import org.cacert.gigi.Digest;
+import org.cacert.gigi.Language;
+
+public class HashAlgorithms implements IterableDataset {
+
+ int i = 0;
+ Digest selected;
+
+ public HashAlgorithms(Digest selected) {
+ this.selected = selected;
+ }
+
+ @Override
+ public boolean next(Language l, Map<String, Object> vars) {
+ Digest[] length = Digest.values();
+ if (i >= length.length) {
+ return false;
+ }
+ Digest d = length[i++];
+ vars.put("algorithm", d.toString());
+ vars.put("name", d.toString());
+ vars.put("info", l.getTranslation(d.getExp()));
+ vars.put("checked", selected == d ? " checked='checked'" : "");
+ return true;
+ }
+}
--- /dev/null
+package org.cacert.gigi.pages.account;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.GeneralSecurityException;
+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 javax.servlet.http.HttpServletResponse;
+
+import org.cacert.gigi.Certificate;
+import org.cacert.gigi.Digest;
+import org.cacert.gigi.Language;
+import org.cacert.gigi.User;
+import org.cacert.gigi.database.DatabaseConnection;
+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 sun.security.pkcs10.PKCS10;
+
+/**
+ * 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();
+
+ private final static Template t = new Template(IssueCertificateForm.class.getResource("IssueCertificateForm.templ"));
+
+ public IssueCertificateForm(HttpServletRequest hsr) {
+ super(hsr);
+ u = LoginPage.getUser(hsr);
+ }
+
+ @Override
+ public boolean submit(PrintWriter out, HttpServletRequest req) {
+ String csr = req.getParameter("CSR");
+ String spkac = req.getParameter("spkac");
+ try {
+ if (csr != null && !"".equals(csr)) {
+ 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/>");
+
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (GeneralSecurityException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ private void issue(HttpServletRequest req, HttpServletResponse resp, String csr) throws IOException {
+ Certificate c = new Certificate(LoginPage.getUser(req).getId(), "/commonName=CAcert WoT User", "sha256", csr);
+ c.issue();
+ try {
+ c.waitFor(60000);
+ resp.sendRedirect(MailCertificates.PATH + "/" + c.getSerial());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ 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<String, Object> vars) {
+ HashMap<String, Object> vars2 = new HashMap<String, Object>(vars);
+ vars2.put("CCA", "<a href='/policy/CAcertCommunityAgreement.html'>CCA</a>");
+
+ 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<String, Object> 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();
+ }
+ }
+
+}
<tr class="expert">
<td colspan="2" align="left">
<?=_Hash algorithm used when signing the certificate:?><br />
- <!-- Hash algs!!! -->
+ <? foreach($hashs) { ?>
+ <input type="radio" id="hash_alg_<?=$algorithm?>" name="hash_alg" value="<?=$algorithm?>"<?=$checked?>/>
+ <label for="hash_alg_<?=$algorithm?>"><?=$name?><? if($info) { ?> - <?=$info?><? } ?></label><br />
+ <? } ?>
</td>
</tr>
</tr>
<? } ?>
- <tr class="expert">
- <td>
- <input type="checkbox" id="SSO" name="SSO" value="1" />
- </td>
- <td align="left">
- <label for="SSO"><?=_Add Single Sign On ID Information?><br />
- <?=_By adding Single Sign On (SSO) ID information to your certificates this could be used to track you, you can also issue certificates with no email addresses that are useful only for Authentication. Please see a more detailed description on our WIKI about it.?>
- <a href="http://wiki.cacert.org/wiki/SSO"><?=_SSO WIKI Entry?></a></label>
- </td>
- </tr>
-
- <tr class="expert">
- <td colspan="2">
- <label for="optionalCSR"><?=_Optional Client CSR, no information on the certificate will be used?></label><br />
- <textarea id="optionalCSR" name="optionalCSR" cols="80" rows="5"></textarea>
- </td>
- </tr>
-
-
<tr>
<td>
<input type="checkbox" id="CCA" name="CCA" />
package org.cacert.gigi.pages.account;
import java.io.IOException;
-import java.io.PrintWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.cacert.gigi.Certificate;
import org.cacert.gigi.Language;
import org.cacert.gigi.User;
import org.cacert.gigi.database.DatabaseConnection;
-import org.cacert.gigi.output.ClientCSRGenerate;
import org.cacert.gigi.output.template.IterableDataset;
import org.cacert.gigi.pages.LoginPage;
+import org.cacert.gigi.output.Form;
+import org.cacert.gigi.output.template.Template;
import org.cacert.gigi.pages.Page;
public class MailCertificateAdd extends Page {
public static final String PATH = "/account/certs/email/new";
+ Template t = new Template(MailCertificateAdd.class.getResource("RequestCertificate.templ"));
public MailCertificateAdd() {
super("Create Email certificate");
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- PrintWriter out = resp.getWriter();
- if (req.getParameter("optionalCSR") == null || req.getParameter("optionalCSR").equals("")) {
- out.println("csr missing");
- ClientCSRGenerate.output(req, resp);
- }
- String csr = req.getParameter("optionalCSR");
- if (!"on".equals(req.getParameter("CCA"))) {
- // Error.
- return;
- }
- Certificate c = new Certificate(LoginPage.getUser(req).getId(), "/commonName=CAcert WoT User", "sha256", csr);
- c.issue();
- try {
- c.waitFor(60000);
- resp.sendRedirect(MailCertificates.PATH + "/" + c.getSerial());
- } catch (SQLException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
+ IssueCertificateForm f;
+ if (req.getParameter(Form.CSRF_FIELD) != null) {
+ f = Form.getForm(req, IssueCertificateForm.class);
+ } else {
+ f = new IssueCertificateForm(req);
+ f.submit(resp.getWriter(), req);
}
+ f.output(resp.getWriter(), getLanguage(req), Collections.<String, Object> emptyMap());
}
-
}
--- /dev/null
+
+<table class="wrapper dataTable">
+ <thead>
+ <tr>
+ <th colspan="2" class="title"><?=_New Certificate?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><?=_CSR?></td>
+ <td><?=_SPKAC?></td>
+ </tr>
+
+ <tr>
+ <td>
+ <form method="post"> <textarea name="CSR"></textarea><br/><input type="submit" name="process" value="<?=_Next?>" /></form>
+ </td>
+ <td align="left">
+ <form method="post"> <keygen name="SPKAC"/><br/><input type="submit" name="process" value="<?=_Next?>" /></form>
+
+ </td>
+ </tr>
+ </tbody>
+</table>
.dataTable select, .dataTable option {
font-size: 92%;
}
+.dataTable textarea{
+ width: 100%;
+}