### Eclipse Workspace Patch 1.0 #P pgjdbc Index: org/postgresql/ssl/MakeSSL.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/ssl/MakeSSL.java,v retrieving revision 1.5 diff -u -r1.5 MakeSSL.java --- org/postgresql/ssl/MakeSSL.java 24 Nov 2005 02:29:22 -0000 1.5 +++ org/postgresql/ssl/MakeSSL.java 19 Feb 2006 10:34:18 -0000 @@ -50,8 +50,14 @@ } catch (NoSuchMethodException nsme) { - ctor = factoryClass.getConstructor((Class[])null); - args = null; + try + { + ctor = factoryClass.getConstructor((Class[])null); + args = null; + } catch (NoSuchMethodException nsme2){ + ctor = factoryClass.getConstructor(new Class[]{Properties.class}); + args[0] = info; + } } factory = (SSLSocketFactory)ctor.newInstance(args); } @@ -60,7 +66,7 @@ throw new PSQLException(GT.tr("The SSLSocketFactory class provided {0} could not be instantiated.", classname), PSQLState.CONNECTION_FAILURE, e); } } - + Socket newConnection = factory.createSocket(stream.getSocket(), stream.getHost(), stream.getPort(), true); stream.changeSocket(newConnection); } Index: org/postgresql/ssl/ValidatingFactory.java =================================================================== RCS file: org/postgresql/ssl/ValidatingFactory.java diff -N org/postgresql/ssl/ValidatingFactory.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ org/postgresql/ssl/ValidatingFactory.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,97 @@ +package org.postgresql.ssl; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Properties; + +public class ValidatingFactory extends WrappedFactory { + + public static final String SSL_FILE_KEYSTORE = "ssl.keystore"; + + public static final String SSL_KEYSTORE_TYPE = "ssl.keystore.type"; + + public static final String SSL_KEYSTORE_PASSWORD = "ssl.keystore.password"; + + public static final String SSL_PROTOCOL = "ssl.protocol"; + + public ValidatingFactory(Properties props) throws Exception { + + File keystoreFile = getKeyStoreFile(props); + + String keyStoreType = getKeyStoreType(props, keystoreFile); + KeyStore trustStore = KeyStore.getInstance(keyStoreType); + KeyStore clientKeyStore = KeyStore.getInstance(keyStoreType); + + char[] password = getKeyStorePWD(props); + + trustStore.load(new FileInputStream(keystoreFile), password); + clientKeyStore.load(new FileInputStream(keystoreFile), password); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(trustStore); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init( clientKeyStore, password ); + + Arrays.fill(password, '\0'); + + SSLContext sslContext = SSLContext.getInstance(getProtocol(props)); + + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + _factory = sslContext.getSocketFactory(); + } + + private static File getKeyStoreFile(Properties props){ + String ks = props.getProperty(SSL_FILE_KEYSTORE); + if ( ks != null ){ + return new File(ks); + } + + File ans = new File(System.getProperty("user.home")); + ans = new File(ans, ".postgresql"); + ans = new File(ans, "postgresql.jks"); + return ans; + } + + private static String getKeyStoreType(Properties props, File keyStore){ + String kst = props.getProperty(SSL_KEYSTORE_TYPE); + if ( kst != null ){ + return kst; + } + + String fileName = keyStore.getName(); + if (fileName.lastIndexOf('.') > 0){ + return fileName.substring(fileName.lastIndexOf('.') + 1 ).toUpperCase(); + } + + return "JKS"; + } + + private static char[] getKeyStorePWD(Properties props){ + String pwd = props.getProperty(SSL_KEYSTORE_PASSWORD, ""); + return pwd.toCharArray(); + } + + private static String getProtocol(Properties props){ + if ( props.containsKey(SSL_PROTOCOL)){ + return props.getProperty(SSL_PROTOCOL); + } + return "SSLv3"; + } +}