/*------------------------------------------------------------------------- * * Copyright (c) 2011, PostgreSQL Global Development Group * * *------------------------------------------------------------------------- */ package org.postgresql.ssl; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.SecureRandom; import javax.net.ssl.KeyManager; import javax.net.ssl.TrustManager; /** * A CertAuthFactory that's configured using system properties, much like * (but independent from) the stock javax.net.ssl SSLSocketFactory implementation. */ public class SysPropCertAuthFactory extends AbstractCertAuthFactory { /** * File-system path to the keystore file to load, or null for system default keystore. * * May be the set to the same path as CONFIG_TRUSTSTORE_PATH if trust and key material are * in the same store. */ public final static String CONFIG_KEYSTORE_PATH = "org.postgresql.jdbc.keystore.path"; /** * Password to use to decode keystore. Ignored if CONFIG_KEYSTORE_PATH unset. */ public final static String CONFIG_KEYSTORE_PWD = "org.postgresql.jdbc.keystore.password"; /** * Password to use to decode keys within keystore. If unset, CONFIG_KEYSTORE_PWD used. * In most cases the KeyStore password is the same as the key password, so this may be * left unset. */ public final static String CONFIG_KEYSTORE_KEYPWD = "org.postgresql.jdbc.keystore.keypassword"; /** * KeyStore type, a JSSE KeyStore type name like JKS, JECKS, pkcs12, etc. Ignored if CONFIG_KEYSTORE_PATH unset. * * JECKS is the usual format used to store private keys with keytool, etc. */ public final static String CONFIG_KEYSTORE_TYPE = "org.postgresql.jdbc.keystore.type"; /** * File system path to the trust store file to load, or null for the system default trust store. * * May be the same path as CONFIG_KEYSTORE_PATH if trust and key material are * in the same store. * * The default Sun JDK trustStore is a JKS format store with password "changeme". * If you wish to use the system-default list of trusted signers, rather than * specifying the location, type, and password of the system default truststore * you should leave CONFIG_TRUSTSTORE_PATH unset so the system default truststore * is automatically loaded for you. */ public final static String CONFIG_TRUSTSTORE_PATH = "org.postgresql.jdbc.truststore.path"; /** * Password used to decode the truststore. Ignored if CONFIG_TRUSTSTORE_PATH unset. */ public final static String CONFIG_TRUSTSTORE_PWD = "org.postgresql.jdbc.truststore.password"; /** * TrustStore type. Just like CONFIG_KEYSTORE_TYPE, but for the TrustStore. * * If the TrustStore is not the same store as the KeyStore, it is common * to use the JKS format for it rather than the JECKS format usually used * for KeyStores and for combined TrustStore/KeyStores. */ public final static String CONFIG_TRUSTSTORE_TYPE = "org.postgresql.jdbc.truststore.type"; /** * The secure random algorithm to use. It is unlikely that you will need to change * this, but support for doing so is provided for completeness. */ public final static String CONFIG_SECURERANDOM = "org.postgresql.jdbc.securerandom"; public SysPropCertAuthFactory() throws IOException, GeneralSecurityException { super(); // Load configuration. First, configure and create the key manager: KeyManager[] keyManagers = null; String keyStorePath = System.getProperty(CONFIG_KEYSTORE_PATH); if (keyStorePath != null && !keyStorePath.isEmpty()) { // If only a keystore passphrase is specified but no // key passphrase is given, use the keystore passphrase for both the keystore // and the key. char[] keyStorePass = null, keyPass = null; String ksp = System.getProperty(CONFIG_KEYSTORE_PWD, null); if (ksp != null) { keyStorePass = ksp.toCharArray(); keyPass = keyStorePass; } String kp = System.getProperty(CONFIG_KEYSTORE_KEYPWD, null); if (kp != null) { keyPass = kp.toCharArray(); } keyManagers = createKeyManagers( keyStorePath, keyStorePass, keyPass, System.getProperty(CONFIG_KEYSTORE_TYPE, null)); } // then create the trust manager TrustManager[] trustManagers = null; String trustStorePath = System.getProperty(CONFIG_TRUSTSTORE_PATH); if (trustStorePath != null && !trustStorePath.isEmpty()) { char[] trustStorePass = null; String tsp = System.getProperty(CONFIG_TRUSTSTORE_PATH, null); if (tsp != null) { trustStorePass = tsp.toCharArray(); } trustManagers = createTrustManagers( trustStorePath, trustStorePass, System.getProperty(CONFIG_TRUSTSTORE_TYPE)); } // and SecureRandom instance if configured SecureRandom secureRandom = null; String secureRandomAlgo = System.getProperty(CONFIG_SECURERANDOM); if (secureRandomAlgo != null) { secureRandom = SecureRandom.getInstance(secureRandomAlgo); } // Finally, configure the factory. buildSSLSocketFactory(keyManagers, trustManagers, secureRandom); } public SysPropCertAuthFactory(String ignored) throws IOException, GeneralSecurityException { this(); } }