Re: SSL - Providing client certificates

From: "Saleem EDAH-TALLY" <nmset(at)netcourrier(dot)com>
To: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: SSL - Providing client certificates
Date: 2009-02-23 14:53:02
Message-ID: 200902231519.29993.nmset@netcourrier.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Regarding Kris Jurka's question :

> > What I don't understand is how it selects the certificate to send. If
> > you have multiple keys in your keystore, how do you indicate which one
> > to use?

http://java.sun.com/javase/6/docs/api/javax/net/ssl/SSLContext.html#init(javax.net.ssl.KeyManager[],
javax.net.ssl.TrustManager[], java.security.SecureRandom)

states

<>
Only the first instance of a particular key and/or trust manager implementation
type in the array is used...
</>

Hence it's not necessary to overload a keystore or a truststore.

And who knows how the entries in the keystore are sorted an presented to
SSLContext.init. My guess they are sorted in ascending order of the aliases,
but it's just a guess.

As an add-on to this thread, the following class allows to build a
SSLSocketFactory that is not JVM wide but specific to a connection. It can be
passed as sslfactory, and a label passed as sslfactoryarg.
It may be adapted and included in the jdbc-driver if found useful.

**********************************************************************
public class SSLBoth extends javax.net.ssl.SSLSocketFactory{
private String ksFile = null;
private String ksType = null;
private String ksPwd = null;
private String tsFile = null;
private String tsType = null;
private String tsPwd = null;
private javax.net.ssl.SSLSocketFactory ssf = null;

public SSLBoth(String label) {
setParams(label);
javax.net.ssl.KeyManagerFactory kmf = makeKMF();
javax.net.ssl.TrustManagerFactory tmf = makeTMF();
javax.net.ssl.SSLContext sslc = makeSSLContext(kmf.getKeyManagers(),
tmf.getTrustManagers());
ssf = sslc.getSocketFactory();
}

private void setParams(String label) {
ksFile = System.getProperty("KEYSTORE_FILE_" + label);
ksType = System.getProperty("KEYSTORE_TYPE_" + label);
ksPwd = System.getProperty("KEYSTORE_PWD_" + label);
tsFile = System.getProperty("TRUSTSTORE_FILE_" + label);
tsType = System.getProperty("TRUSTSTORE_TYPE_" + label);
tsPwd = System.getProperty("TRUSTSTORE_PWD_" + label);
}
private javax.net.ssl.KeyManagerFactory makeKMF() {
java.security.KeyStore ks = loadKeyStore(ksFile, ksType, ksPwd);
if (ks != null) {
try {
javax.net.ssl.KeyManagerFactory kmf =
javax.net.ssl.KeyManagerFactory.getInstance(javax.net.ssl.KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, ksPwd.toCharArray());
return kmf;
} catch (java.security.KeyStoreException ex) {
ex.printStackTrace();
} catch (java.security.UnrecoverableKeyException ex) {
ex.printStackTrace();
} catch (java.security.NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
}
return null;
}
private javax.net.ssl.TrustManagerFactory makeTMF() {
java.security.KeyStore ts = loadKeyStore(tsFile, tsType, tsPwd);
if (ts != null) {
try {
javax.net.ssl.TrustManagerFactory tmf =
javax.net.ssl.TrustManagerFactory.getInstance(javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ts);
return tmf;
} catch (java.security.KeyStoreException ex) {
ex.printStackTrace();
} catch (java.security.NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
}
return null;
}
private javax.net.ssl.SSLContext makeSSLContext(javax.net.ssl.KeyManager[]
km, javax.net.ssl.TrustManager[] tm) {
try {
javax.net.ssl.SSLContext sslc =
javax.net.ssl.SSLContext.getInstance("TLS");
sslc.init(km, tm, new java.security.SecureRandom());
return sslc;
} catch (java.security.KeyManagementException ex) {
ex.printStackTrace();
} catch (java.security.NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return null;
}
public static java.security.KeyStore loadKeyStore(String ksPath, String
type, String pwd) {
try {
java.security.KeyStore ks =
java.security.KeyStore.getInstance(type);
java.io.FileInputStream fis = new java.io.FileInputStream(ksPath);
ks.load(fis, pwd.toCharArray());
fis.close();
return ks;
}

catch (java.security.KeyStoreException ex) {
ex.printStackTrace();
}
catch (java.io.FileNotFoundException ex) {
ex.printStackTrace();
}
catch (java.io.IOException ex) {
ex.printStackTrace();
}
catch (java.security.NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
catch (java.security.cert.CertificateException ex) {
ex.printStackTrace();
}
return null;
}

@Override
public String[] getDefaultCipherSuites() {
return ssf.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
return ssf.getSupportedCipherSuites();
}

@Override
public java.net.Socket createSocket(java.net.Socket arg0, String arg1, int
arg2, boolean arg3) throws java.io.IOException {
return ssf.createSocket(arg0, arg1, arg2, arg3);
}

@Override
public java.net.Socket createSocket(String arg0, int arg1) throws
java.io.IOException, java.net.UnknownHostException {
return ssf.createSocket(arg0, arg1);
}

@Override
public java.net.Socket createSocket(String arg0, int arg1,
java.net.InetAddress arg2, int arg3) throws java.io.IOException,
java.net.UnknownHostException {
return ssf.createSocket(arg0, arg1, arg2, arg3);
}

@Override
public java.net.Socket createSocket(java.net.InetAddress arg0, int arg1)
throws java.io.IOException {
return ssf.createSocket(arg0, arg1);
}

@Override
public java.net.Socket createSocket(java.net.InetAddress arg0, int arg1,
java.net.InetAddress arg2, int arg3) throws java.io.IOException {
return ssf.createSocket(arg0, arg1, arg2, arg3);
}

}

**********************************************************************

In response to

Browse pgsql-jdbc by date

  From Date Subject
Next Message DGPickett 2009-02-25 16:33:36 ResultSetMetaData.getColumnDisplaySize returns 2147483647 ?
Previous Message ralf.baumhof 2009-02-23 13:45:02 Re: Performance of jdbc insert statements and select nextval