/** * Build a PEM string of certificates and private key. * * @param certChainStr * @param bytesPrivateKey * @return certificate chain and private key as a PEM encoded string */ private static String buildPEM(String certChainStr, byte[] bytesPrivateKey) { if (certChainStr == null || bytesPrivateKey == null) throw new RuntimeException("Cannot build PEM of cert & privateKey. An argument is null."); // locate the 2nd occurance of CERT_BEGIN string int posCertEnd = certChainStr.indexOf(X509CertificateChain.CERT_END); if (posCertEnd == -1) throw new RuntimeException("Cannot find END mark of certificate."); StringBuilder sb = new StringBuilder(); sb.append(X509CertificateChain.PRIVATE_KEY_BEGIN); sb.append(X509CertificateChain.NEW_LINE); sb.append(Base64.encodeLines64(bytesPrivateKey)); sb.append(X509CertificateChain.PRIVATE_KEY_END); String privateKeyStr = sb.toString(); int posSecondCertStart = certChainStr.indexOf(X509CertificateChain.CERT_BEGIN, posCertEnd); if (posSecondCertStart == -1) { // this is an end user certificate, number of certificates==1 return (certChainStr + X509CertificateChain.NEW_LINE + privateKeyStr); } else { // private key goes in between the first and second // certificate in the chain String certStrPart1 = certChainStr.substring(0, posSecondCertStart); String certStrPart2 = certChainStr.substring(posSecondCertStart); return (certStrPart1 + privateKeyStr + X509CertificateChain.NEW_LINE + certStrPart2); } }
static byte[] getPrivateKey(byte[] certBuf) throws IOException { BufferedReader rdr = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(certBuf))); String line = rdr.readLine(); StringBuilder base64 = new StringBuilder(); while (line != null) { if (line.startsWith("-----BEGIN RSA PRIVATE KEY-")) { // log.debug(line); line = rdr.readLine(); while (line != null && !line.startsWith("-----END RSA PRIVATE KEY-")) { // log.debug(line + " (" + line.length() + ")"); base64.append(line.trim()); line = rdr.readLine(); } // log.debug(line); line = null; // break from outer loop } else line = rdr.readLine(); } rdr.close(); String encoded = base64.toString(); // log.debug("RSA PRIVATE KEY: " + encoded); // log.debug("RSA private key: " + encoded.length() + " chars"); // now: base64 -> byte[] byte[] ret = Base64.decode(encoded); // log.debug("RSA private key: " + ret.length + " bytes"); return ret; }
/** * Extracts all the certificates from the argument, decodes them from base64 to byte[] and * concatenates all the certificates preserving the order. * * @param certBuf buffer containing certificates * @return decoded certificate chain * @throws IOException */ public static byte[] getCertificates(byte[] certBuf) throws IOException { BufferedReader rdr = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(certBuf))); String line = rdr.readLine(); List<byte[]> certs = new ArrayList<byte[]>(); // list of byte certificates int byteSize = 0; while (line != null) { StringBuilder base64 = new StringBuilder(); if (line.startsWith(X509CertificateChain.CERT_BEGIN)) { // log.debug(line); line = rdr.readLine(); while (line != null && !line.startsWith(X509CertificateChain.CERT_END)) { // log.debug(line + " (" + line.length() + ")"); base64.append(line.trim()); line = rdr.readLine(); } if (line.startsWith(X509CertificateChain.CERT_END)) { String encoded = base64.toString(); // log.debug("CERTIFICATE: " + encoded); byte[] tmp = Base64.decode(encoded); byteSize += tmp.length; certs.add(tmp); } // log.debug(line); } else line = rdr.readLine(); } rdr.close(); // flatten out the certificate bytes into one byte[] byte[] result = new byte[byteSize]; byteSize = 0; for (byte[] cert : certs) { System.arraycopy(cert, 0, result, byteSize, cert.length); byteSize += cert.length; // log.debug("CERTIFICATE: " + result); } return result; }
private void processRequest(boolean get, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String jobID = null; try { // GET: <jobID> // POST: // <jobID>/<current phase>/<new phase> // <jobID>/<current phase>/ERROR/<base64 encoded message>/<errorType> jobID = getPathToken(request, 0); if (jobID == null) throw new IllegalArgumentException("jobID not specified"); if (get) { ExecutionPhase ep = jobUpdater.getPhase(jobID); log.debug("GET: " + jobID + " " + ep.name()); response.setStatus(HttpServletResponse.SC_OK); response.setContentType("text/plain"); PrintWriter w = response.getWriter(); w.println(ep.getValue()); w.close(); return; } String phase = getPathToken(request, 1); if (phase == null) throw new IllegalArgumentException("current phase not specified"); ExecutionPhase cur = ExecutionPhase.valueOf(phase); phase = getPathToken(request, 2); if (phase == null) throw new IllegalArgumentException("new phase not specified"); ExecutionPhase end = ExecutionPhase.valueOf(phase); ErrorSummary err = null; if (ExecutionPhase.ERROR.equals(end)) { String base64 = getPathToken(request, 3); String type = getPathToken(request, 4); if (base64 != null && type != null) { String msg = Base64.decodeString(base64); ErrorType et = ErrorType.valueOf(type); err = new ErrorSummary(msg, et); } } log.debug("changing phase of " + jobID + " to " + end); ExecutionPhase result = null; if (err != null) result = jobUpdater.setPhase(jobID, cur, end, err, new Date()); else result = jobUpdater.setPhase(jobID, cur, end, new Date()); if (result == null) { ExecutionPhase actual = jobUpdater.getPhase(jobID); log.debug( "cannot change phase of " + jobID + " from " + cur + " to " + end + "(was: " + actual + ") [FAIL]"); throw new IllegalArgumentException( "cannot change phase of " + jobID + " from " + cur + " to " + end + "(was: " + actual + ")"); } log.debug("changed phase of " + jobID + " to " + end + " [OK]"); response.setStatus(HttpServletResponse.SC_OK); } catch (IllegalArgumentException ex) { // OutputStream not open, write an error response response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.setContentType("text/plain"); PrintWriter w = response.getWriter(); w.println(ex.getMessage()); w.close(); return; } catch (JobNotFoundException ex) { // OutputStream not open, write an error response response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setContentType("text/plain"); PrintWriter w = response.getWriter(); w.println("failed to find job: " + jobID); w.close(); return; } catch (TransientException ex) { if (!response.isCommitted()) { response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); response.addHeader("Retry-After", Integer.toString(ex.getRetryDelay())); response.setContentType("text/plain"); PrintWriter w = response.getWriter(); w.println("failed to persist job: " + jobID); w.println(" reason: " + ex.getMessage()); w.close(); return; } log.error("response already committed", ex); return; } catch (JobPersistenceException ex) { // OutputStream not open, write an error response response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.setContentType("text/plain"); PrintWriter w = response.getWriter(); w.println("failed to persist job: " + jobID); w.println(" reason: " + ex.getMessage()); w.close(); return; } }