KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > ui > web > admin > cainterface > AdminCertReqServlet


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13
14 package org.ejbca.ui.web.admin.cainterface;
15
16 import java.beans.Beans JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.security.cert.CertificateEncodingException JavaDoc;
19 import java.security.cert.CertificateException JavaDoc;
20 import java.security.cert.X509Certificate JavaDoc;
21
22 import javax.ejb.EJBException JavaDoc;
23 import javax.servlet.ServletConfig JavaDoc;
24 import javax.servlet.ServletException JavaDoc;
25 import javax.servlet.ServletOutputStream JavaDoc;
26 import javax.servlet.http.HttpServlet JavaDoc;
27 import javax.servlet.http.HttpServletRequest JavaDoc;
28 import javax.servlet.http.HttpServletResponse JavaDoc;
29 import javax.servlet.http.HttpSession JavaDoc;
30
31 import org.apache.log4j.Logger;
32 import org.ejbca.core.ejb.ServiceLocator;
33 import org.ejbca.core.ejb.ca.sign.ISignSessionLocal;
34 import org.ejbca.core.ejb.ca.sign.ISignSessionLocalHome;
35 import org.ejbca.core.model.SecConst;
36 import org.ejbca.core.model.ca.AuthLoginException;
37 import org.ejbca.core.model.ca.AuthStatusException;
38 import org.ejbca.core.model.ca.IllegalKeyException;
39 import org.ejbca.core.model.ca.SignRequestException;
40 import org.ejbca.core.model.ca.SignRequestSignatureException;
41 import org.ejbca.core.model.ca.caadmin.CADoesntExistsException;
42 import org.ejbca.core.model.log.Admin;
43 import org.ejbca.core.model.ra.NotFoundException;
44 import org.ejbca.core.protocol.IResponseMessage;
45 import org.ejbca.core.protocol.PKCS10RequestMessage;
46 import org.ejbca.ui.web.RequestHelper;
47 import org.ejbca.ui.web.admin.configuration.EjbcaWebBean;
48 import org.ejbca.ui.web.admin.rainterface.RAInterfaceBean;
49 import org.ejbca.ui.web.admin.rainterface.UserView;
50 import org.ejbca.util.Base64;
51 import org.ejbca.util.CertTools;
52 import org.ejbca.util.FileTools;
53 import org.ejbca.util.StringTools;
54
55
56 /**
57  * This is a servlet that is used for creating a user into EJBCA and retrieving her certificate.
58  * This servlet requires authentication of the administrator, specifically it requires that the
59  * client certificate has the privilege "/ra_functionallity/create_end_entity", as defined in the
60  * admin-GUI.
61  *
62  * <p>
63  * This implementation handles only the POST method.
64  * </p>
65  *
66  * <p>
67  * The CGI parameters for requests are the following.
68  * </p>
69  *
70  * <dl>
71  * <dt>
72  * pkcs10req
73  * </dt>
74  * <dd>
75  * A PKCS#10 request, mandatory.
76  * </dd>
77  * <dt>
78  * username
79  * </dt>
80  * <dd>
81  * The username (for EJBCA use only). Optional, defaults to the DN in the PKCS#10 request.
82  * </dd>
83  * <dt>
84  * password
85  * </dt>
86  * <dd>
87  * Password for the user (for EJBCA internal use only). Optional, defaults to an empty string.
88  * Used for authorization af certificate request.
89  * </dd>
90  * <dt>
91  * entityprofile
92  * </dt>
93  * <dd>
94  * The name of the EJBCA end entity profile for the user. Optional, defaults to the built-in EMPTY
95  * end entity profile.
96  * </dd>
97  * <dt>
98  * certificateprofile
99  * </dt>
100  * <dd>
101  * The name of the EJBCA certificate profile to use. Optional, defaults to the built-in ENDUSER
102  * certificate profile.
103  * </dd>
104  * <dt>ca</dt>
105  * <dd>
106  * The name of the ca to use. Required,
107  * </dd>
108  * </dl>
109  *
110  *
111  * @author Ville Skyttä
112  * @version $Id: AdminCertReqServlet.java,v 1.4 2006/12/04 15:04:59 anatom Exp $
113  *
114  * @web.servlet name = "AdminCertReq"
115  * display-name = "AdminCertReqServlet"
116  * description="Used to retrive CA certificate request and Processed CA Certificates from AdminWeb GUI"
117  * load-on-startup = "99"
118  *
119  * @web.servlet-mapping url-pattern = "/ca/certreq"
120  *
121  */

