1 package org.cacert.gigi.pages.account.certs;
3 import java.io.IOException;
4 import java.io.PrintWriter;
5 import java.net.URLEncoder;
6 import java.security.GeneralSecurityException;
7 import java.security.cert.X509Certificate;
8 import java.util.HashMap;
9 import java.util.LinkedList;
12 import javax.servlet.ServletOutputStream;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
16 import org.cacert.gigi.dbObjects.CACertificate;
17 import org.cacert.gigi.dbObjects.Certificate;
18 import org.cacert.gigi.localisation.Language;
19 import org.cacert.gigi.output.template.Form;
20 import org.cacert.gigi.output.template.IterableDataset;
21 import org.cacert.gigi.output.template.Template;
22 import org.cacert.gigi.pages.HandlesMixedRequest;
23 import org.cacert.gigi.pages.LoginPage;
24 import org.cacert.gigi.pages.Page;
25 import org.cacert.gigi.util.PEM;
27 import sun.security.pkcs.ContentInfo;
28 import sun.security.pkcs.PKCS7;
29 import sun.security.pkcs.SignerInfo;
30 import sun.security.x509.AlgorithmId;
32 public class Certificates extends Page implements HandlesMixedRequest {
34 private Template certDisplay = new Template(Certificates.class.getResource("CertificateDisplay.templ"));
36 public static final String PATH = "/account/certs";
38 static class TrustchainIterable implements IterableDataset {
42 public TrustchainIterable(CACertificate cert) {
47 public boolean next(Language l, Map<String, Object> vars) {
51 vars.put("name", cert.getKeyname());
52 vars.put("link", cert.getLink());
53 if (cert.isSelfsigned()) {
57 cert = cert.getParent();
63 public Certificates() {
64 super("Certificates");
68 public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
70 String pi = req.getPathInfo().substring(PATH.length());
71 if (pi.length() == 0) {
77 resp.setContentType("application/pkix-cert");
78 if (req.getParameter("install") != null) {
79 resp.setContentType("application/x-x509-user-cert");
81 if (pi.endsWith(".crt")) {
83 pi = pi.substring(0, pi.length() - 4);
84 } else if (pi.endsWith(".cer")) {
86 pi = pi.substring(0, pi.length() - 4);
87 } else if (pi.endsWith(".cer")) {
89 pi = pi.substring(0, pi.length() - 4);
93 Certificate c = Certificate.getBySerial(serial);
94 if (c == null || LoginPage.getAuthorizationContext(req).getTarget().getId() != c.getOwner().getId()) {
98 X509Certificate cert = c.cert();
102 ServletOutputStream out = resp.getOutputStream();
104 out.println(PEM.encode("CERTIFICATE", cert.getEncoded()));
105 if (req.getParameter("chain") != null) {
106 CACertificate ca = c.getParent();
107 while ( !ca.isSelfsigned()) {
108 out.println(PEM.encode("CERTIFICATE", ca.getCertificate().getEncoded()));
111 if (req.getParameter("noAnchor") == null) {
112 out.println(PEM.encode("CERTIFICATE", ca.getCertificate().getEncoded()));
116 if (req.getParameter("install") != null) {
117 PKCS7 p7 = toP7Chain(c);
118 p7.encodeSignedData(out);
120 * ContentInfo ci = toCIChain(c); try (DerOutputStream dos =
121 * new DerOutputStream()) { ci.encode(dos);
122 * out.write(dos.toByteArray()); }
125 out.write(cert.getEncoded());
128 } catch (IllegalArgumentException e) {
131 } catch (GeneralSecurityException e) {
139 private static PKCS7 toP7Chain(Certificate c) throws IOException, GeneralSecurityException {
140 LinkedList<X509Certificate> ll = getChain(c);
141 PKCS7 p7 = new PKCS7(new AlgorithmId[0], new ContentInfo(ContentInfo.DATA_OID, null), ll.toArray(new X509Certificate[ll.size()]), new SignerInfo[0]);
145 private static LinkedList<X509Certificate> getChain(Certificate c) throws IOException, GeneralSecurityException {
146 LinkedList<X509Certificate> ll = new LinkedList<>();
148 CACertificate ca = c.getParent();
149 while ( !ca.isSelfsigned()) {
150 ll.add(ca.getCertificate());
153 ll.add(ca.getCertificate());
158 public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
159 if (req.getQueryString() != null && !req.getQueryString().equals("") && !req.getQueryString().equals("withRevoked")) {
160 return;// Block actions by get parameters.
162 if ( !req.getPathInfo().equals(PATH)) {
166 Form.getForm(req, CertificateModificationForm.class).submit(resp.getWriter(), req);
171 public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
172 PrintWriter out = resp.getWriter();
173 String pi = req.getPathInfo().substring(PATH.length());
174 if (pi.length() != 0) {
175 pi = pi.substring(1);
178 Certificate c = Certificate.getBySerial(serial);
179 if (c == null || LoginPage.getAuthorizationContext(req).getTarget().getId() != c.getOwner().getId()) {
183 HashMap<String, Object> vars = new HashMap<>();
184 vars.put("serial", URLEncoder.encode(serial, "UTF-8"));
185 vars.put("trustchain", new TrustchainIterable(c.getParent()));
187 vars.put("cert", c.cert());
188 } catch (GeneralSecurityException e) {
191 certDisplay.output(out, getLanguage(req), vars);
196 HashMap<String, Object> vars = new HashMap<String, Object>();
197 new CertificateModificationForm(req, req.getParameter("withRevoked") != null).output(out, getLanguage(req), vars);