/** * Copyright © 2013 enioka. All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.enioka.jqm.pki; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.StringReader; import java.security.KeyFactory; import java.security.spec.PKCS8EncodedKeySpec; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.util.io.pem.PemReader; import com.enioka.jqm.jdbc.DbConn; import com.enioka.jqm.jdbc.NoResultException; import com.enioka.jqm.model.GlobalParameter; import com.enioka.jqm.model.PKI; /** * This class is the link between the X509 methods in CertificateRequest and the database store. * */ public class JdbcCa { public static CertificateRequest initCa(DbConn cnx) { // result field CertificateRequest cr = new CertificateRequest(); // Get the alias of the private key to use String caAlias = null; caAlias = GlobalParameter.getParameter(cnx, "keyAlias", Constants.CA_DEFAULT_PRETTY_NAME); // Create the CA if it does not already exist PKI pki = null; try { pki = PKI.select_key(cnx, caAlias); } catch (NoResultException e) { // Create the CA certificate and PK cr = new CertificateRequest(); cr.generateCA(caAlias); // Store PKI.create(cnx, caAlias, cr.writePemPrivateToString(), cr.writePemPublicToString()); cnx.commit(); pki = PKI.select_key(cnx, caAlias); } try { // Public (X509 certificate) String pemCert = pki.getPemCert(); StringReader sr = new StringReader(pemCert); PemReader pr = new PemReader(sr); cr.holder = new X509CertificateHolder(pr.readPemObject().getContent()); pr.close(); // Private key String pemPrivate = pki.getPemPK(); sr = new StringReader(pemPrivate); PEMParser pp = new PEMParser(sr); PEMKeyPair caKeyPair = (PEMKeyPair) pp.readObject(); pp.close(); byte[] encodedPrivateKey = caKeyPair.getPrivateKeyInfo().getEncoded(); KeyFactory keyFactory = KeyFactory.getInstance(Constants.KEY_ALGORITHM); PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey); cr.privateKey = keyFactory.generatePrivate(privateKeySpec); } catch (Exception e) { throw new PkiException(e); } // Done return cr; } public static void prepareWebServerStores(DbConn cnx, String subject, String serverPfxPath, String trustPfxPath, String pfxPassword, String serverCertPrettyName, String serverCerPath, String caCerPath) { File pfx = new File(serverPfxPath); if (pfx.canRead()) { return; } CertificateRequest ca = initCa(cnx); ca.writePemPublicToFile(caCerPath); CertificateRequest srv = new CertificateRequest(); srv.generateServerCert(serverCertPrettyName, ca.holder, ca.privateKey, subject); try { FileOutputStream pfxStore = new FileOutputStream(serverPfxPath); srv.writePfxToFile(pfxStore, pfxPassword); pfxStore.close(); } catch (Exception e) { throw new PkiException(e); } srv.writePemPublicToFile(serverCerPath); srv.writeTrustPfxToFile(trustPfxPath, pfxPassword); } public static void prepareClientStore(DbConn cnx, String subject, String pfxPath, String pfxPassword, String prettyName, String cerPath) { File pfx = new File(pfxPath); if (pfx.canRead()) { return; } CertificateRequest ca = initCa(cnx); CertificateRequest srv = new CertificateRequest(); srv.generateClientCert(prettyName, ca.holder, ca.privateKey, subject); try { FileOutputStream pfxStore = new FileOutputStream(pfxPath); srv.writePfxToFile(pfxStore, pfxPassword); pfxStore.close(); } catch (Exception e) { throw new PkiException(e); } srv.writePemPublicToFile(cerPath); } public static InputStream getClientData(DbConn cnx, String userName) throws Exception { ByteArrayOutputStream sink = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(sink); CertificateRequest ca = JdbcCa.initCa(cnx); CertificateRequest cl = new CertificateRequest(); cl.generateClientCert("JQM authentication certificate", ca.holder, ca.privateKey, "CN=" + userName); zos.putNextEntry(new ZipEntry("ca.cer")); zos.write(((ByteArrayOutputStream) ca.getPemPublicFile()).toByteArray()); zos.closeEntry(); zos.putNextEntry(new ZipEntry("client.cer")); zos.write(((ByteArrayOutputStream) cl.getPemPublicFile()).toByteArray()); zos.closeEntry(); zos.putNextEntry(new ZipEntry("client.pfx")); ByteArrayOutputStream os = new ByteArrayOutputStream(); cl.writePfxToFile(os, "SuperPassword"); zos.write(os.toByteArray()); zos.closeEntry(); zos.close(); return new ByteArrayInputStream(sink.toByteArray()); } }