/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ package de.cismet.cids.server.ws; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; /** * DOCUMENT ME! * * @author martin.scholl@cismet.de * @version $Revision$, $Date$ */ public final class SSLConfigFactory { //~ Constructors ----------------------------------------------------------- /** * Creates a new SSLConfigFactory object. */ private SSLConfigFactory() { } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public static SSLConfigFactory getDefault() { return LazyInitialiser.INSTANCE; } /** * DOCUMENT ME! * * @param serverCertificatePath DOCUMENT ME! * @param clientKeystorePath DOCUMENT ME! * @param clientKeystorePW DOCUMENT ME! * @param clientKeyPW DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SSLConfigFactoryException DOCUMENT ME! */ public SSLConfig createClientConfig(final String serverCertificatePath, final String clientKeystorePath, final char[] clientKeystorePW, final char[] clientKeyPW) throws SSLConfigFactoryException { final Certificate serverCert = createCertificateFromFile(new File(serverCertificatePath), SSLConfig.CERTIFICATE_TYPE_X509); final KeyStore serverKeystore = createKeystoreFromFile(null, null, SSLConfig.KEYSTORE_TYPE_JAVA); try { serverKeystore.setCertificateEntry("cids-server-jetty", serverCert); // NOI18N } catch (final KeyStoreException ex) { throw new SSLConfigFactoryException("cannot add server certificate to keystore", ex); // NOI18N } final KeyStore clientKeystore = createKeystoreFromFile(new File(clientKeystorePath), clientKeystorePW, SSLConfig.KEYSTORE_TYPE_JAVA); return new SSLConfigImpl(serverKeystore, clientKeystore, null, clientKeyPW); } /** * DOCUMENT ME! * * @param serverCertIS DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SSLConfigFactoryException DOCUMENT ME! */ public SSLConfig createClientConfig(final InputStream serverCertIS) throws SSLConfigFactoryException { final Certificate serverCert = createCertificateFromStream(serverCertIS, SSLConfig.CERTIFICATE_TYPE_X509); final KeyStore serverKeystore = createKeystoreFromFile(null, null, SSLConfig.KEYSTORE_TYPE_JAVA); try { serverKeystore.setCertificateEntry("cids-server-jetty", serverCert); // NOI18N } catch (final KeyStoreException ex) { throw new SSLConfigFactoryException("cannot add server certificate to keystore", ex); // NOI18N } return new SSLConfigImpl(serverKeystore, null, null, null); } /** * DOCUMENT ME! * * @param certFile DOCUMENT ME! * @param certType DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SSLConfigFactoryException DOCUMENT ME! */ public Certificate createCertificateFromFile(final File certFile, final String certType) throws SSLConfigFactoryException { try { return createCertificateFromStream(new BufferedInputStream(new FileInputStream(certFile)), certType); } catch (final FileNotFoundException ex) { throw new SSLConfigFactoryException("cannot read certificate file: " + certFile, ex); // NOI18N } } /** * DOCUMENT ME! * * @param is DOCUMENT ME! * @param certType DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SSLConfigFactoryException DOCUMENT ME! */ public Certificate createCertificateFromStream(final InputStream is, final String certType) throws SSLConfigFactoryException { try { final CertificateFactory cf = CertificateFactory.getInstance(certType); return cf.generateCertificate(is); } catch (final CertificateException ex) { throw new SSLConfigFactoryException("illegal certificate file", ex); // NOI18N } } /** * DOCUMENT ME! * * @param keystoreFile DOCUMENT ME! * @param keystorePW DOCUMENT ME! * @param keystoreType DOCUMENT ME! * * @return DOCUMENT ME! * * @throws SSLConfigFactoryException DOCUMENT ME! */ public KeyStore createKeystoreFromFile(final File keystoreFile, final char[] keystorePW, final String keystoreType) throws SSLConfigFactoryException { try { final KeyStore keystore = KeyStore.getInstance(keystoreType); if (keystoreFile == null) { keystore.load(null, null); } else { keystore.load(new BufferedInputStream(new FileInputStream(keystoreFile)), keystorePW); } return keystore; } catch (final KeyStoreException ex) { throw new SSLConfigFactoryException("unsupported keystore type: " + keystoreType, ex); // NOI18N } catch (final IOException ex) { throw new SSLConfigFactoryException("cannot read keystore file: " + keystoreFile, ex); // NOI18N } catch (final NoSuchAlgorithmException ex) { throw new SSLConfigFactoryException("cannot check keystore integrity: " + keystoreFile, ex); // NOI18N } catch (final CertificateException ex) { throw new SSLConfigFactoryException("cannot load certificates from keystore: " + keystoreFile, ex); // NOI18N } } //~ Inner Classes ---------------------------------------------------------- /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private static final class LazyInitialiser { //~ Static fields/initializers ----------------------------------------- private static final SSLConfigFactory INSTANCE = new SSLConfigFactory(); } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ private static final class SSLConfigImpl implements SSLConfig { //~ Instance fields ---------------------------------------------------- private final transient KeyStore serverKeystore; private final transient KeyStore clientKeystore; private final char[] serverKeyPW; private final char[] clientKeyPW; //~ Constructors ------------------------------------------------------- /** * Creates a new SSLConfigImpl object. * * @param serverKeystore DOCUMENT ME! * @param clientKeystore DOCUMENT ME! * @param serverKeyPW DOCUMENT ME! * @param clientKeyPW DOCUMENT ME! */ public SSLConfigImpl(final KeyStore serverKeystore, final KeyStore clientKeystore, final char[] serverKeyPW, final char[] clientKeyPW) { this.serverKeystore = serverKeystore; this.clientKeystore = clientKeystore; this.serverKeyPW = serverKeyPW; this.clientKeyPW = clientKeyPW; } //~ Methods ------------------------------------------------------------ @Override public KeyStore getServerKeystore() { return serverKeystore; } @Override public KeyStore getClientKeystore() { return clientKeystore; } @Override public char[] getServerKeyPW() { return serverKeyPW; } @Override public char[] getClientKeyPW() { return clientKeyPW; } @Override public String toString() { final StringBuilder sb = new StringBuilder(super.toString()); sb.append('['); sb.append("server keystore: ").append(serverKeystore); // NOI18N sb.append(','); sb.append("client keystore: ").append(clientKeystore); // NOI18N sb.append(','); sb.append("server key password: ").append((serverKeyPW == null) ? null : "*****"); // NOI18N sb.append(','); sb.append("client key password: ").append((clientKeyPW == null) ? null : "*****"); // NOI18N sb.append(']'); return sb.toString(); } } }