1 13 14 package org.ejbca.ui.web; 15 16 import java.io.BufferedReader ; 17 import java.io.ByteArrayInputStream ; 18 import java.io.IOException ; 19 import java.io.InputStreamReader ; 20 import java.io.OutputStream ; 21 import java.io.PrintStream ; 22 import java.io.PrintWriter ; 23 import java.io.StringWriter ; 24 import java.io.UnsupportedEncodingException ; 25 import java.security.cert.X509Certificate ; 26 import java.util.regex.Pattern ; 27 28 import javax.servlet.ServletContext ; 29 import javax.servlet.ServletOutputStream ; 30 import javax.servlet.http.HttpServletRequest ; 31 import javax.servlet.http.HttpServletResponse ; 32 33 import org.apache.commons.lang.StringUtils; 34 import org.apache.log4j.Logger; 35 import org.bouncycastle.asn1.ASN1InputStream; 36 import org.bouncycastle.asn1.ASN1Sequence; 37 import org.bouncycastle.jce.netscape.NetscapeCertRequest; 38 import org.ejbca.core.ejb.ServiceLocator; 39 import org.ejbca.core.ejb.ServiceLocatorException; 40 import org.ejbca.core.ejb.ca.sign.ISignSessionLocal; 41 import org.ejbca.core.model.ca.SignRequestSignatureException; 42 import org.ejbca.core.model.log.Admin; 43 import org.ejbca.core.protocol.IResponseMessage; 44 import org.ejbca.core.protocol.PKCS10RequestMessage; 45 import org.ejbca.ui.web.pub.ServletDebug; 46 import org.ejbca.ui.web.pub.ServletUtils; 47 import org.ejbca.util.Base64; 48 import org.ejbca.util.CertTools; 49 import org.ejbca.util.FileTools; 50 51 56 public class RequestHelper { 57 private static Logger log = Logger.getLogger(RequestHelper.class); 58 private Admin administrator; 59 private ServletDebug debug; 60 private static final Pattern CLASSID = Pattern.compile("\\$CLASSID"); 61 62 public static final String BEGIN_CERTIFICATE_REQUEST = "-----BEGIN CERTIFICATE REQUEST-----"; 63 public static final String END_CERTIFICATE_REQUEST = "-----END CERTIFICATE REQUEST-----"; 64 public static final String BEGIN_CERTIFICATE_REQUEST_WITH_NL = "-----BEGIN CERTIFICATE REQUEST-----\n"; 65 public static final String END_CERTIFICATE_REQUEST_WITH_NL = "\n-----END CERTIFICATE REQUEST-----\n"; 66 67 public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----"; 68 public static final String END_CERTIFICATE = "-----END CERTIFICATE-----"; 69 public static final String BEGIN_CERTIFICATE_WITH_NL = "-----BEGIN CERTIFICATE-----\n"; 70 public static final String END_CERTIFICATE_WITH_NL = "\n-----END CERTIFICATE-----\n"; 71 public static final String BEGIN_CRL_WITH_NL = "-----BEGIN X509 CRL-----\n"; 72 public static final String END_CRL_WITH_NL = "\n-----END X509 CRL-----\n"; 73 74 public static final String BEGIN_PKCS7 = "-----BEGIN PKCS7-----\n"; 75 public static final String END_PKCS7 = "\n-----END PKCS7-----\n"; 76 public static final String BEGIN_PKCS7_WITH_NL = "-----BEGIN PKCS7-----\n"; 77 public static final String END_PKCS7_WITH_NL = "\n-----END PKCS7-----\n"; 78 79 public static final int ENCODED_CERTIFICATE = 1; 80 public static final int ENCODED_PKCS7 = 2; 81 82 88 public RequestHelper(Admin administrator, ServletDebug debug) { 89 this.administrator = administrator; 90 this.debug = debug; 91 } 92 93 106 public byte[] nsCertRequest(ISignSessionLocal signsession, byte[] reqBytes, String username, 107 String password) throws Exception { 108 byte[] buffer = Base64.decode(reqBytes); 109 110 if (buffer == null) { 111 return null; 112 } 113 114 ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream (buffer)); 115 ASN1Sequence spkac = (ASN1Sequence) in.readObject(); 116 in.close(); 117 118 NetscapeCertRequest nscr = new NetscapeCertRequest(spkac); 119 120 nscr.setChallenge("challenge"); 122 123 if (nscr.verify("challenge") == false) { 124 throw new SignRequestSignatureException( 125 "Invalid signature in NetscapeCertRequest, popo-verification failed."); 126 } 127 128 log.debug("POPO verification successful"); 129 130 X509Certificate cert = (X509Certificate ) signsession.createCertificate(administrator, 131 username, password, nscr.getPublicKey()); 132 133 byte[] pkcs7 = signsession.createPKCS7(administrator, cert, false); 135 log.debug("Created certificate (PKCS7) for " + username); 136 debug.print("<h4>Generated certificate:</h4>"); 137 debug.printInsertLineBreaks(cert.toString().getBytes()); 138 139 return pkcs7; 140 } 142 161 public byte[] pkcs10CertRequest(ISignSessionLocal signsession, byte[] b64Encoded, 162 String username, String password, int resulttype, boolean doSplitLines) throws Exception { 163 byte[] result = null; 164 X509Certificate cert=null; 165 PKCS10RequestMessage req = genPKCS10RequestMessageFromPEM(b64Encoded); 166 req.setUsername(username); 167 req.setPassword(password); 168 IResponseMessage resp = signsession.createCertificate(administrator,req,Class.forName("org.ejbca.core.protocol.X509ResponseMessage")); 169 cert = CertTools.getCertfromByteArray(resp.getResponseMessage()); 170 if(resulttype == ENCODED_CERTIFICATE) 171 result = cert.getEncoded(); 172 else 173 result = signsession.createPKCS7(administrator, cert, true); 174 log.debug("Created certificate (PKCS7) for " + username); 175 debug.print("<h4>Generated certificate:</h4>"); 176 debug.printInsertLineBreaks(cert.toString().getBytes()); 177 return Base64.encode(result, doSplitLines); 178 } 180 190 public byte[] pkcs10CertRequest(ISignSessionLocal signsession, byte[] b64Encoded, 191 String username, String password, int resulttype) throws Exception { 192 return pkcs10CertRequest(signsession, b64Encoded, username, password, resulttype, true); 193 } 194 195 201 public static void ieCertFormat(byte[] bA, PrintStream out) 202 throws Exception { 203 BufferedReader br = new BufferedReader (new InputStreamReader (new ByteArrayInputStream (bA))); 204 int rowNr = 0; 205 206 while (true) { 207 String line = br.readLine(); 208 209 if (line == null) { 210 break; 211 } 212 213 if (line.indexOf("END CERT") < 0) { 214 if (line.indexOf(" CERT") < 0) { 215 if (++rowNr > 1) { 216 out.println(" & _ "); 217 } else { 218 out.print(" cert = "); 219 } 220 221 out.print('\"' + line + '\"'); 222 } 223 } else { 224 break; 225 } 226 } 227 228 out.println(); 229 } 231 238 public static void sendNewCertToIidClient(byte[] certificate, OutputStream out, ServletContext sc, 239 String responseTemplate, String classid) throws Exception { 240 if (certificate.length <= 0) { 241 log.error("0 length certificate can not be sent to client!"); 242 return; 243 } 244 StringWriter sw = new StringWriter (); 245 { 246 BufferedReader br = new BufferedReader (new InputStreamReader (sc.getResourceAsStream(responseTemplate))); 247 PrintWriter pw = new PrintWriter (sw); 248 while (true) { 249 String line = br.readLine(); 250 if (line == null) 251 break; 252 line = line.replaceAll("TAG_cert",new String (certificate)); 253 line = CLASSID.matcher(line).replaceFirst(classid); 254 pw.println(line); 255 } 256 pw.close(); 257 sw.flush(); 258 } 259 { 260 PrintWriter pw = new PrintWriter (out); 261 log.debug(sw); 262 pw.print(sw); 263 pw.close(); 264 out.flush(); 265 } 266 } 278 public static void sendNewCertToIEClient(byte[] b64cert, OutputStream out, ServletContext sc, 279 String responseTemplate, String classid) throws Exception { 280 if (b64cert.length == 0) { 281 log.error("0 length certificate can not be sent to IE client!"); 282 return; 283 } 284 285 PrintStream ps = new PrintStream (out); 286 BufferedReader br = new BufferedReader (new InputStreamReader (sc.getResourceAsStream( 287 responseTemplate))); 288 289 while (true) { 290 String line = br.readLine(); 291 292 if (line == null) { 293 break; 294 } 295 296 if (line.indexOf("cert =") < 0) { 297 ps.println(CLASSID.matcher(line).replaceFirst(classid)); 298 } else { 299 RequestHelper.ieCertFormat(b64cert, ps); 300 } 301 } 302 303 ps.close(); 304 log.debug("Sent reply to IE client"); 305 log.debug(new String (b64cert)); 306 } 308 316 public static void sendNewCertToNSClient(byte[] certs, HttpServletResponse out) 317 throws Exception { 318 if (certs.length == 0) { 319 log.error("0 length certificate can not be sent to NS client!"); 320 return; 321 } 322 323 out.setContentType("application/x-x509-user-cert"); 325 out.setContentLength(certs.length); 326 327 out.getOutputStream().write(certs); 329 log.debug("Sent reply to NS client"); 330 log.debug(new String (Base64.encode(certs))); 331 } 333 344 public static void sendNewB64File(byte[] b64cert, HttpServletResponse out, String filename, String beginKey, String endKey) 345 throws IOException { 346 if (b64cert.length == 0) { 347 log.error("0 length certificate can not be sent to client!"); 348 return; 349 } 350 351 ServletUtils.removeCacheHeaders(out); 353 354 out.setContentType("application/octet-stream"); 356 out.setHeader("Content-disposition", "filename=\""+filename+"\""); 357 358 out.setContentLength(b64cert.length + beginKey.length() + endKey.length()); 359 360 ServletOutputStream os = out.getOutputStream(); 362 os.write(beginKey.getBytes()); 363 os.write(b64cert); 364 os.write(endKey.getBytes()); 365 out.flushBuffer(); 366 log.debug("Sent reply to client"); 367 log.debug(new String (b64cert)); 368 } 369 378 public static void sendNewB64Cert(byte[] b64cert, HttpServletResponse out, String beginKey, String endKey) 379 throws IOException { 380 RequestHelper.sendNewB64File(b64cert, out, "cert.pem", beginKey, endKey); 381 } 383 391 public static void sendNewX509CaCert(byte[] cert, HttpServletResponse out) 392 throws Exception { 393 sendBinaryBytes(cert, out, "application/x-x509-ca-cert", null); 395 } 397 407 public static void sendBinaryBytes(byte[] bytes, HttpServletResponse out, String contentType, String filename) 408 throws Exception { 409 if ( (bytes == null) || (bytes.length == 0) ) { 410 log.error("0 length can not be sent to client!"); 411 return; 412 } 413 414 if (filename != null) { 415 ServletUtils.removeCacheHeaders(out); 417 out.setHeader("Content-disposition", "filename=\""+filename+"\""); 418 } 419 420 out.setContentType(contentType); 422 out.setContentLength(bytes.length); 423 424 ServletOutputStream os = out.getOutputStream(); 426 os.write(bytes); 427 out.flushBuffer(); 428 log.debug("Sent " + bytes.length + " bytes to client"); 429 } 431 public static PKCS10RequestMessage genPKCS10RequestMessageFromPEM(byte[] b64Encoded){ 432 byte[] buffer = null; 433 try { 434 String beginKey = BEGIN_CERTIFICATE_REQUEST; 436 String endKey = END_CERTIFICATE_REQUEST; 437 buffer = FileTools.getBytesFromPEM(b64Encoded, beginKey, endKey); 438 } catch (IOException e) { 439 try { 440 String beginKey = "-----BEGIN NEW CERTIFICATE REQUEST-----"; 442 String endKey = "-----END NEW CERTIFICATE REQUEST-----"; 443 buffer = FileTools.getBytesFromPEM(b64Encoded, beginKey, endKey); 444 } catch (IOException ioe) { 445 buffer = Base64.decode(b64Encoded); 447 } 448 } 449 if (buffer == null) { 450 return null; 451 } 452 return new PKCS10RequestMessage(buffer); 453 } 455 459 public static String getDefaultContentEncoding() { 460 String ret = null; 461 try { 462 ret = ServiceLocator.getInstance().getString("java:comp/env/contentEncoding"); 463 } catch (ServiceLocatorException e) { 464 log.debug("Can not find any default content encoding, using hard default ISO-8859-1."); 465 ret = "ISO-8859-1"; 466 } 467 if (ret == null) { 468 log.debug("Can not find any default content encoding, using hard default ISO-8859-1."); 469 ret = "ISO-8859-1"; 470 } 471 return ret; 472 } 473 474 482 public static void setDefaultCharacterEncoding(HttpServletRequest request) throws UnsupportedEncodingException { 483 String encoding = request.getCharacterEncoding(); 484 if(StringUtils.isEmpty(encoding)) { 485 encoding = RequestHelper.getDefaultContentEncoding(); 486 log.debug("Setting encoding to default value: "+encoding); 487 request.setCharacterEncoding(encoding); 488 } else { 489 log.debug("Setting encoding to value from request: "+encoding); 490 request.setCharacterEncoding(encoding); 491 } 492 } 493 494 } 495 | Popular Tags |