Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search archives
  Advanced Search

Re: SSL - Providing client certificates



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);
    }



}



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








Home | Main Index | Thread Index

Privacy Policy | About PostgreSQL
Copyright © 1996 – 2012 PostgreSQL Global Development Group