1 13 14 package org.ejbca.ui.web.pub; 15 16 import java.io.BufferedReader ; 17 import java.io.IOException ; 18 import java.io.InputStreamReader ; 19 import java.io.OutputStream ; 20 import java.io.PrintWriter ; 21 import java.io.StringWriter ; 22 import java.rmi.RemoteException ; 23 import java.security.cert.X509Certificate ; 24 import java.util.Enumeration ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.Set ; 28 29 import javax.ejb.CreateException ; 30 import javax.ejb.ObjectNotFoundException ; 31 import javax.naming.InitialContext ; 32 import javax.rmi.PortableRemoteObject ; 33 import javax.servlet.ServletConfig ; 34 import javax.servlet.ServletContext ; 35 import javax.servlet.ServletException ; 36 import javax.servlet.http.HttpServlet ; 37 import javax.servlet.http.HttpServletRequest ; 38 import javax.servlet.http.HttpServletResponse ; 39 40 import org.apache.log4j.Logger; 41 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionHome; 42 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionRemote; 43 import org.ejbca.core.ejb.ca.sign.ISignSessionHome; 44 import org.ejbca.core.ejb.ca.sign.ISignSessionRemote; 45 import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionHome; 46 import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionRemote; 47 import org.ejbca.core.ejb.hardtoken.IHardTokenSessionHome; 48 import org.ejbca.core.ejb.ra.IUserAdminSessionHome; 49 import org.ejbca.core.ejb.ra.IUserAdminSessionRemote; 50 import org.ejbca.core.model.SecConst; 51 import org.ejbca.core.model.ca.AuthLoginException; 52 import org.ejbca.core.model.ca.AuthStatusException; 53 import org.ejbca.core.model.ca.IllegalKeyException; 54 import org.ejbca.core.model.ca.SignRequestException; 55 import org.ejbca.core.model.ca.SignRequestSignatureException; 56 import org.ejbca.core.model.ca.caadmin.CAInfo; 57 import org.ejbca.core.model.ca.crl.RevokedCertInfo; 58 import org.ejbca.core.model.hardtoken.profiles.EIDProfile; 59 import org.ejbca.core.model.hardtoken.profiles.HardTokenProfile; 60 import org.ejbca.core.model.hardtoken.profiles.SwedishEIDProfile; 61 import org.ejbca.core.model.log.Admin; 62 import org.ejbca.core.model.ra.UserDataConstants; 63 import org.ejbca.core.model.ra.UserDataVO; 64 import org.ejbca.core.protocol.IResponseMessage; 65 import org.ejbca.core.protocol.PKCS10RequestMessage; 66 import org.ejbca.ui.web.RequestHelper; 67 import org.ejbca.util.Base64; 68 import org.ejbca.util.CertTools; 69 70 71 95 public class CardCertReqServlet extends HttpServlet { 96 private final static Logger log = Logger.getLogger(CardCertReqServlet.class); 97 private ISignSessionHome signsessionhome = null; 98 private IUserAdminSessionHome useradminhome = null; 99 private ICertificateStoreSessionHome certificatestorehome = null; 100 private ICAAdminSessionHome caadminsessionhome = null; 101 private IHardTokenSessionHome tokenSessionHome = null; 102 103 110 public void init(ServletConfig config) throws ServletException { 111 super.init(config); 112 113 try { 114 CertTools.installBCProvider(); 116 117 InitialContext ctx = new InitialContext (); 119 signsessionhome = (ISignSessionHome) PortableRemoteObject.narrow( 120 ctx.lookup("RSASignSession"), ISignSessionHome.class ); 121 useradminhome = (IUserAdminSessionHome) PortableRemoteObject.narrow( 122 ctx.lookup("UserAdminSession"), IUserAdminSessionHome.class ); 123 certificatestorehome = (ICertificateStoreSessionHome) PortableRemoteObject.narrow( 124 ctx.lookup("CertificateStoreSession"), ICertificateStoreSessionHome.class ); 125 caadminsessionhome = (ICAAdminSessionHome) javax.rmi.PortableRemoteObject.narrow(ctx.lookup("CAAdminSession"), 126 ICAAdminSessionHome.class); 127 tokenSessionHome = (IHardTokenSessionHome)javax.rmi.PortableRemoteObject.narrow(ctx.lookup("HardTokenSession"), 128 IHardTokenSessionHome.class); 129 } catch( Exception e ) { 130 throw new ServletException (e); 131 } 132 } 133 134 143 public void doPost(HttpServletRequest request, HttpServletResponse response) 144 throws IOException , ServletException { 145 final ServletDebug debug = new ServletDebug(request, response); 146 boolean usekeyrecovery = false; 147 try { 148 Admin administrator = new Admin(Admin.TYPE_RA_USER); 149 ICertificateStoreSessionRemote certificatestoresession = certificatestorehome.create(); 150 final String username; { 151 Object o = request.getAttribute("javax.servlet.request.X509Certificate"); 152 final X509Certificate [] certs; 153 if ( o!=null && o instanceof X509Certificate [] ) 154 certs = (X509Certificate [])o; 155 else 156 throw new AuthLoginException("No authenicating certificate"); 157 RevokedCertInfo rci=certificatestoresession.isRevoked(administrator, certs[0].getIssuerDN().getName(), 158 certs[0].getSerialNumber()); 159 if ( rci==null || rci.getReason()!=RevokedCertInfo.NOT_REVOKED ) 160 throw new UserCertificateRevokedException(certs[0]); 161 username = certificatestoresession.findUsernameByCertSerno(administrator, 162 certs[0].getSerialNumber(), certs[0].getIssuerX500Principal().toString()); 163 if ( username==null || username.length()==0 ) 164 throw new ObjectNotFoundException ("Not possible to retrieve user name"); 165 } 166 IUserAdminSessionRemote adminsession = useradminhome.create(); 167 ISignSessionRemote signsession = signsessionhome.create(); 168 log.debug("Got request for " + username + "."); 169 debug.print("<h3>username: " + username + "</h3>"); 170 171 final UserDataVO data = adminsession.findUser(administrator, username); 172 final X509Certificate notRevokedCerts[]; { 173 Set set = new HashSet (); 174 for( Iterator i = certificatestoresession.findCertificatesByUsername(administrator, username).iterator(); i.hasNext(); ) { 175 Object o = i.next(); 176 if ( o instanceof X509Certificate ) { 177 X509Certificate cert = (X509Certificate )o; 178 RevokedCertInfo rci=certificatestoresession.isRevoked(administrator, cert.getIssuerDN().getName(), cert.getSerialNumber()); 179 if ( rci!=null && rci.getReason()==RevokedCertInfo.NOT_REVOKED ) 180 set.add(cert); 181 } 182 } 183 notRevokedCerts = (X509Certificate [])set.toArray(new X509Certificate [0]); 184 } 185 if (data == null) 186 throw new ObjectNotFoundException (); 187 188 final String authReq = request.getParameter("authpkcs10"); 189 final String signReq = request.getParameter("signpkcs10"); 190 191 if ( authReq!=null && signReq!=null ) { 192 final int authCertProfile; 193 final int signCertProfile; 194 final HardTokenProfile hardTokenProfile = tokenSessionHome.create().getHardTokenProfile(administrator, data.getTokenType()); 195 { 196 CertProfileID certProfileID = new CertProfileID(certificatestoresession, data, administrator, 197 hardTokenProfile); 198 authCertProfile = certProfileID.getProfileID("authCertProfile", SwedishEIDProfile.CERTUSAGE_AUTHENC); 199 signCertProfile = certProfileID.getProfileID("signCertProfile", SwedishEIDProfile.CERTUSAGE_SIGN); 200 } 201 final int authCA; 202 final int signCA; 203 { 204 CAID caid = new CAID(data,administrator, hardTokenProfile); 205 authCA = caid.getProfileID("authCA", SwedishEIDProfile.CERTUSAGE_AUTHENC); 206 signCA = caid.getProfileID("signCA", SwedishEIDProfile.CERTUSAGE_SIGN); 207 } 208 final byte[] authReqBytes = authReq.getBytes(); 210 final byte[] signReqBytes = signReq.getBytes(); 211 if ( authReqBytes!=null && signReqBytes!=null) { 212 try { 213 adminsession.changeUser(administrator, username,data.getPassword(), data.getDN(), data.getSubjectAltName(), 214 data.getEmail(), true, data.getEndEntityProfileId(), authCertProfile, data.getType(), 215 SecConst.TOKEN_SOFT_BROWSERGEN, 0, data.getStatus(), authCA); 216 final byte[] authb64cert=pkcs10CertRequest(administrator, signsession, authReqBytes, username, data.getPassword()); 217 218 adminsession.changeUser(administrator, username, data.getPassword(), data.getDN(), data.getSubjectAltName(), 219 data.getEmail(), true, data.getEndEntityProfileId(), signCertProfile, data.getType(), 220 SecConst.TOKEN_SOFT_BROWSERGEN, 0, UserDataConstants.STATUS_NEW, signCA); 221 final byte[] signb64cert=pkcs10CertRequest(administrator, signsession, signReqBytes, username, data.getPassword()); 222 223 224 for (int i=0; i<notRevokedCerts.length; i++) 225 adminsession.revokeCert(administrator, notRevokedCerts[i].getSerialNumber(), 226 notRevokedCerts[i].getIssuerDN().toString(), username, 227 RevokedCertInfo.REVOKATION_REASON_SUPERSEDED); 228 229 sendCertificates(authb64cert, signb64cert, response, getServletContext(), 230 getInitParameter("responseTemplate"), notRevokedCerts); 231 } catch( Throwable t ) { 232 if (t instanceof Exception ) 233 throw (Exception )t; 234 else 235 throw new Error (t); 236 } finally { 237 data.setStatus(UserDataConstants.STATUS_GENERATED); 238 adminsession.changeUser(administrator, data, true); } 240 } 241 } 242 } catch( UserCertificateRevokedException e) { 243 log.error("An error revoking certificaates occured: ", e); 244 debug.printMessage(e.getMessage()); 245 debug.printDebugInfo(); 246 return; 247 } catch (ObjectNotFoundException oe) { 248 log.error("Non existent username!", oe); 249 debug.printMessage("Non existent username!"); 250 debug.printDebugInfo(); 251 return; 252 } catch (AuthStatusException ase) { 253 log.error("Wrong user status!", ase); 254 debug.printMessage("Wrong user status!"); 255 if (usekeyrecovery) { 256 debug.printMessage( 257 "To generate a certificate for a user the user must have status new, failed or inprocess."); 258 } else { 259 debug.printMessage( 260 "To generate a certificate for a user the user must have status new, failed or inprocess."); 261 } 262 debug.printDebugInfo(); 263 return; 264 } catch (AuthLoginException ale) { 265 log.error("Wrong password for user!", ale); 266 debug.printMessage("Wrong username or password!"); 267 debug.printDebugInfo(); 268 return; 269 } catch (SignRequestException re) { 270 log.error("Invalid request!", re); 271 debug.printMessage("Invalid request!"); 272 debug.printMessage("Please supply a correct request."); 273 debug.printDebugInfo(); 274 return; 275 } catch (SignRequestSignatureException se) { 276 log.error("Invalid signature on certificate request!", se); 277 debug.printMessage("Invalid signature on certificate request!"); 278 debug.printMessage("Please supply a correctly signed request."); 279 debug.printDebugInfo(); 280 return; 281 } catch (java.lang.ArrayIndexOutOfBoundsException ae) { 282 log.error("Empty or invalid request received.", ae); 283 debug.printMessage("Empty or invalid request!"); 284 debug.printMessage("Please supply a correct request."); 285 debug.printDebugInfo(); 286 return; 287 } catch (IllegalKeyException e) { 288 log.error("Illegal Key received: ", e); 289 debug.printMessage("Invalid Key in request: "+e.getMessage()); 290 debug.printMessage("Please supply a correct request."); 291 debug.printDebugInfo(); 292 return; 293 } catch (Exception e) { 294 log.error("Exception occured: ", e); 295 debug.print("<h3>parameter name and values: </h3>"); 296 Enumeration paramNames = request.getParameterNames(); 297 while (paramNames.hasMoreElements()) { 298 String name = paramNames.nextElement().toString(); 299 String parameter = request.getParameter(name); 300 debug.print("<h4>" + name + ":</h4>" + parameter + "<br>"); 301 } 302 debug.takeCareOfException(e); 303 debug.printDebugInfo(); 304 } 305 } 307 private class UserCertificateRevokedException extends Exception { 308 UserCertificateRevokedException(X509Certificate cert) { 309 super("User certificate with serial number "+cert.getSerialNumber() + 310 " from issuer \'"+cert.getIssuerX500Principal()+"\' is revoked."); 311 } 312 } 313 private class CAID extends BaseID { 314 final private ICAAdminSessionRemote caadminsession; 315 CAID(UserDataVO d, Admin a, HardTokenProfile hardTokenProfile) throws RemoteException , CreateException { 316 super(d, a, hardTokenProfile); 317 caadminsession = caadminsessionhome.create(); 318 } 319 protected int getFromName(String name) throws RemoteException { 320 CAInfo caInfo = caadminsession.getCAInfo(administrator, name); 321 if ( caInfo!=null ) 322 return caInfo.getCAId(); 323 else 324 return 0; 325 } 326 protected int getFromOldData() { 327 return data.getCAId(); 328 } 329 protected int getFromHardToken(int keyType) { 330 final int id = hardTokenProfile.getCAId(keyType); 331 if ( id!=EIDProfile.CAID_USEUSERDEFINED ) 332 return id; 333 else 334 return data.getCAId(); 335 } 336 } 337 private class CertProfileID extends BaseID { 338 final ICertificateStoreSessionRemote certificatestoresession; 339 CertProfileID(ICertificateStoreSessionRemote c, UserDataVO d, Admin a, 340 HardTokenProfile hardTokenProfile) throws RemoteException , CreateException { 341 super(d, a, hardTokenProfile); 342 certificatestoresession = c; 343 } 344 protected int getFromName(String name) throws RemoteException { 345 return certificatestoresession.getCertificateProfileId(administrator, name); 346 } 347 protected int getFromOldData() { 348 return data.getCertificateProfileId(); 349 } 350 protected int getFromHardToken(int keyType) { 351 return hardTokenProfile.getCertificateProfileId(keyType); 352 } 353 } 354 private abstract class BaseID { 355 final UserDataVO data; 356 final Admin administrator; 357 final EIDProfile hardTokenProfile; 358 359 protected abstract int getFromHardToken(int keyType); 360 protected abstract int getFromName(String name) throws RemoteException ; 361 protected abstract int getFromOldData(); 362 BaseID(UserDataVO d, Admin a, HardTokenProfile htp) { 363 data = d; 364 administrator = a; 365 if ( htp!=null && htp instanceof EIDProfile ) 366 hardTokenProfile = (EIDProfile)htp; 367 else 368 hardTokenProfile = null; 369 } 370 public int getProfileID(String parameterName, int keyType) throws RemoteException { 371 if ( hardTokenProfile!=null ) 372 return getFromHardToken(keyType); 373 String name = CardCertReqServlet.this.getInitParameter(parameterName); 374 if ( name!=null && name.length()>0 ) { 375 final int id = getFromName(name); 376 log.debug("parameter name "+parameterName+" has ID "+id); 377 if (id!=0) 378 return id; 379 } 380 return getFromOldData(); 381 } 382 } 383 392 public void doGet(HttpServletRequest request, HttpServletResponse response) 393 throws IOException , ServletException { 394 log.debug(">doGet()"); 395 response.setHeader("Allow", "POST"); 396 397 ServletDebug debug = new ServletDebug(request, response); 398 debug.print("The certificate request servlet only handles POST method."); 399 debug.printDebugInfo(); 400 log.debug("<doGet()"); 401 } 402 403 405 406 418 private static void sendCertificates(byte[] authb64cert,byte[] signb64cert, HttpServletResponse response, ServletContext sc, 419 String responseTemplate, X509Certificate [] notRevokedCerts) throws Exception { 420 if (authb64cert.length == 0 || signb64cert.length == 0) { 421 log.error("0 length certificate can not be sent to client!"); 422 return; 423 } 424 StringWriter sw = new StringWriter (); 425 { 426 BufferedReader br = new BufferedReader (new InputStreamReader (sc.getResourceAsStream(responseTemplate))); 427 PrintWriter pw = new PrintWriter (sw); 428 while (true) { 429 String line = br.readLine(); 430 if (line == null) 431 break; 432 line = line.replaceAll("TAG_authb64cert",new String (authb64cert)); 433 line = line.replaceAll("TAG_signb64cert",new String (signb64cert)); 434 if ( notRevokedCerts.length > 0 ) 435 line = line.replaceAll("TAG_certToRemove1",new String (Base64.encode(notRevokedCerts[0].getEncoded(),false))); 436 if ( notRevokedCerts.length > 1 ) 437 line = line.replaceAll("TAG_certToRemove2",new String (Base64.encode(notRevokedCerts[1].getEncoded(),false))); 438 if ( notRevokedCerts.length > 2 ) 439 line = line.replaceAll("TAG_certToRemove3",new String (Base64.encode(notRevokedCerts[2].getEncoded(),false))); 440 if ( notRevokedCerts.length > 3 ) 441 line = line.replaceAll("TAG_certToRemove4",new String (Base64.encode(notRevokedCerts[3].getEncoded(),false))); 442 pw.println(line); 443 } 444 pw.close(); 445 sw.flush(); 446 } 447 { 448 OutputStream out = response.getOutputStream(); 449 PrintWriter pw = new PrintWriter (out); 450 log.debug(sw); 451 pw.print(sw); 452 pw.close(); 453 out.flush(); 454 } 455 } 457 475 private byte[] pkcs10CertRequest(Admin administrator, ISignSessionRemote signsession, byte[] b64Encoded, 476 String username, String password) throws Exception { 477 byte[] result = null; 478 X509Certificate cert=null; 479 PKCS10RequestMessage req = RequestHelper.genPKCS10RequestMessageFromPEM(b64Encoded); 480 req.setUsername(username); 481 req.setPassword(password); 482 IResponseMessage resp = signsession.createCertificate(administrator,req,Class.forName("org.ejbca.core.protocol.X509ResponseMessage")); 483 cert = CertTools.getCertfromByteArray(resp.getResponseMessage()); 484 result = cert.getEncoded(); 485 486 return Base64.encode(result, false); 487 } } 489 490 491 | Popular Tags |