122 public class AdminCertReqServlet extends HttpServlet JavaDoc {
123     private final static Logger log = Logger.getLogger(AdminCertReqServlet.class);
124     
125     private final static byte[] BEGIN_CERT =
126         "-----BEGIN CERTIFICATE-----".getBytes();
127     private final static int BEGIN_CERT_LENGTH = BEGIN_CERT.length;
128     
129     private final static byte[] END_CERT =
130         "-----END CERTIFICATE-----".getBytes();
131     private final static int END_CERT_LENGTH = END_CERT.length;
132     
133     private final static byte[] NL = "\n".getBytes();
134     private final static int NL_LENGTH = NL.length;
135     
136     private ISignSessionLocal signsession = null;
137
138     private synchronized ISignSessionLocal getSignSession(){
139         if(signsession == null){
140             try {
141                 ISignSessionLocalHome signhome = (ISignSessionLocalHome)ServiceLocator.getInstance().getLocalHome(ISignSessionLocalHome.COMP_NAME);
142                 signsession = signhome.create();
143             }catch(Exception JavaDoc e){
144                 throw new EJBException JavaDoc(e);
145             }
146         }
147         return signsession;
148     }
149
150     public void init(ServletConfig JavaDoc config)
151     throws ServletException JavaDoc
152     {
153         super.init(config);
154         try {
155             // Install BouncyCastle provider
156
CertTools.installBCProvider();
157         } catch (Exception JavaDoc e) {
158             throw new ServletException JavaDoc(e);
159         }
160     }
161     
162     
163     /**
164      * Handles PKCS10 certificate request, these are constructed as:
165      * <pre><code>
166      * CertificationRequest ::= SEQUENCE {
167      * certificationRequestInfo CertificationRequestInfo,
168      * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
169      * signature BIT STRING
170      * }
171      * CertificationRequestInfo ::= SEQUENCE {
172      * version INTEGER { v1(0) } (v1,...),
173      * subject Name,
174      * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
175      * attributes [0] Attributes{{ CRIAttributes }}
176      * }
177      * SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {
178      * algorithm AlgorithmIdentifier {{IOSet}},
179      * subjectPublicKey BIT STRING
180      * }
181      * </pre>
182      *
183      * PublicKey's encoded-format has to be RSA X.509.
184      */

185     public void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
186     throws IOException JavaDoc, ServletException JavaDoc
187     {
188         // Check if authorized
189
EjbcaWebBean ejbcawebbean= getEjbcaWebBean(request);
190         try{
191             ejbcawebbean.initialize(request, "/ra_functionallity/create_end_entity");
192         } catch(Exception JavaDoc e){
193             throw new java.io.IOException JavaDoc("Authorization Denied");
194         }
195         
196         X509Certificate JavaDoc[] certs = (X509Certificate JavaDoc[]) request.getAttribute("javax.servlet.request.X509Certificate");
197         if (certs == null) {
198             throw new ServletException JavaDoc("This servlet requires certificate authentication!");
199         }
200         
201         Admin admin = new Admin(certs[0]);
202         
203         RequestHelper.setDefaultCharacterEncoding(request);
204
205         byte[] buffer = pkcs10Bytes(request.getParameter("pkcs10req"));
206         if (buffer == null) {
207             response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid request, missing 'pkcs10req'!");
208             return;
209         }
210         
211         RAInterfaceBean rabean = getRaBean(request);
212         
213         // Decompose the PKCS#10 request, and create the user.
214
PKCS10RequestMessage p10 = new PKCS10RequestMessage(buffer);
215         String JavaDoc dn = p10.getCertificationRequest().getCertificationRequestInfo().getSubject().toString();
216         
217         String JavaDoc username = request.getParameter("username");
218         if (username == null || username.trim().length() == 0) {
219             username = dn;
220         }
221         // Strip dangerous chars
222
username = StringTools.strip(username);
223         // need null check here?
224
// Before doing anything else, check if the user name is unique and ok.
225
username = checkUsername(rabean, username);
226         
227         UserView newuser = new UserView();
228         newuser.setUsername(username);
229         
230         newuser.setSubjectDN(dn);
231         newuser.setTokenType(SecConst.TOKEN_SOFT_BROWSERGEN);
232         newuser.setAdministrator(false);
233         newuser.setKeyRecoverable(false);
234         
235         String JavaDoc email = CertTools.getPartFromDN(dn, "E"); // BC says VeriSign
236
if (email == null) email = CertTools.getPartFromDN(dn, "EMAILADDRESS");
237         if (email != null) {
238             newuser.setEmail(email);
239         }
240         
241         String JavaDoc tmp = null;
242         int eProfileId = SecConst.EMPTY_ENDENTITYPROFILE;
243         if ((tmp = request.getParameter("entityprofile")) != null) {
244             int reqId = rabean.getEndEntityProfileId(tmp);
245             if (reqId == 0) {
246                 throw new ServletException JavaDoc("No such end entity profile: " + tmp);
247             }
248             eProfileId = reqId;
249         }
250         newuser.setEndEntityProfileId(eProfileId);
251         
252         int cProfileId = SecConst.CERTPROFILE_FIXED_ENDUSER;
253         if ((tmp = request.getParameter("certificateprofile")) != null) {
254             CAInterfaceBean cabean = getCaBean(request);
255             int reqId = cabean.getCertificateProfileId(tmp);
256             if (reqId == 0) {
257                 throw new ServletException JavaDoc("No such certificate profile: " + tmp);
258             }
259             cProfileId = reqId;
260         }
261         newuser.setCertificateProfileId(cProfileId);
262         
263         int caid = 0;
264         if ((tmp = request.getParameter("ca")) != null) {
265             // TODO: get requested CA to sign with
266
}
267         newuser.setCAId(caid);
268         
269         
270         String JavaDoc password = request.getParameter("password");
271         if (password == null) password = "";
272         newuser.setPassword(password);
273         newuser.setClearTextPassword(false);
274         
275         try {
276             rabean.addUser(newuser);
277         } catch (Exception JavaDoc e) {
278             throw new ServletException JavaDoc("Error adding user: " + e.toString(), e);
279         }
280         
281         byte[] pkcs7;
282         try {
283             p10.setUsername(username);
284             p10.setPassword(password);
285             ISignSessionLocal ss = getSignSession();
286             IResponseMessage resp = ss.createCertificate(admin, p10, Class.forName("org.ejbca.core.protocol.X509ResponseMessage"));
287             X509Certificate JavaDoc cert = CertTools.getCertfromByteArray(resp.getResponseMessage());
288             pkcs7 = ss.createPKCS7(admin, cert, true);
289         } catch (ClassNotFoundException JavaDoc e) {
290             // Class not found
291
throw new ServletException JavaDoc(e);
292         } catch (CertificateEncodingException JavaDoc e) {
293             // Error in cert
294
throw new ServletException JavaDoc(e);
295         } catch (CertificateException JavaDoc e) {
296             // Error in cert
297
throw new ServletException JavaDoc(e);
298         } catch (NotFoundException e) {
299             // User not found
300
throw new ServletException JavaDoc(e);
301         } catch (AuthStatusException e) {
302             // Wrong user status, shouldn't really happen. The user needs to have
303
// status of NEW, FAILED or INPROCESS.
304
throw new ServletException JavaDoc(e);
305         } catch (AuthLoginException e) {
306             // Wrong username or password, hmm... wasn't the wrong username caught
307
// in the objectnotfoundexception above... and this shouldn't happen.
308
throw new ServletException JavaDoc(e);
309         } catch (IllegalKeyException e) {
310             // Malformed key (?)
311
throw new ServletException JavaDoc(e);
312         } catch (SignRequestException e) {
313             // Invalid request
314
throw new ServletException JavaDoc(e);
315         } catch (SignRequestSignatureException e) {
316             // Invalid signature in certificate request
317
throw new ServletException JavaDoc(e);
318         } catch (CADoesntExistsException e) {
319             // Reqqested CA does not exist
320
throw new ServletException JavaDoc(e);
321         }
322         
323         log.debug("Created certificate (PKCS7) for " + username);
324         
325         sendNewB64Cert(Base64.encode(pkcs7), response);
326         
327     }
328     
329     
330     public void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
331     throws IOException JavaDoc, ServletException JavaDoc
332     {
333         log.debug(">doGet()");
334         response.setHeader("Allow", "POST");
335         response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "The certificate request servlet only handles the POST method.");
336         log.debug("<doGet()");
337     } // doGet
338

