766d21ea0ab7e6b5ba50f678721084d76b6cd35f
[gigi.git] / src / org / cacert / gigi / pages / account / certs / Certificates.java
1 package org.cacert.gigi.pages.account.certs;
2
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.Map;
10
11 import javax.servlet.ServletOutputStream;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14
15 import org.cacert.gigi.dbObjects.CACertificate;
16 import org.cacert.gigi.dbObjects.Certificate;
17 import org.cacert.gigi.localisation.Language;
18 import org.cacert.gigi.output.template.Form;
19 import org.cacert.gigi.output.template.IterableDataset;
20 import org.cacert.gigi.output.template.Template;
21 import org.cacert.gigi.pages.HandlesMixedRequest;
22 import org.cacert.gigi.pages.LoginPage;
23 import org.cacert.gigi.pages.Page;
24 import org.cacert.gigi.util.PEM;
25
26 public class Certificates extends Page implements HandlesMixedRequest {
27
28     private Template certDisplay = new Template(Certificates.class.getResource("CertificateDisplay.templ"));
29
30     public static final String PATH = "/account/certs";
31
32     static class TrustchainIterable implements IterableDataset {
33
34         CACertificate cert;
35
36         public TrustchainIterable(CACertificate cert) {
37             this.cert = cert;
38         }
39
40         @Override
41         public boolean next(Language l, Map<String, Object> vars) {
42             if (cert == null) {
43                 return false;
44             }
45             vars.put("name", cert.getKeyname());
46             vars.put("link", cert.getLink());
47             if (cert.isSelfsigned()) {
48                 cert = null;
49                 return true;
50             }
51             cert = cert.getParent();
52             return true;
53         }
54
55     }
56
57     public Certificates() {
58         super("Certificates");
59     }
60
61     @Override
62     public boolean beforeTemplate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
63
64         String pi = req.getPathInfo().substring(PATH.length());
65         if (pi.length() == 0) {
66             return false;
67         }
68         pi = pi.substring(1);
69         boolean crt = false;
70         boolean cer = false;
71         resp.setContentType("application/pkix-cert");
72         if (pi.endsWith(".crt")) {
73             crt = true;
74             pi = pi.substring(0, pi.length() - 4);
75         } else if (pi.endsWith(".cer")) {
76             if (req.getParameter("install") != null) {
77                 resp.setContentType("application/x-x509-user-cert");
78             }
79             cer = true;
80             pi = pi.substring(0, pi.length() - 4);
81         } else if (pi.endsWith(".cer")) {
82             cer = true;
83             pi = pi.substring(0, pi.length() - 4);
84         }
85         String serial = pi;
86         try {
87             Certificate c = Certificate.getBySerial(serial);
88             if (c == null || LoginPage.getAuthorizationContext(req).getTarget().getId() != c.getOwner().getId()) {
89                 resp.sendError(404);
90                 return true;
91             }
92             X509Certificate cert = c.cert();
93             if ( !crt && !cer) {
94                 return false;
95             }
96             ServletOutputStream out = resp.getOutputStream();
97             if (crt) {
98                 out.println(PEM.encode("CERTIFICATE", cert.getEncoded()));
99                 if (req.getParameter("chain") != null) {
100                     CACertificate ca = c.getParent();
101                     while ( !ca.isSelfsigned()) {
102                         out.println(PEM.encode("CERTIFICATE", ca.getCertificate().getEncoded()));
103                         ca = ca.getParent();
104                     }
105                     if (req.getParameter("noAnchor") == null) {
106                         out.println(PEM.encode("CERTIFICATE", ca.getCertificate().getEncoded()));
107                     }
108                 }
109             } else if (cer) {
110                 out.write(cert.getEncoded());
111             }
112         } catch (IllegalArgumentException e) {
113             resp.sendError(404);
114             return true;
115         } catch (GeneralSecurityException e) {
116             resp.sendError(404);
117             return true;
118         }
119
120         return true;
121     }
122
123     @Override
124     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
125         if (req.getQueryString() != null && !req.getQueryString().equals("") && !req.getQueryString().equals("withRevoked")) {
126             return;// Block actions by get parameters.
127         }
128         if ( !req.getPathInfo().equals(PATH)) {
129             resp.sendError(500);
130             return;
131         }
132         Form.getForm(req, CertificateModificationForm.class).submit(resp.getWriter(), req);
133         doGet(req, resp);
134     }
135
136     @Override
137     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
138         PrintWriter out = resp.getWriter();
139         String pi = req.getPathInfo().substring(PATH.length());
140         if (pi.length() != 0) {
141             pi = pi.substring(1);
142
143             String serial = pi;
144             Certificate c = Certificate.getBySerial(serial);
145             if (c == null || LoginPage.getAuthorizationContext(req).getTarget().getId() != c.getOwner().getId()) {
146                 resp.sendError(404);
147                 return;
148             }
149             HashMap<String, Object> vars = new HashMap<>();
150             vars.put("serial", URLEncoder.encode(serial, "UTF-8"));
151             vars.put("trustchain", new TrustchainIterable(c.getParent()));
152             try {
153                 vars.put("cert", c.cert());
154             } catch (GeneralSecurityException e) {
155                 e.printStackTrace();
156             }
157             certDisplay.output(out, getLanguage(req), vars);
158
159             return;
160         }
161
162         HashMap<String, Object> vars = new HashMap<String, Object>();
163         new CertificateModificationForm(req, req.getParameter("withRevoked") != null).output(out, getLanguage(req), vars);
164     }
165
166 }