directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dran...@apache.org
Subject [14/36] directory-kerby git commit: Moved the source codes of not-so-commons-ssl into kerby-pkix module and cleaned up accordingly
Date Sun, 13 Dec 2015 02:02:05 GMT
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSL.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSL.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSL.java
new file mode 100644
index 0000000..3df4867
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSL.java
@@ -0,0 +1,607 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSL.java $
+ * $Revision: 180 $
+ * $Date: 2014-09-23 11:33:47 -0700 (Tue, 23 Sep 2014) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Not thread-safe.  (But who would ever share this thing across multiple
+ * threads???)
+ *
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since May 1, 2006
+ */
+public class SSL {
+    private static final String[] KNOWN_PROTOCOLS =
+            {"TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3", "SSLv2", "SSLv2Hello"};
+
+    // SUPPORTED_CIPHERS_ARRAY is initialized in the static constructor.
+    private static final String[] SUPPORTED_CIPHERS;
+
+    public static final SortedSet KNOWN_PROTOCOLS_SET;
+    public static final SortedSet SUPPORTED_CIPHERS_SET;
+
+    static {
+        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
+        ts.addAll(Arrays.asList(KNOWN_PROTOCOLS));
+        KNOWN_PROTOCOLS_SET = Collections.unmodifiableSortedSet(ts);
+
+        // SSLSocketFactory.getDefault() sometimes blocks on FileInputStream
+        // reads of "/dev/random" (Linux only?).  You might find you system
+        // stuck here.  Move the mouse around a little!
+        SSLSocketFactory s = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        ts = new TreeSet<String>();
+        SUPPORTED_CIPHERS = s.getSupportedCipherSuites();
+        Arrays.sort(SUPPORTED_CIPHERS);
+        ts.addAll(Arrays.asList(SUPPORTED_CIPHERS));
+        SUPPORTED_CIPHERS_SET = Collections.unmodifiableSortedSet(ts);
+    }
+
+    private Object sslContext = null;
+    private int initCount = 0;
+    private SSLSocketFactory socketFactory = null;
+    private SSLServerSocketFactory serverSocketFactory = null;
+    private HostnameVerifier hostnameVerifier = HostnameVerifier.DEFAULT;
+    private boolean isSecure = true;  // if false, the client-style operations only create plain sockets.
+    private boolean checkHostname = true;
+    private boolean checkCRL = true;
+    private boolean checkExpiry = true;
+    private boolean useClientMode = false;
+    private boolean useClientModeDefault = true;
+    private int soTimeout = 24 * 60 * 60 * 1000; // default: one day
+    private int connectTimeout = 60 * 60 * 1000; // default: one hour
+    private TrustChain trustChain = null;
+    private KeyMaterial keyMaterial = null;
+    private String[] enabledCiphers = null;
+    private String[] enabledProtocols = null;
+    private String defaultProtocol = "TLS";
+    private X509Certificate[] currentServerChain;
+    private X509Certificate[] currentClientChain;
+    private boolean wantClientAuth = true;
+    private boolean needClientAuth = false;
+    private SSLWrapperFactory sslWrapperFactory = SSLWrapperFactory.NO_WRAP;
+    private Map dnsOverride;
+
+    protected final boolean usingSystemProperties;
+
+    public SSL()
+            throws GeneralSecurityException, IOException {
+        boolean usingSysProps = false;
+        Properties props = System.getProperties();
+        boolean ksSet = props.containsKey("javax.net.ssl.keyStore");
+        boolean tsSet = props.containsKey("javax.net.ssl.trustStore");
+        if (ksSet) {
+            String path = System.getProperty("javax.net.ssl.keyStore");
+            String pwd = System.getProperty("javax.net.ssl.keyStorePassword");
+            pwd = pwd != null ? pwd : ""; // JSSE default is "".
+            File f = new File(path);
+            if (f.exists()) {
+                KeyMaterial km = new KeyMaterial(path, pwd.toCharArray());
+                setKeyMaterial(km);
+                usingSysProps = true;
+            }
+        }
+        boolean trustMaterialSet = false;
+        if (tsSet) {
+            String path = System.getProperty("javax.net.ssl.trustStore");
+            String pwd = System.getProperty("javax.net.ssl.trustStorePassword");
+            boolean pwdWasNull = pwd == null;
+            pwd = pwdWasNull ? "" : pwd; // JSSE default is "".
+            File f = new File(path);
+            if (f.exists()) {
+                TrustMaterial tm;
+                try {
+                    tm = new TrustMaterial(path, pwd.toCharArray());
+                } catch (GeneralSecurityException gse) {
+                    // Probably a bad password.  If we're using the default password,
+                    // let's try and survive this setback.
+                    if (pwdWasNull) {
+                        tm = new TrustMaterial(path);
+                    } else {
+                        throw gse;
+                    }
+                }
+
+                setTrustMaterial(tm);
+                usingSysProps = true;
+                trustMaterialSet = true;
+            }
+        }
+
+        /*
+            No default trust material was set.  We'll use the JSSE standard way
+            where we test for "JSSE_CACERTS" first, and then fall back on
+            "CACERTS".  We could just leave TrustMaterial null, but then our
+            setCheckCRL() and setCheckExpiry() features won't work.  We need a
+            non-null TrustMaterial object in order to intercept and decorate
+            the JVM's default TrustManager.
+          */
+        if (!trustMaterialSet) {
+            setTrustMaterial(TrustMaterial.DEFAULT);
+        }
+        this.usingSystemProperties = usingSysProps;
+        dirtyAndReloadIfYoung();
+    }
+
+    private void dirty() {
+        this.sslContext = null;
+        this.socketFactory = null;
+        this.serverSocketFactory = null;
+    }
+
+    private void dirtyAndReloadIfYoung()
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
+        dirty();
+        if (initCount >= 0 && initCount <= 5) {
+            // The first five init's we do early (before any sockets are
+            // created) in the hope that will trigger any explosions nice
+            // and early, with the correct exception type.
+
+            // After the first five init's, we revert to a regular
+            // dirty / init pattern, and the "init" happens very late:
+            // just before the socket is created.  If badness happens, a
+            // wrapping RuntimeException will be thrown.
+            init();
+        }
+    }
+
+    String dnsOverride(String host) {
+        if (dnsOverride != null && dnsOverride.containsKey(host)) {
+            String override = (String) dnsOverride.get(host);
+            if (override != null && !"".equals(override.trim())) {
+                return override;
+            }
+        }
+        return host;
+    }
+
+    public void setDnsOverride(Map m) {
+        this.dnsOverride = m;
+    }
+
+    public void setIsSecure(boolean b) {
+        this.isSecure = b;
+    }
+
+    public boolean isSecure() {
+        return isSecure;
+    }
+
+    public SSLContext getSSLContext()
+            throws GeneralSecurityException, IOException {
+        Object obj = getSSLContextAsObject();
+        return (SSLContext) obj;
+    }
+
+    /**
+     * @return com.sun.net.ssl.SSLContext or javax.net.ssl.SSLContext depending
+     *         on the JSSE implementation we're using.
+     * @throws java.security.GeneralSecurityException problem creating SSLContext
+     * @throws java.io.IOException              problem creating SSLContext
+     */
+    public Object getSSLContextAsObject()
+            throws GeneralSecurityException, IOException {
+        if (sslContext == null) {
+            init();
+        }
+        return sslContext;
+    }
+
+    public void addTrustMaterial(TrustChain trustChain)
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
+        if (this.trustChain == null || trustChain == TrustMaterial.TRUST_ALL) {
+            this.trustChain = trustChain;
+        } else {
+            this.trustChain.addTrustMaterial(trustChain);
+        }
+        dirtyAndReloadIfYoung();
+    }
+
+    public void setTrustMaterial(TrustChain trustChain)
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
+        this.trustChain = trustChain;
+        dirtyAndReloadIfYoung();
+    }
+
+    public void setKeyMaterial(KeyMaterial keyMaterial)
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
+        this.keyMaterial = keyMaterial;
+        dirtyAndReloadIfYoung();
+    }
+
+    public X509Certificate[] getAssociatedCertificateChain() {
+        if (keyMaterial != null) {
+            List list = keyMaterial.getAssociatedCertificateChains();
+            return (X509Certificate[]) list.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    public String[] getEnabledCiphers() {
+        return enabledCiphers != null ? enabledCiphers : getDefaultCipherSuites();
+    }
+
+    public void setEnabledCiphers(String[] ciphers) {
+        HashSet<String> desired = new HashSet<String>(Arrays.asList(ciphers));
+        desired.removeAll(SUPPORTED_CIPHERS_SET);
+        if (!desired.isEmpty()) {
+            throw new IllegalArgumentException("following ciphers not supported: " + desired);
+        }
+        this.enabledCiphers = ciphers;
+    }
+
+    public String[] getEnabledProtocols() {
+        return enabledProtocols;
+    }
+
+    public void setEnabledProtocols(String[] protocols) {
+        this.enabledProtocols = protocols;
+    }
+
+    public String getDefaultProtocol() {
+        return defaultProtocol;
+    }
+
+    public void setDefaultProtocol(String protocol) {
+        this.defaultProtocol = protocol;
+        dirty();
+    }
+
+    public boolean getCheckHostname() {
+        return checkHostname;
+    }
+
+    public void setCheckHostname(boolean checkHostname) {
+        this.checkHostname = checkHostname;
+    }
+
+    public void setHostnameVerifier(HostnameVerifier verifier) {
+        if (verifier == null) {
+            verifier = HostnameVerifier.DEFAULT;
+        }
+        this.hostnameVerifier = verifier;
+    }
+
+    public HostnameVerifier getHostnameVerifier() {
+        return hostnameVerifier;
+    }
+
+    public boolean getCheckCRL() {
+        return checkCRL;
+    }
+
+    public void setCheckCRL(boolean checkCRL) {
+        this.checkCRL = checkCRL;
+    }
+
+    public boolean getCheckExpiry() {
+        return checkExpiry;
+    }
+
+    public void setCheckExpiry(boolean checkExpiry) {
+        this.checkExpiry = checkExpiry;
+    }
+
+    public void setSoTimeout(int soTimeout) {
+        if (soTimeout < 0) {
+            throw new IllegalArgumentException("soTimeout must not be negative");
+        }
+        this.soTimeout = soTimeout;
+    }
+
+    public int getSoTimeout() {
+        return soTimeout;
+    }
+
+    public void setConnectTimeout(int connectTimeout) {
+        if (connectTimeout < 0) {
+            throw new IllegalArgumentException("connectTimeout must not be negative");
+        }
+        this.connectTimeout = connectTimeout;
+    }
+
+    public void setUseClientMode(boolean useClientMode) {
+        this.useClientModeDefault = false;
+        this.useClientMode = useClientMode;
+    }
+
+    public boolean getUseClientModeDefault() {
+        return useClientModeDefault;
+    }
+
+    public boolean getUseClientMode() {
+        return useClientMode;
+    }
+
+    public void setWantClientAuth(boolean wantClientAuth) {
+        this.wantClientAuth = wantClientAuth;
+    }
+
+    public void setNeedClientAuth(boolean needClientAuth) {
+        this.needClientAuth = needClientAuth;
+    }
+
+    public boolean getWantClientAuth() {
+        return wantClientAuth;
+    }
+
+    public boolean getNeedClientAuth() {
+        return needClientAuth;
+    }
+
+    public SSLWrapperFactory getSSLWrapperFactory() {
+        return this.sslWrapperFactory;
+    }
+
+    public void setSSLWrapperFactory(SSLWrapperFactory wf) {
+        this.sslWrapperFactory = wf;
+    }
+
+    private void initThrowRuntime() {
+        try {
+            init();
+        } catch (GeneralSecurityException gse) {
+            throw JavaImpl.newRuntimeException(gse);
+        } catch (IOException ioe) {
+            throw JavaImpl.newRuntimeException(ioe);
+        }
+    }
+
+    private void init()
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
+        socketFactory = null;
+        serverSocketFactory = null;
+        this.sslContext = JavaImpl.init(this, trustChain, keyMaterial);
+        initCount++;
+    }
+
+    public void doPreConnectSocketStuff(Socket s) throws IOException {
+        if (s instanceof SSLSocket && !useClientModeDefault) {
+            ((SSLSocket) s).setUseClientMode(useClientMode);
+        }
+        if (soTimeout > 0) {
+            s.setSoTimeout(soTimeout);
+        }
+        if (s instanceof SSLSocket) {
+            if (enabledProtocols != null) {
+                JavaImpl.setEnabledProtocols(s, enabledProtocols);
+            }
+            if (enabledCiphers != null) {
+                ((SSLSocket) s).setEnabledCipherSuites(enabledCiphers);
+            }
+        }
+    }
+
+    public void doPostConnectSocketStuff(Socket s, String host)
+            throws IOException {
+        if (checkHostname && s instanceof SSLSocket) {
+            hostnameVerifier.check(host, (SSLSocket) s);
+        }
+    }
+
+    public Socket createSocket() throws IOException {
+        if (isSecure) {
+            return sslWrapperFactory.wrap(JavaImpl.createSocket(this));
+        } else {
+            Socket s = SocketFactory.getDefault().createSocket();
+            doPreConnectSocketStuff(s);
+            return s;
+        }
+    }
+
+    /**
+     * Attempts to get a new socket connection to the given host within the
+     * given time limit.
+     *
+     * @param remoteHost the host name/IP
+     * @param remotePort the port on the host
+     * @param localHost  the local host name/IP to bind the socket to
+     * @param localPort  the port on the local machine
+     * @param timeout    the connection timeout (0==infinite)
+     * @return Socket a new socket
+     * @throws java.io.IOException          if an I/O error occurs while creating the socket
+     * @throws java.net.UnknownHostException if the IP address of the host cannot be
+     *                              determined
+     */
+    public Socket createSocket(
+            String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout
+    ) throws IOException {
+        // Only use our factory-wide connectTimeout if this method was passed
+        // in a timeout of 0 (infinite).
+        int factoryTimeout = getConnectTimeout();
+        int connectTimeout = timeout == 0 ? factoryTimeout : timeout;
+        Socket s;
+        if (isSecure) {
+            s = JavaImpl.createSocket(
+                    this, remoteHost, remotePort, localHost, localPort, connectTimeout
+            );
+        } else {
+            s = JavaImpl.createPlainSocket(
+                    this, remoteHost, remotePort, localHost, localPort, connectTimeout
+            );
+        }
+        return sslWrapperFactory.wrap(s);
+    }
+
+    public Socket createSocket(
+            Socket s, String remoteHost, int remotePort, boolean autoClose
+    ) throws IOException {
+        SSLSocketFactory sf = getSSLSocketFactory();
+        s = sf.createSocket(s, remoteHost, remotePort, autoClose);
+        doPreConnectSocketStuff(s);
+        doPostConnectSocketStuff(s, remoteHost);
+        return sslWrapperFactory.wrap(s);
+    }
+
+    public ServerSocket createServerSocket() throws IOException {
+        SSLServerSocket ss = JavaImpl.createServerSocket(this);
+        return getSSLWrapperFactory().wrap(ss, this);
+    }
+
+    /**
+     * Attempts to get a new socket connection to the given host within the
+     * given time limit.
+     *
+     * @param localHost the local host name/IP to bind against (null == ANY)
+     * @param port      the port to listen on
+     * @param backlog   number of connections allowed to queue up for accept().
+     * @return SSLServerSocket a new server socket
+     * @throws java.io.IOException if an I/O error occurs while creating thesocket
+     */
+    public ServerSocket createServerSocket(int port, int backlog,
+                                           InetAddress localHost)
+            throws IOException {
+        SSLServerSocketFactory f = getSSLServerSocketFactory();
+        ServerSocket ss = f.createServerSocket(port, backlog, localHost);
+        SSLServerSocket s = (SSLServerSocket) ss;
+        doPreConnectServerSocketStuff(s);
+        return getSSLWrapperFactory().wrap(s, this);
+    }
+
+    public void doPreConnectServerSocketStuff(SSLServerSocket s)
+            throws IOException {
+        if (soTimeout > 0) {
+            s.setSoTimeout(soTimeout);
+        }
+        if (enabledProtocols != null) {
+            JavaImpl.setEnabledProtocols(s, enabledProtocols);
+        }
+        if (enabledCiphers != null) {
+            s.setEnabledCipherSuites(enabledCiphers);
+        }
+
+        /*
+          setNeedClientAuth( false ) has an annoying side effect:  it seems to
+          reset setWantClient( true ) back to to false.  So I do things this
+          way to make sure setting things "true" happens after setting things
+          "false" - giving "true" priority.
+          */
+        if (!wantClientAuth) {
+            JavaImpl.setWantClientAuth(s, false);
+        }
+        if (!needClientAuth) {
+            s.setNeedClientAuth(false);
+        }
+        if (wantClientAuth) {
+            JavaImpl.setWantClientAuth(s, true);
+        }
+        if (needClientAuth) {
+            s.setNeedClientAuth(true);
+        }
+    }
+
+    public SSLSocketFactory getSSLSocketFactory() {
+        if (sslContext == null) {
+            initThrowRuntime();
+        }
+        if (socketFactory == null) {
+            socketFactory = JavaImpl.getSSLSocketFactory(sslContext);
+        }
+        return socketFactory;
+    }
+
+    public SSLServerSocketFactory getSSLServerSocketFactory() {
+        if (sslContext == null) {
+            initThrowRuntime();
+        }
+        if (serverSocketFactory == null) {
+            serverSocketFactory = JavaImpl.getSSLServerSocketFactory(sslContext);
+        }
+        return serverSocketFactory;
+    }
+
+    public int getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    public String[] getDefaultCipherSuites() {
+        return getSSLSocketFactory().getDefaultCipherSuites();
+    }
+
+    public String[] getSupportedCipherSuites() {
+        String[] s = new String[SUPPORTED_CIPHERS.length];
+        System.arraycopy(SUPPORTED_CIPHERS, 0, s, 0, s.length);
+        return s;
+    }
+
+    public TrustChain getTrustChain() {
+        return trustChain;
+    }
+
+    public void setCurrentServerChain(X509Certificate[] chain) {
+        this.currentServerChain = chain;
+    }
+
+    public void setCurrentClientChain(X509Certificate[] chain) {
+        this.currentClientChain = chain;
+    }
+
+    public X509Certificate[] getCurrentServerChain() {
+        return currentServerChain;
+    }
+
+    public X509Certificate[] getCurrentClientChain() {
+        return currentClientChain;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLClient.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLClient.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLClient.java
new file mode 100644
index 0000000..5c0bc03
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLClient.java
@@ -0,0 +1,271 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLClient.java $
+ * $Revision: 180 $
+ * $Date: 2014-09-23 11:33:47 -0700 (Tue, 23 Sep 2014) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 27-Feb-2006
+ */
+public class SSLClient extends SSLSocketFactory {
+    private final SSL ssl;
+
+    public SSLClient()
+        throws GeneralSecurityException, IOException {
+        this.ssl = new SSL();
+    }
+
+    public void addTrustMaterial(TrustChain trustChain)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        KeyManagementException, IOException, CertificateException {
+        ssl.addTrustMaterial(trustChain);
+    }
+
+    public void setTrustMaterial(TrustChain trustChain)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        KeyManagementException, IOException, CertificateException {
+        ssl.setTrustMaterial(trustChain);
+    }
+
+    public void setKeyMaterial(KeyMaterial keyMaterial)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        KeyManagementException, IOException, CertificateException {
+        ssl.setKeyMaterial(keyMaterial);
+    }
+
+    public void setIsSecure(boolean b) {
+        ssl.setIsSecure(b);
+    }
+
+    public void setDnsOverride(Map m) {
+        ssl.setDnsOverride(m);
+    }
+
+    public void setCheckCRL(boolean b) {
+        ssl.setCheckCRL(b);
+    }
+
+    public void setCheckExpiry(boolean b) {
+        ssl.setCheckExpiry(b);
+    }
+
+    public void setCheckHostname(boolean b) {
+        ssl.setCheckHostname(b);
+    }
+
+    public void setConnectTimeout(int i) {
+        ssl.setConnectTimeout(i);
+    }
+
+    public void setDefaultProtocol(String s) {
+        ssl.setDefaultProtocol(s);
+    }
+
+    public void setEnabledCiphers(String[] ciphers) {
+        ssl.setEnabledCiphers(ciphers);
+    }
+
+    public void setEnabledProtocols(String[] protocols) {
+        ssl.setEnabledProtocols(protocols);
+    }
+
+    public void setHostnameVerifier(HostnameVerifier verifier) {
+        ssl.setHostnameVerifier(verifier);
+    }
+
+    public void setSoTimeout(int soTimeout) {
+        ssl.setSoTimeout(soTimeout);
+    }
+
+    public void setSSLWrapperFactory(SSLWrapperFactory wf) {
+        ssl.setSSLWrapperFactory(wf);
+    }
+
+    public void setNeedClientAuth(boolean b) {
+        ssl.setNeedClientAuth(b);
+    }
+
+    public void setWantClientAuth(boolean b) {
+        ssl.setWantClientAuth(b);
+    }
+
+    public void setUseClientMode(boolean b) {
+        ssl.setUseClientMode(b);
+    }
+
+    public boolean isSecure() {
+        return ssl.isSecure();
+    }
+
+    public X509Certificate[] getAssociatedCertificateChain() {
+        return ssl.getAssociatedCertificateChain();
+    }
+
+    public boolean getCheckCRL() {
+        return ssl.getCheckCRL();
+    }
+
+    public boolean getCheckExpiry() {
+        return ssl.getCheckExpiry();
+    }
+
+    public boolean getCheckHostname() {
+        return ssl.getCheckHostname();
+    }
+
+    public int getConnectTimeout() {
+        return ssl.getConnectTimeout();
+    }
+
+    public String getDefaultProtocol() {
+        return ssl.getDefaultProtocol();
+    }
+
+    public String[] getEnabledCiphers() {
+        return ssl.getEnabledCiphers();
+    }
+
+    public String[] getEnabledProtocols() {
+        return ssl.getEnabledProtocols();
+    }
+
+    public HostnameVerifier getHostnameVerifier() {
+        return ssl.getHostnameVerifier();
+    }
+
+    public int getSoTimeout() {
+        return ssl.getSoTimeout();
+    }
+
+    public SSLWrapperFactory getSSLWrapperFactory() {
+        return ssl.getSSLWrapperFactory();
+    }
+
+    public boolean getNeedClientAuth() {
+        return ssl.getNeedClientAuth();
+    }
+
+    public boolean getWantClientAuth() {
+        return ssl.getWantClientAuth();
+    }
+
+    public boolean getUseClientMode() { /* SSLClient's default is true. */
+        return ssl.getUseClientModeDefault() || ssl.getUseClientMode();
+    }
+
+    public SSLContext getSSLContext() throws GeneralSecurityException, IOException {
+        return ssl.getSSLContext();
+    }
+
+    public TrustChain getTrustChain() {
+        return ssl.getTrustChain();
+    }
+
+    public X509Certificate[] getCurrentServerChain() {
+        return ssl.getCurrentServerChain();
+    }
+
+    public String[] getDefaultCipherSuites() {
+        return ssl.getDefaultCipherSuites();
+    }
+
+    public String[] getSupportedCipherSuites() {
+        return ssl.getSupportedCipherSuites();
+    }
+
+    public Socket createSocket() throws IOException {
+        return ssl.createSocket();
+    }
+
+    public Socket createSocket(String host, int port)
+        throws IOException {
+        return createSocket(host, port, null, 0);
+    }
+
+    public Socket createSocket(InetAddress host, int port)
+        throws IOException {
+        return createSocket(host.getHostName(), port);
+    }
+
+    public Socket createSocket(InetAddress host, int port,
+                               InetAddress localHost, int localPort)
+        throws IOException {
+        return createSocket(host.getHostName(), port, localHost, localPort);
+    }
+
+    public Socket createSocket(String host, int port,
+                               InetAddress localHost, int localPort)
+        throws IOException {
+        return createSocket(host, port, localHost, localPort, 0);
+    }
+
+    /**
+     * Attempts to get a new socket connection to the given host within the
+     * given time limit.
+     *
+     * @param host      the host name/IP
+     * @param port      the port on the host
+     * @param localHost the local host name/IP to bind the socket to
+     * @param localPort the port on the local machine
+     * @param timeout   the connection timeout (0==infinite)
+     * @return Socket a new socket
+     * @throws java.io.IOException          if an I/O error occurs while creating thesocket
+     * @throws java.net.UnknownHostException if the IP address of the host cannot be
+     *                              determined
+     */
+    public Socket createSocket(String host, int port, InetAddress localHost,
+                               int localPort, int timeout)
+        throws IOException {
+        return ssl.createSocket(host, port, localHost, localPort, timeout);
+    }
+
+    public Socket createSocket(Socket s, String remoteHost, int remotePort,
+                               boolean autoClose)
+        throws IOException {
+        return ssl.createSocket(s, remoteHost, remotePort, autoClose);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLEchoServer.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLEchoServer.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLEchoServer.java
new file mode 100644
index 0000000..437ccc4
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLEchoServer.java
@@ -0,0 +1,147 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLEchoServer.java $
+ * $Revision: 180 $
+ * $Date: 2014-09-23 11:33:47 -0700 (Tue, 23 Sep 2014) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import org.apache.commons.ssl.util.ReadLine;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 2-May-2006
+ */
+public class SSLEchoServer {
+
+    public static void main(String[] args) throws Exception {
+        int port = 7443;
+        if (args.length >= 1) {
+            port = Integer.parseInt(args[0]);
+        }
+
+        SSLServer ssl = new SSLServer();
+        ssl.setTrustMaterial(TrustMaterial.TRUST_ALL);
+        ssl.setCheckExpiry(false);
+        ssl.setCheckCRL(false);
+        ssl.setCheckHostname(false);
+        ssl.setWantClientAuth(true);
+
+        SSLServerSocket ss = (SSLServerSocket) ssl.createServerSocket(port, 3);
+        System.out.println("SSL Echo server listening on port: " + port);
+        while (true) {
+            SSLSocket s = (SSLSocket) ss.accept();
+            s.setSoTimeout(30000);
+            EchoRunnable r = new EchoRunnable(s);
+            new Thread(r).start();
+        }
+
+    }
+
+    public static class EchoRunnable implements Runnable {
+        private SSLSocket s;
+
+        public EchoRunnable(SSLSocket s) {
+            this.s = s;
+        }
+
+        public void run() {
+            InputStream in = null;
+            OutputStream out = null;
+            System.out.println("Socket accepted!");
+            try {
+                SSLSession session = s.getSession();
+
+                try {
+                    Certificate[] certs = JavaImpl.getPeerCertificates(session);
+                    if (certs != null) {
+                        for (int i = 0; i < certs.length; i++) {
+                            // log client cert info
+                            X509Certificate cert = (X509Certificate) certs[i];
+                            String s = "client cert " + i + ":";
+                            s += JavaImpl.getSubjectX500(cert);
+                            System.out.println(s);
+                            System.out.println(Certificates.toString(cert));
+                        }
+                    }
+                } catch (SSLPeerUnverifiedException sslpue) {
+                    // oh well, no client cert for us
+                    System.out.println(sslpue);
+                }
+
+                in = s.getInputStream();
+                out = s.getOutputStream();
+                ReadLine readLine = new ReadLine(in);
+                String line = readLine.next();
+                if (line != null && line.indexOf("HTTP") > 0) {
+                    out.write("HTTP/1.1 200 OK\r\n\r\n".getBytes());
+                    out.flush();
+                }
+                while (line != null) {
+                    String echo = "ECHO:>" + line + "\n";
+                    out.write(echo.getBytes());
+                    out.flush();
+                    line = readLine.next();
+                }
+            } catch (IOException ioe) {
+                try {
+                    if (out != null) {
+                        out.close();
+                    }
+                    if (in != null) {
+                        in.close();
+                    }
+                    s.close();
+                } catch (Exception e) {
+                    System.err.println(e);
+                }
+
+                if (ioe instanceof InterruptedIOException) {
+                    System.out.println("Socket closed after 30 second timeout.");
+                } else {
+                    ioe.printStackTrace();
+                }
+
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLProxyServer.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLProxyServer.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLProxyServer.java
new file mode 100644
index 0000000..c2ca551
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLProxyServer.java
@@ -0,0 +1,194 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLProxyServer.java $
+ * $Revision: 132 $
+ * $Date: 2008-01-11 21:20:26 -0800 (Fri, 11 Jan 2008) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import org.apache.commons.ssl.util.ReadLine;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 5-May-2006
+ */
+public class SSLProxyServer {
+
+    public static void main(String[] args) throws Exception {
+        int port = 7444;
+        if (args.length >= 1) {
+            port = Integer.parseInt(args[0]);
+        }
+
+        ServerSocket ss = new ServerSocket(port);
+
+        System.out.println("SSL Proxy server listening on port: " + port);
+        while (true) {
+            Socket s = ss.accept();
+            s.setSoTimeout(10000);
+            ProxyRunnable r = new ProxyRunnable(s);
+            new Thread(r).start();
+        }
+
+    }
+
+    public static class ProxyRunnable implements Runnable {
+        private Socket s;
+
+        public ProxyRunnable(Socket s) {
+            this.s = s;
+        }
+
+        public void run() {
+            InputStream in = null;
+            OutputStream out = null;
+            InputStream newIn = null;
+            OutputStream newOut = null;
+            Socket newSocket = new Socket();
+            System.out.println("Socket accepted!");
+            try {
+                in = s.getInputStream();
+                out = s.getOutputStream();
+                ReadLine readLine = new ReadLine(in);
+                String line = readLine.next();
+                line = line.trim();
+                String connect = line.substring(0, "CONNECT".length());
+                InetSocketAddress addr = null;
+                if ("CONNECT".equalsIgnoreCase(connect)) {
+                    line = line.substring("CONNECT".length()).trim();
+                    line = line.substring(0, line.length() - "HTTP/1.1".length()).trim();
+                    HostPort hostPort = Util.toAddress(line, 443);
+                    addr = new InetSocketAddress(hostPort.host, hostPort.port);
+                    System.out.println("Attempting to proxy to: " + line);
+                } else {
+                    throw new IOException("not a proxy request: " + line);
+                }
+
+                int avail = in.available();
+                in.skip(avail);
+                Thread.yield();
+                avail = in.available();
+                while (avail != 0) {
+                    in.skip(avail);
+                    Thread.yield();
+                    avail = in.available();
+                }
+
+                InetSocketAddress local = new InetSocketAddress(0);
+                newSocket.setSoTimeout(10000);
+                newSocket.bind(local);
+                newSocket.connect(addr, 5000);
+                newIn = newSocket.getInputStream();
+                newOut = newSocket.getOutputStream();
+
+                out.write("HTTP/1.1 200 OKAY\r\n\r\n".getBytes());
+                out.flush();
+
+                final IOException[] e = new IOException[1];
+                final InputStream rIn = in;
+                final OutputStream rNewOut = newOut;
+                Runnable r = new Runnable() {
+                    public void run() {
+                        try {
+                            byte[] buf = new byte[4096];
+                            int read = rIn.read(buf);
+                            while (read >= 0) {
+                                if (read > 0) {
+                                    rNewOut.write(buf, 0, read);
+                                    rNewOut.flush();
+                                }
+                                read = rIn.read(buf);
+                            }
+                        } catch (IOException ioe) {
+                            e[0] = ioe;
+                        }
+                    }
+                };
+                new Thread(r).start();
+
+                byte[] buf = new byte[4096];
+                int read = newIn.read(buf);
+                while (read >= 0) {
+                    if (read > 0) {
+                        out.write(buf, 0, read);
+                        out.flush();
+                    }
+                    if (e[0] != null) {
+                        throw e[0];
+                    }
+                    read = newIn.read(buf);
+                }
+
+
+            } catch (IOException ioe) {
+                try {
+                    if (out != null) {
+                        out.close();
+                    }
+                    if (in != null) {
+                        in.close();
+                    }
+                    s.close();
+                } catch (Exception e) {
+                    System.err.println(e);
+                }
+
+                try {
+                    if (newOut != null) {
+                        newOut.close();
+                    }
+                    if (newIn != null) {
+                        newIn.close();
+                    }
+                    newSocket.close();
+                } catch (Exception e) {
+                    System.err.println(e);
+                }
+
+
+                if (ioe instanceof InterruptedIOException) {
+                    System.out.println("Socket closed after 10 second timeout.");
+                } else {
+                    ioe.printStackTrace();
+                }
+
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServer.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServer.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServer.java
new file mode 100644
index 0000000..cc13e98
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServer.java
@@ -0,0 +1,291 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLServer.java $
+ * $Revision: 180 $
+ * $Date: 2014-09-23 11:33:47 -0700 (Tue, 23 Sep 2014) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since May 1, 2006
+ */
+public class SSLServer extends SSLServerSocketFactory {
+    protected final SSL ssl;
+
+    public SSLServer()
+        throws GeneralSecurityException, IOException {
+        this.ssl = new SSL();
+        // client certs aren't usually tied down to a single host (and who knows
+        // if the DNS reverse-lookup will work!).
+        setCheckHostname(false);
+
+        // If "javax.net.ssl.keyStore" is set, then we won't bother with this
+        // silly SSLServer default behaviour.
+        if (!ssl.usingSystemProperties) {
+            // commons-ssl default KeyMaterial will be
+            //  ~/.keystore with a password of "changeit".
+            useDefaultKeyMaterial();
+        }
+    }
+
+    private boolean useDefaultKeyMaterial()
+        throws GeneralSecurityException, IOException {
+        // If we're not able to re-use Tomcat's SSLServerSocket configuration,
+        // commons-ssl default KeyMaterial will be  ~/.keystore with a password
+        // of "changeit".
+        Properties props = System.getProperties();
+        boolean pwdSet = props.containsKey("javax.net.ssl.keyStorePassword");
+        String pwd = props.getProperty("javax.net.ssl.keyStorePassword");
+        pwd = pwdSet ? pwd : "changeit";
+
+        String userHome = System.getProperty("user.home");
+        String path = userHome + "/.keystore";
+        File f = new File(path);
+        boolean success = false;
+        if (f.exists()) {
+            KeyMaterial km = null;
+            try {
+                km = new KeyMaterial(path, pwd.toCharArray());
+            } catch (Exception e) {
+                // Don't want to blowup just because this silly default
+                // behaviour didn't work out.
+                if (pwdSet) {
+                    // Buf if the user has specified a non-standard password for
+                    // "javax.net.ssl.keyStorePassword", then we will warn them
+                    // that things didn't work out.
+                    System.err.println("commons-ssl automatic loading of [" + path + "] failed. ");
+                    System.err.println(e);
+                }
+            }
+            if (km != null) {
+                setKeyMaterial(km);
+                success = true;
+            }
+        }
+        return success;
+    }
+
+    public void setDnsOverride(Map m) {
+        ssl.setDnsOverride(m);
+    }
+
+    public void addTrustMaterial(TrustChain trustChain)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        KeyManagementException, IOException, CertificateException {
+        ssl.addTrustMaterial(trustChain);
+    }
+
+    public void setTrustMaterial(TrustChain trustChain)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        KeyManagementException, IOException, CertificateException {
+        ssl.setTrustMaterial(trustChain);
+    }
+
+    public void setKeyMaterial(KeyMaterial keyMaterial)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        KeyManagementException, IOException, CertificateException {
+        ssl.setKeyMaterial(keyMaterial);
+    }
+
+    public void setCheckCRL(boolean b) {
+        ssl.setCheckCRL(b);
+    }
+
+    public void setCheckExpiry(boolean b) {
+        ssl.setCheckExpiry(b);
+    }
+
+    public void setCheckHostname(boolean b) {
+        ssl.setCheckHostname(b);
+    }
+
+    public void setConnectTimeout(int i) {
+        ssl.setConnectTimeout(i);
+    }
+
+    public void setDefaultProtocol(String s) {
+        ssl.setDefaultProtocol(s);
+    }
+
+    public void setEnabledCiphers(String[] ciphers) {
+        ssl.setEnabledCiphers(ciphers);
+    }
+
+    public void setEnabledProtocols(String[] protocols) {
+        ssl.setEnabledProtocols(protocols);
+    }
+
+    public void setHostnameVerifier(HostnameVerifier verifier) {
+        ssl.setHostnameVerifier(verifier);
+    }
+
+    public void setSoTimeout(int soTimeout) {
+        ssl.setSoTimeout(soTimeout);
+    }
+
+    public void setSSLWrapperFactory(SSLWrapperFactory wf) {
+        ssl.setSSLWrapperFactory(wf);
+    }
+
+    public void setNeedClientAuth(boolean b) {
+        ssl.setNeedClientAuth(b);
+    }
+
+    public void setWantClientAuth(boolean b) {
+        ssl.setWantClientAuth(b);
+    }
+
+    public void setUseClientMode(boolean b) {
+        ssl.setUseClientMode(b);
+    }
+
+    public X509Certificate[] getAssociatedCertificateChain() {
+        return ssl.getAssociatedCertificateChain();
+    }
+
+    public boolean getCheckCRL() {
+        return ssl.getCheckCRL();
+    }
+
+    public boolean getCheckExpiry() {
+        return ssl.getCheckExpiry();
+    }
+
+    public boolean getCheckHostname() {
+        return ssl.getCheckHostname();
+    }
+
+    public int getConnectTimeout() {
+        return ssl.getConnectTimeout();
+    }
+
+    public String getDefaultProtocol() {
+        return ssl.getDefaultProtocol();
+    }
+
+    public String[] getEnabledCiphers() {
+        return ssl.getEnabledCiphers();
+    }
+
+    public String[] getEnabledProtocols() {
+        return ssl.getEnabledProtocols();
+    }
+
+    public HostnameVerifier getHostnameVerifier() {
+        return ssl.getHostnameVerifier();
+    }
+
+    public int getSoTimeout() {
+        return ssl.getSoTimeout();
+    }
+
+    public SSLWrapperFactory getSSLWrapperFactory() {
+        return ssl.getSSLWrapperFactory();
+    }
+
+    public boolean getNeedClientAuth() {
+        return ssl.getNeedClientAuth();
+    }
+
+    public boolean getWantClientAuth() {
+        return ssl.getWantClientAuth();
+    }
+
+    public boolean getUseClientMode() { /* SSLServer's default is false. */
+        return !ssl.getUseClientModeDefault() && ssl.getUseClientMode();
+    }
+
+    public SSLContext getSSLContext() throws GeneralSecurityException, IOException {
+        return ssl.getSSLContext();
+    }
+
+    public TrustChain getTrustChain() {
+        return ssl.getTrustChain();
+    }
+
+    public X509Certificate[] getCurrentClientChain() {
+        return ssl.getCurrentClientChain();
+    }
+
+    public String[] getDefaultCipherSuites() {
+        return ssl.getDefaultCipherSuites();
+    }
+
+    public String[] getSupportedCipherSuites() {
+        return ssl.getSupportedCipherSuites();
+    }
+
+    public ServerSocket createServerSocket() throws IOException {
+        return ssl.createServerSocket();
+    }
+
+    public ServerSocket createServerSocket(int port)
+        throws IOException {
+        return createServerSocket(port, 50);
+    }
+
+    public ServerSocket createServerSocket(int port, int backlog)
+        throws IOException {
+        return createServerSocket(port, backlog, null);
+    }
+
+    /**
+     * Attempts to get a new socket connection to the given host within the
+     * given time limit.
+     *
+     * @param localHost the local host name/IP to bind against (null == ANY)
+     * @param port      the port to listen on
+     * @param backlog   number of connections allowed to queue up for accept().
+     * @return SSLServerSocket a new server socket
+     * @throws java.io.IOException if an I/O error occurs while creating thesocket
+     */
+    public ServerSocket createServerSocket(int port, int backlog,
+                                           InetAddress localHost)
+        throws IOException {
+        return ssl.createServerSocket(port, backlog, localHost);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServerSocketWrapper.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServerSocketWrapper.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServerSocketWrapper.java
new file mode 100644
index 0000000..ead1a0f
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLServerSocketWrapper.java
@@ -0,0 +1,210 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java $
+ * $Revision: 121 $
+ * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.ServerSocketChannel;
+
+/**
+ * Wraps an SSLServerSocket - NOTE that the accept() method applies a number of
+ * important common-ssl settings before returning the SSLSocket!
+ *
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 20-Nov-2006
+ */
+public class SSLServerSocketWrapper extends SSLServerSocket {
+    protected SSLServerSocket s;
+    protected SSL ssl;
+    protected SSLWrapperFactory wf;
+
+    public SSLServerSocketWrapper(SSLServerSocket s, SSL ssl,
+                                  SSLWrapperFactory wf)
+        throws IOException {
+        super();
+        this.s = s;
+        this.ssl = ssl;
+        this.wf = wf;
+    }
+
+    /* javax.net.ssl.SSLServerSocket */
+
+    public Socket accept() throws IOException {
+        SSLSocket secureSocket = (SSLSocket) s.accept();
+
+        // Do the commons-ssl usual housekeeping for every socket:
+        ssl.doPreConnectSocketStuff(secureSocket);
+        InetAddress addr = secureSocket.getInetAddress();
+        String hostName = addr.getHostName();
+        ssl.doPostConnectSocketStuff(secureSocket, hostName);
+
+        return wf.wrap(secureSocket);
+    }
+
+    public String[] getEnabledCipherSuites() {
+        return s.getEnabledCipherSuites();
+    }
+
+    public String[] getEnabledProtocols() {
+        return s.getEnabledProtocols();
+    }
+
+    public boolean getEnableSessionCreation() {
+        return s.getEnableSessionCreation();
+    }
+
+    public boolean getNeedClientAuth() {
+        return s.getNeedClientAuth();
+    }
+
+    public String[] getSupportedCipherSuites() {
+        return s.getSupportedCipherSuites();
+    }
+
+    public String[] getSupportedProtocols() {
+        return s.getSupportedProtocols();
+    }
+
+    public boolean getUseClientMode() {
+        return s.getUseClientMode();
+    }
+
+    public boolean getWantClientAuth() {
+        return s.getWantClientAuth();
+    }
+
+    public void setEnabledCipherSuites(String[] suites) {
+        s.setEnabledCipherSuites(suites);
+    }
+
+    public void setEnabledProtocols(String[] protocols) {
+        s.setEnabledProtocols(protocols);
+    }
+
+    public void setEnableSessionCreation(boolean flag) {
+        s.setEnableSessionCreation(flag);
+    }
+
+    public void setNeedClientAuth(boolean need) {
+        s.setNeedClientAuth(need);
+    }
+
+    public void setUseClientMode(boolean use) {
+        s.setUseClientMode(use);
+    }
+
+    public void setWantClientAuth(boolean want) {
+        s.setWantClientAuth(want);
+    }
+
+    /* java.net.Socket */
+
+    public void bind(SocketAddress endpoint) throws IOException {
+        s.bind(endpoint);
+    }
+
+    public void bind(SocketAddress ep, int bl) throws IOException {
+        s.bind(ep, bl);
+    }
+
+    public void close() throws IOException {
+        s.close();
+    }
+
+    public ServerSocketChannel getChannel() {
+        return s.getChannel();
+    }
+
+    public InetAddress getInetAddress() {
+        return s.getInetAddress();
+    }
+
+    public int getLocalPort() {
+        return s.getLocalPort();
+    }
+
+    public SocketAddress getLocalSocketAddress() {
+        return s.getLocalSocketAddress();
+    }
+
+    public int getReceiveBufferSize() throws SocketException {
+        return s.getReceiveBufferSize();
+    }
+
+    public boolean getReuseAddress() throws SocketException {
+        return s.getReuseAddress();
+    }
+
+    public int getSoTimeout() throws IOException {
+        return s.getSoTimeout();
+    }
+
+    public boolean isBound() {
+        return s.isBound();
+    }
+
+    public boolean isClosed() {
+        return s.isClosed();
+    }
+
+    public void setReceiveBufferSize(int size) throws SocketException {
+        s.setReceiveBufferSize(size);
+    }
+
+    public void setReuseAddress(boolean on) throws SocketException {
+        s.setReuseAddress(on);
+    }
+
+    public void setSoTimeout(int timeout) throws SocketException {
+        s.setSoTimeout(timeout);
+    }
+
+    public String toString() {
+        return s.toString();
+    }
+
+    /*  Java 1.5
+     public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
+     {
+         s.setPerformancePreferences( connectionTime, latency, bandwidth );
+     }
+     */
+
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java
new file mode 100644
index 0000000..4abeb11
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLSocketWrapper.java
@@ -0,0 +1,356 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLSocketWrapper.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SocketChannel;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 16-Aug-2006
+ */
+public class SSLSocketWrapper extends SSLSocket {
+    protected Socket s;
+
+    public SSLSocketWrapper(Socket s) {
+        this.s = s;
+    }
+
+    /* javax.net.ssl.SSLSocket */
+
+    public void addHandshakeCompletedListener(HandshakeCompletedListener hcl) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).addHandshakeCompletedListener(hcl);
+        }
+    }
+
+    public void removeHandshakeCompletedListener(HandshakeCompletedListener hcl) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).removeHandshakeCompletedListener(hcl);
+        }
+    }
+
+    public String[] getSupportedCipherSuites() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getSupportedCipherSuites();
+        } else {
+            return null;
+        }
+    }
+
+    public boolean getEnableSessionCreation() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getEnableSessionCreation();
+        } else {
+            return false;
+        }
+    }
+
+    public String[] getEnabledCipherSuites() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getEnabledCipherSuites();
+        } else {
+            return null;
+        }
+    }
+
+    public String[] getSupportedProtocols() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getSupportedProtocols();
+        } else {
+            return null;
+        }
+    }
+
+    public String[] getEnabledProtocols() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getEnabledProtocols();
+        } else {
+            return null;
+        }
+    }
+
+    public SSLSession getSession() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getSession();
+        } else {
+            return null;
+        }
+    }
+
+    public boolean getUseClientMode() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getUseClientMode();
+        } else {
+            return false;
+        }
+    }
+
+    public boolean getNeedClientAuth() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getNeedClientAuth();
+        } else {
+            return false;
+        }
+    }
+
+    public boolean getWantClientAuth() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getWantClientAuth();
+        } else {
+            return false;
+        }
+    }
+
+    public void setEnabledCipherSuites(String[] cs) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setEnabledCipherSuites(cs);
+        }
+    }
+
+    public void setEnabledProtocols(String[] ep) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setEnabledProtocols(ep);
+        }
+    }
+
+    public void startHandshake() throws IOException {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).startHandshake();
+        }
+    }
+
+    public void setUseClientMode(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setUseClientMode(b);
+        }
+    }
+
+    public void setNeedClientAuth(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setNeedClientAuth(b);
+        }
+    }
+
+    public void setWantClientAuth(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setWantClientAuth(b);
+        }
+    }
+
+    public void setEnableSessionCreation(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setEnableSessionCreation(b);
+        }
+    }
+
+    /* java.net.Socket */
+
+    public SocketChannel getChannel() {
+        return s.getChannel();
+    }
+
+    public InetAddress getInetAddress() {
+        return s.getInetAddress();
+    }
+
+    public boolean getKeepAlive() throws SocketException {
+        return s.getKeepAlive();
+    }
+
+    public InetAddress getLocalAddress() {
+        return s.getLocalAddress();
+    }
+
+    public int getLocalPort() {
+        return s.getLocalPort();
+    }
+
+    public SocketAddress getLocalSocketAddress() {
+        return s.getLocalSocketAddress();
+    }
+
+    public boolean getOOBInline() throws SocketException {
+        return s.getOOBInline();
+    }
+
+    public int getPort() {
+        return s.getPort();
+    }
+
+    public int getReceiveBufferSize() throws SocketException {
+        return s.getReceiveBufferSize();
+    }
+
+    public SocketAddress getRemoteSocketAddress() {
+        return s.getRemoteSocketAddress();
+    }
+
+    public boolean getReuseAddress() throws SocketException {
+        return s.getReuseAddress();
+    }
+
+    public int getSendBufferSize() throws SocketException {
+        return s.getSendBufferSize();
+    }
+
+    public int getSoLinger() throws SocketException {
+        return s.getSoLinger();
+    }
+
+    public int getSoTimeout() throws SocketException {
+        return s.getSoTimeout();
+    }
+
+    public boolean getTcpNoDelay() throws SocketException {
+        return s.getTcpNoDelay();
+    }
+
+    public int getTrafficClass() throws SocketException {
+        return s.getTrafficClass();
+    }
+
+    public boolean isBound() {
+        return s.isBound();
+    }
+
+    public boolean isClosed() {
+        return s.isClosed();
+    }
+
+    public boolean isConnected() {
+        return s.isConnected();
+    }
+
+    public boolean isInputShutdown() {
+        return s.isInputShutdown();
+    }
+
+    public boolean isOutputShutdown() {
+        return s.isOutputShutdown();
+    }
+
+    public void sendUrgentData(int data) throws IOException {
+        s.sendUrgentData(data);
+    }
+
+    public void setKeepAlive(boolean on) throws SocketException {
+        s.setKeepAlive(on);
+    }
+
+    public void setOOBInline(boolean on) throws SocketException {
+        s.setOOBInline(on);
+    }
+
+    public void setReceiveBufferSize(int size) throws SocketException {
+        s.setReceiveBufferSize(size);
+    }
+
+    public void setReuseAddress(boolean on) throws SocketException {
+        s.setReuseAddress(on);
+    }
+
+    public void setSendBufferSize(int size) throws SocketException {
+        s.setSendBufferSize(size);
+    }
+
+    public void setSoLinger(boolean on, int l) throws SocketException {
+        s.setSoLinger(on, l);
+    }
+
+    public void setSoTimeout(int timeout) throws SocketException {
+        s.setSoTimeout(timeout);
+    }
+
+    public void setTcpNoDelay(boolean on) throws SocketException {
+        s.setTcpNoDelay(on);
+    }
+
+    public void setTrafficClass(int tc) throws SocketException {
+        s.setTrafficClass(tc);
+    }
+
+    public void shutdownInput() throws IOException {
+        s.shutdownInput();
+    }
+
+    public void shutdownOutput() throws IOException {
+        s.shutdownOutput();
+    }
+
+    public String toString() {
+        return s.toString();
+    }
+
+    /*  Java 1.5
+     public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
+     {
+         s.setPerformancePreferences( connectionTime, latency, bandwidth );
+     }
+     */
+
+    public void bind(SocketAddress bindpoint) throws IOException {
+        s.bind(bindpoint);
+    }
+
+    public void close() throws IOException {
+        s.close();
+    }
+
+    public void connect(SocketAddress endpoint) throws IOException {
+        s.connect(endpoint);
+    }
+
+    public void connect(SocketAddress endpoint, int timeout) throws IOException {
+        s.connect(endpoint, timeout);
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return s.getInputStream();
+    }
+
+    public OutputStream getOutputStream() throws IOException {
+        return s.getOutputStream();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java
new file mode 100644
index 0000000..d6e68f7
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/SSLWrapperFactory.java
@@ -0,0 +1,107 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/SSLWrapperFactory.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import javax.net.ssl.SSLServerSocket;
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 19-Sep-2006
+ */
+public interface SSLWrapperFactory {
+
+    /**
+     * Wraps an SSLSSocket.
+     *
+     * @param s SSLSocket to wrap.
+     * @return The new wrapped SSLSocket.
+     * @throws java.io.IOException if wrapping failed
+     */
+    Socket wrap(Socket s) throws IOException;
+
+    /**
+     * Wraps an SSLServerSocket.
+     *
+     * @param s   The SSLServerSocket to wrap.
+     * @param ssl The SSL object that created the SSLServerSocket.
+     *            This way some important commons-ssl config can be applied
+     *            to the returned socket.
+     * @return The new wrapped SSLServerSocket.
+     * @throws java.io.IOException if wrapping failed
+     */
+    SSLServerSocket wrap(SSLServerSocket s, SSL ssl)
+        throws IOException;
+
+
+    /**
+     * NO_WRAP doesn't wrap the SSLSocket.  It does wrap the SSLServerSocket
+     * so that we can do the usual housekeeping after accept() that we like to
+     * do on every socket.  E.g. setSoTimeout, setEnabledProtocols,
+     * setEnabledCiphers, setUseClientMode, and the hostname verifier (which
+     * should be very rare on SSLServerSockets!).
+     */
+    SSLWrapperFactory NO_WRAP = new SSLWrapperFactory() {
+        // Notice!  No wrapping!
+        public Socket wrap(Socket s) {
+            return s;
+        }
+
+        // We still wrap the ServerSocket, but we don't wrap the result of the
+        // the accept() call.
+        public SSLServerSocket wrap(SSLServerSocket s, SSL ssl)
+            throws IOException {
+            return new SSLServerSocketWrapper(s, ssl, this);
+        }
+    };
+
+    /**
+     * DUMB_WRAP is useful to make sure that wrapping the sockets doesn't break
+     * anything.  It doesn't actually do anything interesting in its wrapped
+     * implementations.
+     */
+    SSLWrapperFactory DUMB_WRAP = new SSLWrapperFactory() {
+        public Socket wrap(Socket s) {
+            return new SSLSocketWrapper(s);
+        }
+
+        public SSLServerSocket wrap(SSLServerSocket s, SSL ssl)
+            throws IOException {
+            return new SSLServerSocketWrapper(s, ssl, this);
+        }
+    };
+
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a2c604ee/kerby-pkix/src/main/java/org/apache/commons/ssl/TrustChain.java
----------------------------------------------------------------------
diff --git a/kerby-pkix/src/main/java/org/apache/commons/ssl/TrustChain.java b/kerby-pkix/src/main/java/org/apache/commons/ssl/TrustChain.java
new file mode 100644
index 0000000..4340e6d
--- /dev/null
+++ b/kerby-pkix/src/main/java/org/apache/commons/ssl/TrustChain.java
@@ -0,0 +1,219 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/TrustChain.java $
+ * $Revision: 138 $
+ * $Date: 2008-03-03 23:50:07 -0800 (Mon, 03 Mar 2008) $
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.ssl;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @author Credit Union Central of British Columbia
+ * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
+ * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
+ * @since 27-Feb-2006
+ */
+public class TrustChain {
+    private final Set trustMaterial =
+        Collections.synchronizedSet(new HashSet());
+    private SortedSet x509Certificates = null;
+    private KeyStore unifiedKeyStore = null;
+
+    public TrustChain() {
+    }
+
+    public synchronized KeyStore getUnifiedKeyStore()
+        throws KeyStoreException, IOException, NoSuchAlgorithmException,
+        CertificateException {
+
+        // x509Certificates serves as our "cache available" indicator.
+        if (x509Certificates != null) {
+            return unifiedKeyStore;
+        }
+
+        // First, extract all the X509Certificates from this TrustChain.
+        this.x509Certificates = new TreeSet(Certificates.COMPARE_BY_EXPIRY);
+        Iterator it = trustMaterial.iterator();
+        while (it.hasNext()) {
+            TrustMaterial tm = (TrustMaterial) it.next();
+            KeyStore ks = tm.getKeyStore();
+            if (ks != null) {
+                Enumeration en = ks.aliases();
+                while (en.hasMoreElements()) {
+                    String alias = (String) en.nextElement();
+                    if (ks.isCertificateEntry(alias)) {
+                        X509Certificate cert;
+                        cert = (X509Certificate) ks.getCertificate(alias);
+                        if (!x509Certificates.contains(cert)) {
+                            x509Certificates.add(cert);
+                        }
+                    }
+                }
+            }
+        }
+
+        // Now that the X509Certificates are extracted, create the unified
+        // keystore.
+        it = x509Certificates.iterator();
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        ks.load(null, null);
+        int count = 0;
+        while (it.hasNext()) {
+            X509Certificate cert = (X509Certificate) it.next();
+            // The "count" should keep the aliases unique (is that important?)
+            String alias = "commons-ssl-" + count;
+            ks.setCertificateEntry(alias, cert);
+            count++;
+        }
+        this.unifiedKeyStore = ks;
+        return unifiedKeyStore;
+    }
+
+    public synchronized void addTrustMaterial(TrustChain tc) {
+        this.x509Certificates = null;  // invalidate cache
+        if (tc instanceof TrustMaterial) {
+            trustMaterial.add(tc);
+        }
+        // If duplicates are added, the Set will remove them.
+        trustMaterial.addAll(tc.trustMaterial);
+    }
+
+    public boolean contains(TrustChain tc) {
+        if (tc instanceof TrustMaterial) {
+            return trustMaterial.contains(tc);
+        } else {
+            return trustMaterial.containsAll(tc.trustMaterial);
+        }
+    }
+
+    public boolean contains(X509Certificate cert)
+        throws KeyStoreException, IOException, NoSuchAlgorithmException,
+        CertificateException {
+        return getCertificates().contains(cert);
+    }
+
+    public Object getTrustManagerFactory()
+        throws NoSuchAlgorithmException, KeyStoreException, IOException,
+        CertificateException {
+        KeyStore uks = getUnifiedKeyStore();
+        if (uks != null) {
+            return JavaImpl.newTrustManagerFactory(uks);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @return Array of TrustManager[] - presumably these will be dropped into
+     *         a call to SSLContext.init().  Note:  returns null if this
+     *         TrustChain doesn't contain anything to trust.
+     * @throws java.security.NoSuchAlgorithmException serious problems
+     * @throws java.security.KeyStoreException        serious problems
+     * @throws java.io.IOException              serious problems
+     * @throws java.security.cert.CertificateException     serious problems
+     */
+    public Object[] getTrustManagers()
+        throws NoSuchAlgorithmException, KeyStoreException, IOException,
+        CertificateException {
+        Object tmf = getTrustManagerFactory();
+        return tmf != null ? JavaImpl.getTrustManagers(tmf) : null;
+    }
+
+    /**
+     * @return All X509Certificates contained in this TrustChain as a SortedSet.
+     *         The X509Certificates are sorted based on expiry date.
+     *         <p/>
+     *         See org.apache.commons.ssl.Certificates.COMPARE_BY_EXPIRY.
+     * @throws java.security.KeyStoreException        serious problems
+     * @throws java.io.IOException              serious problems
+     * @throws java.security.NoSuchAlgorithmException serious problems
+     * @throws java.security.cert.CertificateException     serious problems
+     */
+    public synchronized SortedSet getCertificates()
+        throws KeyStoreException, IOException, NoSuchAlgorithmException,
+        CertificateException {
+        if (x509Certificates == null) {
+            getUnifiedKeyStore();
+        }
+        return Collections.unmodifiableSortedSet(x509Certificates);
+    }
+
+    /**
+     * @return Count of all X509Certificates contained in this TrustChain.
+     * @throws java.security.KeyStoreException
+     * @throws java.io.IOException
+     * @throws java.security.NoSuchAlgorithmException
+     * @throws java.security.cert.CertificateException
+     */
+    public synchronized int getSize()
+        throws KeyStoreException, IOException, NoSuchAlgorithmException,
+        CertificateException {
+        return getCertificates().size();
+    }
+
+    /**
+     * @return Count of all X509Certificates contained in this TrustChain.
+     * @throws java.security.KeyStoreException
+     * @throws java.io.IOException
+     * @throws java.security.NoSuchAlgorithmException
+     * @throws java.security.cert.CertificateException
+     */
+    public synchronized boolean isEmpty()
+        throws KeyStoreException, IOException, NoSuchAlgorithmException,
+        CertificateException {
+        return getCertificates().isEmpty();
+    }
+
+    protected boolean containsTrustAll() {
+        Iterator it = trustMaterial.iterator();
+        while (it.hasNext()) {
+            TrustChain tc = (TrustChain) it.next();
+            if (tc == this) {
+                continue;
+            }
+            if (tc.containsTrustAll()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}


Mime
View raw message