339     
340     private void sendNewB64Cert(byte[] b64cert, HttpServletResponse JavaDoc out)
341     throws IOException JavaDoc
342     {
343         out.setContentType("application/octet-stream");
344         out.setHeader("Content-Disposition", "filename=cert.pem");
345         out.setContentLength(b64cert.length +
346                 BEGIN_CERT_LENGTH + END_CERT_LENGTH + (3 *NL_LENGTH));
347         
348         ServletOutputStream JavaDoc os = out.getOutputStream();
349         os.write(BEGIN_CERT);
350         os.write(NL);
351         os.write(b64cert);
352         os.write(NL);
353         os.write(END_CERT);
354         os.write(NL);
355         out.flushBuffer();
356     }
357     
358     
359     /**
360      *
361      */

362     private final static byte[] pkcs10Bytes(String JavaDoc pkcs10)
363     {
364         if (pkcs10 == null) return null;
365         byte[] reqBytes = pkcs10.getBytes();
366         byte[] bytes = null;
367         try {
368             // A real PKCS10 PEM request
369
String JavaDoc beginKey = "-----BEGIN CERTIFICATE REQUEST-----";
370             String JavaDoc endKey = "-----END CERTIFICATE REQUEST-----";
371             bytes = FileTools.getBytesFromPEM(reqBytes, beginKey, endKey);
372         } catch (IOException JavaDoc e) {
373             try {
374                 // Keytool PKCS10 PEM request
375
String JavaDoc beginKey = "-----BEGIN NEW CERTIFICATE REQUEST-----";
376                 String JavaDoc endKey = "-----END NEW CERTIFICATE REQUEST-----";
377                 bytes = FileTools.getBytesFromPEM(reqBytes, beginKey, endKey);
378             } catch (IOException JavaDoc e2) {
379                 // IE PKCS10 Base64 coded request
380
bytes = Base64.decode(reqBytes);
381             }
382         }
383         return bytes;
384     }
385     
386     
387     /**
388      *
389      */

390     private final RAInterfaceBean getRaBean(HttpServletRequest JavaDoc req)
391     throws ServletException JavaDoc
392     {
393         HttpSession JavaDoc session = req.getSession();
394         RAInterfaceBean rabean = (RAInterfaceBean) session.getAttribute("rabean");
395         if (rabean == null) {
396             try {
397                 rabean = (RAInterfaceBean) Beans.instantiate(this.getClass().getClassLoader(), "org.ejbca.ui.web.admin.rainterface.RAInterfaceBean");
398             } catch (ClassNotFoundException JavaDoc e) {
399                 throw new ServletException JavaDoc(e);
400             } catch (Exception JavaDoc e) {
401                 throw new ServletException JavaDoc("Unable to instantiate RAInterfaceBean", e);
402             }
403             try {
404                 rabean.initialize(req, getEjbcaWebBean(req));
405             } catch (Exception JavaDoc e) {
406                 throw new ServletException JavaDoc("Cannot initialize RAInterfaceBean", e);
407             }
408             session.setAttribute("rabean", rabean);
409         }
410         return rabean;
411     }
412     
413     
414     /**
415      *
416      */

417     private final EjbcaWebBean getEjbcaWebBean(HttpServletRequest JavaDoc req)
418     throws ServletException JavaDoc
419     {
420         HttpSession JavaDoc session = req.getSession();
421         EjbcaWebBean ejbcawebbean= (EjbcaWebBean)session.getAttribute("ejbcawebbean");
422         if ( ejbcawebbean == null ){
423             try {
424                 ejbcawebbean = (EjbcaWebBean) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "org.ejbca.ui.web.admin.configuration.EjbcaWebBean");
425             } catch (ClassNotFoundException JavaDoc exc) {
426                 throw new ServletException JavaDoc(exc.getMessage());
427             }catch (Exception JavaDoc exc) {
428                 throw new ServletException JavaDoc (" Cannot create bean of class "+"org.ejbca.ui.web.admin.configuration.EjbcaWebBean", exc);
429             }
430             session.setAttribute("ejbcawebbean", ejbcawebbean);
431         }
432         return ejbcawebbean;
433     }
434     /**
435      *
436      */

437     private final CAInterfaceBean getCaBean(HttpServletRequest JavaDoc req)
438     throws ServletException JavaDoc
439     {
440         HttpSession JavaDoc session = req.getSession();
441         CAInterfaceBean cabean = (CAInterfaceBean) session.getAttribute("cabean");
442         if (cabean == null) {
443             try {
444                 cabean = (CAInterfaceBean) Beans.instantiate(this.getClass().getClassLoader(), "org.ejbca.ui.web.admin.cainterface.CAInterfaceBean");
445             } catch (ClassNotFoundException JavaDoc e) {
446                 throw new ServletException JavaDoc(e);
447             } catch (Exception JavaDoc e) {
448                 throw new ServletException JavaDoc("Unable to instantiate CAInterfaceBean", e);
449             }
450             try {
451                 cabean.initialize(req, getEjbcaWebBean(req));
452             } catch (Exception JavaDoc e) {
453                 throw new ServletException JavaDoc("Cannot initialize CAInterfaceBean", e);
454             }
455             session.setAttribute("cabean", cabean);
456         }
457         return cabean;
458     }
459     
460     
461     /**
462      *
463      */

464     private final String JavaDoc checkUsername(RAInterfaceBean rabean, String JavaDoc username)
465     throws ServletException JavaDoc
466     {
467         if (username != null) username = username.trim();
468         if (username == null || username.length() == 0) {
469             throw new ServletException JavaDoc("Username must not be empty.");
470         }
471         
472         String JavaDoc msg = null;
473         try {
474             if (rabean.userExist(username)) {
475                 msg = "User '" + username + "' already exists.";
476             }
477         } catch (Exception JavaDoc e) {
478             throw new ServletException JavaDoc("Error checking username '" + username +
479                     ": " + e.toString(), e);
480         }
481         if (msg != null) {
482             throw new ServletException JavaDoc(msg);
483         }
484         
485         return username;
486     }
487     
488 }
489
Popular Tags