directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dran...@apache.org
Subject [02/18] directory-kerby git commit: Add back not-so-commons-ssl library and pki provider for pkinit support in the branch
Date Sat, 13 Jun 2015 10:45:26 GMT
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java
new file mode 100644
index 0000000..ca6d5a0
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/TrustMaterial.java
@@ -0,0 +1,281 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/TrustMaterial.java $
+ * $Revision: 171 $
+ * $Date: 2014-05-09 08:15:26 -0700 (Fri, 09 May 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 java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * @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 TrustMaterial extends TrustChain {
+    final static int SIMPLE_TRUST_TYPE_TRUST_ALL = 1;
+    final static int SIMPLE_TRUST_TYPE_TRUST_THIS_JVM = 2;
+
+    /**
+     * Might be null if "$JAVA_HOME/jre/lib/security/cacerts" doesn't exist.
+     */
+    public final static TrustMaterial CACERTS;
+
+    /**
+     * Might be null if "$JAVA_HOME/jre/lib/security/jssecacerts" doesn't exist.
+     */
+    public final static TrustMaterial JSSE_CACERTS;
+
+    /**
+     * Should never be null (unless both CACERTS and JSSE_CACERTS are not
+     * present???).  Is either CACERTS or JSSE_CACERTS.  Priority given to
+     * JSSE_CACERTS, but 99.9% of the time it's CACERTS, since JSSE_CACERTS
+     * is almost never present.
+     */
+    public final static TrustMaterial DEFAULT;
+
+    static {
+        JavaImpl.load();
+        String javaHome = System.getProperty("java.home");
+        String pathToCacerts = javaHome + "/lib/security/cacerts";
+        String pathToJSSECacerts = javaHome + "/lib/security/jssecacerts";
+        TrustMaterial cacerts = null;
+        TrustMaterial jssecacerts = null;
+        try {
+            File f = new File(pathToCacerts);
+            if (f.exists()) {
+                cacerts = new TrustMaterial(pathToCacerts);
+            }
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            File f = new File(pathToJSSECacerts);
+            if (f.exists()) {
+                jssecacerts = new TrustMaterial(pathToJSSECacerts);
+            }
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        CACERTS = cacerts;
+        JSSE_CACERTS = jssecacerts;
+        if (JSSE_CACERTS != null) {
+            DEFAULT = JSSE_CACERTS;
+        } else {
+            DEFAULT = CACERTS;
+        }
+    }
+
+    public final static TrustMaterial TRUST_ALL =
+        new TrustMaterial(SIMPLE_TRUST_TYPE_TRUST_ALL);
+
+    public final static TrustMaterial TRUST_THIS_JVM =
+        new TrustMaterial(SIMPLE_TRUST_TYPE_TRUST_THIS_JVM);
+
+    public final int simpleTrustType;
+    private final KeyStore jks;
+
+    private TrustMaterial(int simpleTrustType) {
+        this(null, simpleTrustType);
+    }
+
+    TrustMaterial(KeyStore jks, int simpleTrustType) {
+        if (jks == null && simpleTrustType != 0) {
+            // Just use CACERTS as a place holder, since Java 5 and 6 seem to get
+            // upset when we hand SSLContext null TrustManagers.  See
+            // Java14.initSSL(), which despite its name, is also used
+            // with Java5 and Java6.
+            this.jks = CACERTS != null ? CACERTS.jks : JSSE_CACERTS.jks;
+        } else {
+            this.jks = jks;
+        }
+        addTrustMaterial(this);
+        this.simpleTrustType = simpleTrustType;
+    }
+
+    public TrustMaterial(Collection x509Certs)
+        throws GeneralSecurityException, IOException {
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        ks.load(null, null);
+        loadCerts(ks, x509Certs);
+        this.jks = ks;
+        addTrustMaterial(this);
+
+        // We're not a simple trust type, so set value to 0.
+        // Only TRUST_ALL and TRUST_THIS_JVM are simple trust types.
+        this.simpleTrustType = 0;
+    }
+
+    public TrustMaterial(X509Certificate x509Cert)
+        throws GeneralSecurityException, IOException {
+        this(Collections.singleton(x509Cert));
+    }
+
+    public TrustMaterial(X509Certificate[] x509Certs)
+        throws GeneralSecurityException, IOException {
+        this(Arrays.asList(x509Certs));
+    }
+
+    public TrustMaterial(byte[] pemBase64)
+        throws GeneralSecurityException, IOException {
+        this(pemBase64, null);
+    }
+
+    public TrustMaterial(InputStream pemBase64)
+        throws GeneralSecurityException, IOException {
+        this(Util.streamToBytes(pemBase64));
+    }
+
+    public TrustMaterial(String pathToPemFile)
+        throws GeneralSecurityException, IOException {
+        this(new FileInputStream(pathToPemFile));
+    }
+
+    public TrustMaterial(File pemFile)
+        throws GeneralSecurityException, IOException {
+        this(new FileInputStream(pemFile));
+    }
+
+    public TrustMaterial(URL urlToPemFile)
+        throws GeneralSecurityException, IOException {
+        this(urlToPemFile.openStream());
+    }
+
+    public TrustMaterial(String pathToJksFile, char[] password)
+        throws GeneralSecurityException, IOException {
+        this(new File(pathToJksFile), password);
+    }
+
+    public TrustMaterial(File jksFile, char[] password)
+        throws GeneralSecurityException, IOException {
+        this(new FileInputStream(jksFile), password);
+    }
+
+    public TrustMaterial(URL urlToJKS, char[] password)
+        throws GeneralSecurityException, IOException {
+        this(urlToJKS.openStream(), password);
+    }
+
+    public TrustMaterial(InputStream jks, char[] password)
+        throws GeneralSecurityException, IOException {
+        this(Util.streamToBytes(jks), password);
+    }
+
+    public TrustMaterial(byte[] jks, char[] password)
+        throws GeneralSecurityException, IOException {
+
+        KeyStoreBuilder.BuildResult br;
+        br = KeyStoreBuilder.parse(jks, password, null, true);
+        if (br.jks != null) {
+            // If we've been given a keystore, just use that.
+            this.jks = br.jks;
+        } else {
+            // Otherwise we need to build a keystore from what we were given.
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            if (br.chains != null && !br.chains.isEmpty()) {
+                Certificate[] c = (Certificate[]) br.chains.get(0);
+                if (c.length > 0) {
+                    ks.load(null, password);
+                    loadCerts(ks, Arrays.asList(c));
+                }
+            }
+            this.jks = ks;
+        }
+
+        // Should validate our keystore to make sure it has at least ONE
+        // certificate entry:
+        KeyStore ks = this.jks;
+        boolean hasCertificates = false;
+        Enumeration en = ks.aliases();
+        while (en.hasMoreElements()) {
+            String alias = (String) en.nextElement();
+            if (ks.isCertificateEntry(alias)) {
+                hasCertificates = true;
+                break;
+            }
+        }
+        if (!hasCertificates) {
+            throw new KeyStoreException("TrustMaterial couldn't load any certificates to trust!");
+        }
+
+        addTrustMaterial(this);
+
+        // We're not a simple trust type, so set value to 0.
+        // Only TRUST_ALL and TRUST_THIS_JVM are simple trust types.
+        this.simpleTrustType = 0;
+    }
+
+    public KeyStore getKeyStore() {
+        return jks;
+    }
+
+    private static void loadCerts(KeyStore ks, Collection certs)
+        throws KeyStoreException {
+        Iterator it = certs.iterator();
+        int count = 0;
+        while (it.hasNext()) {
+            X509Certificate cert = (X509Certificate) it.next();
+
+            // I could be fancy and parse out the CN field from the
+            // certificate's subject, but these names don't actually matter
+            // at all - I think they just have to be unique.
+            String cn = Certificates.getCN(cert);
+            String alias = cn + "_" + count;
+            ks.setCertificateEntry(alias, cert);
+            count++;
+        }
+    }
+
+    protected boolean containsTrustAll() {
+        boolean yes = this.simpleTrustType == SIMPLE_TRUST_TYPE_TRUST_ALL;
+        if ( !yes ) {
+            yes = super.containsTrustAll();
+        }
+        return yes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java
new file mode 100644
index 0000000..45f716a
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Util.java
@@ -0,0 +1,452 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Util.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.ByteArrayReadLine;
+import org.apache.commons.ssl.util.IPAddressParser;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+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 28-Feb-2006
+ */
+public class Util {
+    public final static int SIZE_KEY = 0;
+    public final static int LAST_READ_KEY = 1;
+
+    /**
+     * True if the Keystores have the same # of entries, have the same set of aliases, and all the certificate-chains
+     * (of the certificate entries) match.   Does not check the private keys for equality, since we
+     * don't bother taking the passwords to get at them.
+     */
+    public static boolean equals(KeyStore ks1, KeyStore ks2) throws KeyStoreException {
+        if (ks1 == null || ks2 == null) {
+            return ks1 == null && ks2 == null;
+        }
+        Set<String> aliases1 = aliases(ks1);
+        Set<String> aliases2 = aliases(ks2);
+        if (aliases1.equals(aliases2)) {
+            for (String s : aliases1) {
+                if (ks1.isCertificateEntry(s) != ks2.isCertificateEntry(s)) {
+                    return false;
+                }
+                if (ks1.isKeyEntry(s) != ks2.isKeyEntry(s)) {
+                    return false;
+                }
+                if (ks1.isCertificateEntry(s)) {
+                    Certificate[] cc1 = ks1.getCertificateChain(s);
+                    Certificate[] cc2 = ks2.getCertificateChain(s);
+                    if (!Arrays.equals(cc1, cc2)) {
+                        return false;
+                    }
+
+                    Certificate c1 = ks1.getCertificate(s);
+                    Certificate c2 = ks2.getCertificate(s);
+                    if (!c1.equals(c2)) {
+                        return false;
+                    }
+                }
+
+                // should we bother checking keys?   maybe one day....
+            }
+        }
+        return true;
+    }
+
+    private static Set<String> aliases(KeyStore ks) throws KeyStoreException {
+        Set<String> aliases = new TreeSet<String>();
+        Enumeration<String> en = ks.aliases();
+        while (en.hasMoreElements()) {
+            aliases.add(en.nextElement());
+        }
+        return aliases;
+    }
+
+    public static boolean isYes(String yesString) {
+        if (yesString == null) {
+            return false;
+        }
+        String s = yesString.trim().toUpperCase();
+        return "1".equals(s) || "YES".equals(s) || "TRUE".equals(s) ||
+               "ENABLE".equals(s) || "ENABLED".equals(s) || "Y".equals(s) ||
+               "ON".equals(s);
+    }
+
+    public static String trim(final String s) {
+        if (s == null || "".equals(s)) {
+            return s;
+        }
+        int i = 0;
+        int j = s.length() - 1;
+        while (isWhiteSpace(s.charAt(i))) {
+            i++;
+        }
+        while (isWhiteSpace(s.charAt(j))) {
+            j--;
+        }
+        return j >= i ? s.substring(i, j + 1) : "";
+    }
+
+    public static boolean isWhiteSpace(final char c) {
+        switch (c) {
+            case 0:
+            case ' ':
+            case '\t':
+            case '\n':
+            case '\r':
+            case '\f':
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public static void pipeStream(InputStream in, OutputStream out)
+        throws IOException {
+        pipeStream(in, out, true);
+    }
+
+    public static void pipeStream(InputStream in, OutputStream out,
+                                  boolean autoClose)
+        throws IOException {
+        byte[] buf = new byte[8192];
+        IOException ioe = null;
+        try {
+            int bytesRead = in.read(buf);
+            while (bytesRead >= 0) {
+                if (bytesRead > 0) {
+                    out.write(buf, 0, bytesRead);
+                }
+                bytesRead = in.read(buf);
+            }
+        }
+        finally {
+            // Probably it's best to let consumer call "close", but I'm usually
+            // the consumer, and I want to be lazy.  [Julius, November 20th, 2006]
+            try { in.close(); } catch (IOException e) { ioe = e; }
+            if (autoClose) {
+                try { out.close(); } catch (IOException e) { ioe = e; }
+            }
+        }
+        if (ioe != null) {
+            throw ioe;
+        }
+    }
+
+    public static byte[] fileToBytes(final File f) throws IOException {
+        return streamToBytes(new FileInputStream(f));
+    }
+
+    public static byte[] streamToBytes(final ByteArrayInputStream in,
+                                       int maxLength) {
+        byte[] buf = new byte[maxLength];
+        int[] status = fill(buf, 0, in);
+        int size = status[SIZE_KEY];
+        if (buf.length != size) {
+            byte[] smallerBuf = new byte[size];
+            System.arraycopy(buf, 0, smallerBuf, 0, size);
+            buf = smallerBuf;
+        }
+        return buf;
+    }
+
+    public static byte[] streamToBytes(final InputStream in, int maxLength)
+        throws IOException {
+        byte[] buf = new byte[maxLength];
+        int[] status = fill(buf, 0, in);
+        int size = status[SIZE_KEY];
+        if (buf.length != size) {
+            byte[] smallerBuf = new byte[size];
+            System.arraycopy(buf, 0, smallerBuf, 0, size);
+            buf = smallerBuf;
+        }
+        return buf;
+    }
+
+    public static byte[] streamToBytes(final InputStream in) throws IOException {
+        byte[] buf = new byte[4096];
+        try {
+            int[] status = fill(buf, 0, in);
+            int size = status[SIZE_KEY];
+            int lastRead = status[LAST_READ_KEY];
+            while (lastRead != -1) {
+                buf = resizeArray(buf);
+                status = fill(buf, size, in);
+                size = status[SIZE_KEY];
+                lastRead = status[LAST_READ_KEY];
+            }
+            if (buf.length != size) {
+                byte[] smallerBuf = new byte[size];
+                System.arraycopy(buf, 0, smallerBuf, 0, size);
+                buf = smallerBuf;
+            }
+        }
+        finally {
+            in.close();
+        }
+        return buf;
+    }
+
+    public static byte[] streamToBytes(final ByteArrayInputStream in) {
+        byte[] buf = new byte[4096];
+        int[] status = fill(buf, 0, in);
+        int size = status[SIZE_KEY];
+        int lastRead = status[LAST_READ_KEY];
+        while (lastRead != -1) {
+            buf = resizeArray(buf);
+            status = fill(buf, size, in);
+            size = status[SIZE_KEY];
+            lastRead = status[LAST_READ_KEY];
+        }
+        if (buf.length != size) {
+            byte[] smallerBuf = new byte[size];
+            System.arraycopy(buf, 0, smallerBuf, 0, size);
+            buf = smallerBuf;
+        }
+        // in.close();  <-- this is a no-op on ByteArrayInputStream.
+        return buf;
+    }
+
+    public static int[] fill(final byte[] buf, final int offset,
+                             final InputStream in)
+        throws IOException {
+        int read = in.read(buf, offset, buf.length - offset);
+        int lastRead = read;
+        if (read == -1) {
+            read = 0;
+        }
+        while (lastRead != -1 && read + offset < buf.length) {
+            lastRead = in.read(buf, offset + read, buf.length - read - offset);
+            if (lastRead != -1) {
+                read += lastRead;
+            }
+        }
+        return new int[]{offset + read, lastRead};
+    }
+
+    public static int[] fill(final byte[] buf, final int offset,
+                             final ByteArrayInputStream in) {
+        int read = in.read(buf, offset, buf.length - offset);
+        int lastRead = read;
+        if (read == -1) {
+            read = 0;
+        }
+        while (lastRead != -1 && read + offset < buf.length) {
+            lastRead = in.read(buf, offset + read, buf.length - read - offset);
+            if (lastRead != -1) {
+                read += lastRead;
+            }
+        }
+        return new int[]{offset + read, lastRead};
+    }
+
+    public static byte[] resizeArray(final byte[] bytes) {
+        byte[] biggerBytes = new byte[bytes.length * 2];
+        System.arraycopy(bytes, 0, biggerBytes, 0, bytes.length);
+        return biggerBytes;
+    }
+
+    public static String pad(String s, final int length, final boolean left) {
+        if (s == null) {
+            s = "";
+        }
+        int diff = length - s.length();
+        if (diff == 0) {
+            return s;
+        } else if (diff > 0) {
+            StringBuffer sb = new StringBuffer();
+            if (left) {
+                for (int i = 0; i < diff; i++) {
+                    sb.append(' ');
+                }
+            }
+            sb.append(s);
+            if (!left) {
+                for (int i = 0; i < diff; i++) {
+                    sb.append(' ');
+                }
+            }
+            return sb.toString();
+        } else {
+            return s;
+        }
+    }
+
+    public static Map parseArgs(final String[] cargs) {
+        Map args = new TreeMap();
+        Map ARGS_MATCH = Ping.ARGS_MATCH;
+
+        int l = cargs.length;
+        final String[] EMPTY_VALUES = {""};
+        for (int i = 0; i < l; i++) {
+            String k = cargs[i];
+            Ping.Arg a = (Ping.Arg) ARGS_MATCH.get(k);
+            if (l > i + 1) {
+                String v = cargs[++i];
+                while (ARGS_MATCH.containsKey(v)) {
+                    args.put(a, EMPTY_VALUES);
+                    a = (Ping.Arg) ARGS_MATCH.get(v);
+                    v = "";
+                    if (l > i + 1) {
+                        v = cargs[++i];
+                    }
+                }
+                String[] values = new String[1];
+                values[0] = v;
+                args.put(a, values);
+                if (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) {
+                    LinkedList list = new LinkedList();
+                    list.add(v);
+                    while (l > i + 1 && !ARGS_MATCH.containsKey(cargs[i + 1])) {
+                        v = cargs[++i];
+                        list.add(v);
+                    }
+                    args.put(a, list.toArray(new String[list.size()]));
+                }
+            } else {
+                args.put(a, EMPTY_VALUES);
+            }
+        }
+        return args;
+    }
+
+    public static HostPort toAddress(final String target,
+                                     final int defaultPort)
+        throws UnknownHostException {
+        String host = target;
+        int port = defaultPort;
+        StringTokenizer st = new StringTokenizer(target, ":");
+        if (st.hasMoreTokens()) {
+            host = st.nextToken().trim();
+        }
+        if (st.hasMoreTokens()) {
+            port = Integer.parseInt(st.nextToken().trim());
+        }
+        if (st.hasMoreTokens()) {
+            throw new IllegalArgumentException("Invalid host: " + target);
+        }
+        return new HostPort(host, port);
+    }
+
+    public static String cipherToAuthType(String cipher) {
+        if (cipher == null) {
+            return null;
+        }
+
+        // SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA  ==> "DHE_DSS_EXPORT"
+        // SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA      ==> "DHE_DSS"
+        // SSL_RSA_WITH_3DES_EDE_CBC_SHA          ==> "RSA"
+
+        StringTokenizer st = new StringTokenizer(cipher.trim(), "_");
+        if (st.hasMoreTokens()) {
+            st.nextToken();  // always skip first token
+        }
+        if (st.hasMoreTokens()) {
+            String tok = st.nextToken();
+            StringBuffer buf = new StringBuffer();
+            buf.append(tok);
+            if (st.hasMoreTokens()) {
+                tok = st.nextToken();
+                while (!"WITH".equalsIgnoreCase(tok)) {
+                    buf.append('_');
+                    buf.append(tok);
+                    tok = st.nextToken();
+                }
+            }
+            return buf.toString();
+        }
+        throw new IllegalArgumentException("not a valid cipher: " + cipher);
+    }
+
+    /**
+     * Utility method to make sure IP-literals don't trigger reverse-DNS lookups.
+     */
+    public static InetAddress toInetAddress(String s) throws UnknownHostException {
+        byte[] ip = IPAddressParser.parseIPv4Literal(s);
+        if (ip == null) {
+            ip = IPAddressParser.parseIPv6Literal(s);
+        }
+        if (ip != null) {
+            // Strangely, this prevents Java's annoying SSL reverse-DNS lookup that it
+            // normally does, even with literal IP addresses.
+            return InetAddress.getByAddress(s, ip);
+        } else {
+            return InetAddress.getByName(s);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        String s = "line1\n\rline2\n\rline3";
+        ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
+        ByteArrayReadLine readLine = new ByteArrayReadLine(in);
+        String line = readLine.next();
+        while (line != null) {
+            System.out.println(line);
+            line = readLine.next();
+        }
+
+        System.out.println("--------- test 2 ----------");
+
+        s = "line1\n\rline2\n\rline3\n\r\n\r";
+        in = new ByteArrayInputStream(s.getBytes());
+        readLine = new ByteArrayReadLine(in);
+        line = readLine.next();
+        while (line != null) {
+            System.out.println(line);
+            line = readLine.next();
+        }
+
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java
new file mode 100644
index 0000000..04401a3
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Version.java
@@ -0,0 +1,197 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Version.java $
+ * $Revision: 130 $
+ * $Date: 2007-11-14 19:24:15 -0800 (Wed, 14 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 java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Extracts tagged version from a subversion $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Version.java $ property, and prints it
+ * out nicely on standard out.
+ * <p/>
+ * e.g. If this version came from /tags/commons-ssl-0_3_9/, then Version.java
+ * will print:  "Version: 0.3.9" on standard out.
+ *
+ * @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 14-Nov-2007
+ */
+public class Version {
+    public static final String HEAD_URL = "$HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Version.java $";
+    public static final String VERSION;
+    public static final String COMPILE_TIME;
+
+    static {
+        // Try to extract a clean version number from svn's HeadURL property:
+        String v = "UNKNOWN";
+        boolean fromBranch = false;
+        int x = HEAD_URL.lastIndexOf("/tags/");
+        if (x >= 0) {
+            int y = HEAD_URL.indexOf("/", x + "/tags/".length());
+            if (y >= 0) {
+                v = HEAD_URL.substring(x + "/tags/".length(), y);
+            }
+            v = v.replace('_', '.');
+            v = v.replace('-', '.');
+        } else if (HEAD_URL.indexOf("/trunk/") >= 0) {
+            v = "trunk";
+        } else if (HEAD_URL.indexOf("/branches/") >= 0) {
+            fromBranch = true;
+            x = HEAD_URL.indexOf("/branches/");
+            int y = HEAD_URL.indexOf("/", x + "/branches/".length());
+            if (y >= 0) {
+                v = HEAD_URL.substring(x + "/branches/".length(), y);
+            }
+            v = v.replace('_', '.');
+            v = v.replace('-', '.');
+        }
+
+        String V = v.toUpperCase();
+        x = V.indexOf("COMMONS.SSL.");
+        if (x >= 0) {
+            v = v.substring(x + "commons.ssl.".length());
+        }
+        VERSION = fromBranch ? "***Branch*** " + v : v;
+
+        // Try to calculate when jar file was compiled:
+        String s;
+        try {
+            s = CompileTime.getCompileTimeString(Version.class);
+        }
+        catch (NoClassDefFoundError e) {
+            s = null;
+        }
+        COMPILE_TIME = s;
+    }
+
+    public static String versionString() {
+        String v;
+        if (COMPILE_TIME != null) {
+            v = CompileTime.formatVersion(VERSION, COMPILE_TIME);
+        } else {
+            v = VERSION;
+        }
+        return "Version: " + v;
+    }
+
+    public static void main(String[] args) {
+        System.out.println(versionString());
+    }
+
+    public String toString() {
+        return versionString();
+    }
+
+
+    /**
+     * Searches through a jar file to the find the most recent timestamp of
+     * all the class files.
+     */
+    private static class CompileTime {
+        private final static String PATTERN = ".jar!";
+        private final static String PREFIX = "file:";
+        private final static String DF_FORMAT = "zzz:yyyy-MM-dd/HH:mm:ss.SSS";
+        private final static DateFormat DF = new SimpleDateFormat(DF_FORMAT);
+
+        public static String getCompileTimeString(Class clazz) {
+            String s = clazz.getName();
+            s = "/" + s.replace('.', '/') + ".class";
+            return getCompileTimeString(s);
+        }
+
+        private static String getCompileTimeString(String resource) {
+            try {
+                Date d = getCompileTime(resource);
+                return d != null ? DF.format(d) : "[unknown]";
+            }
+            catch (IOException ioe) {
+                return ioe.toString();
+            }
+        }
+
+        public static Date getCompileTime(String resource) throws IOException {
+            URL url = CompileTime.class.getResource(resource);
+            if (url != null) {
+                String urlString = url.getFile();
+                String fileLocation;
+                int i = urlString.indexOf(PATTERN);
+                if (i > 0) {
+                    int x = i + PATTERN.length() - 1;
+                    fileLocation = urlString.substring(0, x);
+                    if (fileLocation.startsWith(PREFIX)) {
+                        fileLocation = fileLocation.substring(PREFIX.length());
+                    }
+                    JarFile jf = new JarFile(fileLocation);
+                    long newestTime = 0;
+                    Enumeration entries = jf.entries();
+                    while (entries.hasMoreElements()) {
+                        JarEntry entry = (JarEntry) entries.nextElement();
+                        if (entry.getName().endsWith(".class")) {
+                            newestTime = Math.max(newestTime, entry.getTime());
+                        }
+                    }
+                    if (newestTime > 0) {
+                        return new Date(newestTime);
+                    }
+                } else {
+                    File f = new File(urlString);
+                    try {
+                        return new Date(f.lastModified());
+                    }
+                    catch (Exception e) {
+                        return null;
+                    }
+                }
+            }
+            return null;
+        }
+
+        public static String formatVersion(String version, String compileTime) {
+            StringBuffer buf = new StringBuffer();
+            buf.append(version);
+            buf.append("   Compiled: [");
+            buf.append(compileTime);
+            buf.append("]");
+            return buf.toString();
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java
new file mode 100644
index 0000000..fb2642f
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/X509CertificateChainBuilder.java
@@ -0,0 +1,204 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java $
+ * $Revision: 134 $
+ * $Date: 2008-02-26 21:30:48 -0800 (Tue, 26 Feb 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.FileInputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * Utility for building X509 certificate chains.
+ *
+ * @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-Nov-2005
+ */
+public class X509CertificateChainBuilder {
+    /**
+     * Builds the ordered certificate chain upwards from the startingPoint.
+     * Uses the supplied X509Certificate[] array to search for the parent,
+     * grandparent, and higher ancestor certificates.  Stops at self-signed
+     * certificates, or when no ancestor can be found.
+     * <p/>
+     * Thanks to Joe Whitney for helping me put together a Big-O( m * n )
+     * implementation where m = the length of the final certificate chain.
+     * For a while I was using a Big-O( n ^ 2 ) implementation!
+     *
+     * @param startingPoint the X509Certificate for which we want to find
+     *                      ancestors
+     * @param certificates  A pool of certificates in which we expect to find
+     *                      the startingPoint's ancestors.
+     * @return Array of X509Certificates, starting with the "startingPoint" and
+     *         ending with highest level ancestor we could find in the supplied
+     *         collection.
+     * @throws java.security.NoSuchAlgorithmException
+     *          on unsupported signature
+     *          algorithms.
+     * @throws java.security.InvalidKeyException
+     *          on incorrect key.
+     * @throws java.security.NoSuchProviderException
+     *          if there's no default provider.
+     * @throws java.security.cert.CertificateException
+     *          on encoding errors.
+     */
+    public static X509Certificate[] buildPath(X509Certificate startingPoint,
+                                              Certificate[] certificates)
+        throws NoSuchAlgorithmException, InvalidKeyException,
+        NoSuchProviderException, CertificateException {
+        // Use a LinkedList, because we do lots of random it.remove() operations.
+        return buildPath(startingPoint,
+            new LinkedList(Arrays.asList(certificates)));
+    }
+
+    /**
+     * Builds the ordered certificate chain upwards from the startingPoint.
+     * Uses the supplied collection to search for the parent, grandparent,
+     * and higher ancestor certificates.  Stops at self-signed certificates,
+     * or when no ancestor can be found.
+     * <p/>
+     * Thanks to Joe Whitney for helping me put together a Big-O( m * n )
+     * implementation where m = the length of the final certificate chain.
+     * For a while I was using a Big-O( n ^ 2 ) implementation!
+     *
+     * @param startingPoint the X509Certificate for which we want to find
+     *                      ancestors
+     * @param certificates  A pool of certificates in which we expect to find
+     *                      the startingPoint's ancestors.
+     * @return Array of X509Certificates, starting with the "startingPoint" and
+     *         ending with highest level ancestor we could find in the supplied
+     *         collection.
+     * @throws java.security.NoSuchAlgorithmException
+     *          on unsupported signature
+     *          algorithms.
+     * @throws java.security.InvalidKeyException
+     *          on incorrect key.
+     * @throws java.security.NoSuchProviderException
+     *          if there's no default provider.
+     * @throws java.security.cert.CertificateException
+     *          on encoding errors.
+     */
+    public static X509Certificate[] buildPath(X509Certificate startingPoint,
+                                              Collection certificates)
+        throws NoSuchAlgorithmException, InvalidKeyException,
+        NoSuchProviderException, CertificateException {
+        LinkedList path = new LinkedList();
+        path.add(startingPoint);
+        boolean nodeAdded = true;
+        // Keep looping until an iteration happens where we don't add any nodes
+        // to our path.
+        while (nodeAdded) {
+            // We'll start out by assuming nothing gets added.  If something
+            // gets added, then nodeAdded will be changed to "true".
+            nodeAdded = false;
+            X509Certificate top = (X509Certificate) path.getLast();
+            if (isSelfSigned(top)) {
+                // We're self-signed, so we're done!
+                break;
+            }
+
+            // Not self-signed.  Let's see if we're signed by anyone in the
+            // collection.
+            Iterator it = certificates.iterator();
+            while (it.hasNext()) {
+                X509Certificate x509 = (X509Certificate) it.next();
+                if (verify(top, x509.getPublicKey())) {
+                    // We're signed by this guy!  Add him to the chain we're
+                    // building up.
+                    path.add(x509);
+                    nodeAdded = true;
+                    it.remove(); // Not interested in this guy anymore!
+                    break;
+                }
+                // Not signed by this guy, let's try the next guy.
+            }
+        }
+        X509Certificate[] results = new X509Certificate[path.size()];
+        path.toArray(results);
+        return results;
+    }
+
+    public static boolean isSelfSigned(X509Certificate cert)
+        throws CertificateException, InvalidKeyException,
+        NoSuchAlgorithmException, NoSuchProviderException {
+
+        return verify(cert, cert.getPublicKey());
+    }
+
+    public static boolean verify(X509Certificate cert, PublicKey key)
+        throws CertificateException, InvalidKeyException,
+        NoSuchAlgorithmException, NoSuchProviderException {
+
+        String sigAlg = cert.getSigAlgName();
+        String keyAlg = key.getAlgorithm();
+        sigAlg = sigAlg != null ? sigAlg.trim().toUpperCase() : "";
+        keyAlg = keyAlg != null ? keyAlg.trim().toUpperCase() : "";
+        if (keyAlg.length() >= 2 && sigAlg.endsWith(keyAlg)) {
+            try {
+                cert.verify(key);
+                return true;
+            } catch (SignatureException se) {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length < 2) {
+            System.out.println("Usage: [special-one] [file-with-certs]");
+            System.exit(1);
+        }
+        FileInputStream f1 = new FileInputStream(args[0]);
+        FileInputStream f2 = new FileInputStream(args[1]);
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        X509Certificate theOne = (X509Certificate) cf.generateCertificate(f1);
+        Collection c = cf.generateCertificates(f2);
+
+        X509Certificate[] path = buildPath(theOne, c);
+        for (int i = 0; i < path.length; i++) {
+            System.out.println(Certificates.getCN(path[i]));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ByteArrayReadLine.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ByteArrayReadLine.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ByteArrayReadLine.java
new file mode 100644
index 0000000..88d0a29
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ByteArrayReadLine.java
@@ -0,0 +1,32 @@
+package org.apache.commons.ssl.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+public class ByteArrayReadLine extends ReadLine {
+
+    public ByteArrayReadLine(ByteArrayInputStream in) { super(in); }
+
+    public String next() { return next(1); }
+
+    public String next(int lines) {
+        try {
+            return super.next(lines);
+        } catch (IOException ioe) {
+            // impossible since we're using ByteArrayInputStream
+            throw new RuntimeException("impossible", ioe);
+        }
+    }
+
+    public byte[] nextAsBytes() { return nextAsBytes(1); }
+
+    public byte[] nextAsBytes(int lines) {
+        try {
+            return super.nextAsBytes(lines);
+        } catch (IOException ioe) {
+            // impossible since we're using ByteArrayInputStream
+            throw new RuntimeException("impossible", ioe);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/IPAddressParser.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/IPAddressParser.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/IPAddressParser.java
new file mode 100644
index 0000000..b0da817
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/IPAddressParser.java
@@ -0,0 +1,183 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/trunk/src/java/org/apache/commons/ssl/util/IPAddressParser.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.util;
+
+/**
+ * Parses String representations of IPv4 and IPv6 addresses, and converts
+ * them to byte[].  Returns null if the supplied String is not a valid IP
+ * address.
+ * <p/>
+ * IPv6 addresses are allowed to include square brackets (e.g., "[::a:b:c:d]"),
+ * but IPv4 addresses are not.  This is to help in situation where an IPv6
+ * literal address is encoded directly inside a URL (the square brackets allow
+ * the web client to separate the IPv6 address from its port, since the colon
+ * character is overloaded in that context).
+ */
+public class IPAddressParser {
+
+    /**
+     * Converts the supplied IPv4 literal to byte[], or null if the
+     * IPv4 address was invalid.
+     *
+     * @param s Literal IPv4 address.
+     * @return byte[] array or null if the supplied IPv4 address was invalid.
+     */
+    public static byte[] parseIPv4Literal(String s) {
+        s = s != null ? s.trim() : "";
+        String[] toks = s.split("\\.");
+        byte[] ip = new byte[4];
+        if (toks.length == 4) {
+            for (int i = 0; i < ip.length; i++) {
+                try {
+                    int val = Integer.parseInt(toks[i]);
+                    if (val < 0 || val > 255) {
+                        return null;
+                    }
+                    ip[i] = (byte) val;
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+            }
+            return ip;
+        }
+        return null;
+    }
+
+    /**
+     * Converts the supplied IPv6 literal to byte[], or null if the
+     * IPv6 address was invalid.
+     *
+     * @param s Literal IPv6 address.
+     * @return byte[] array or null if the supplied IPv6 address was invalid.
+     */
+    public static byte[] parseIPv6Literal(String s) {
+        s = s != null ? s.trim() : "";
+        if (s.length() > 0 && s.charAt(0) == '[' && s.charAt(s.length() - 1) == ']') {
+            s = s.substring(1, s.length() - 1).trim();
+        }
+        int x = s.lastIndexOf(':');
+        int y = s.indexOf('.');
+        // Contains a dot!  Look for IPv4 literal suffix.
+        if (x >= 0 && y > x) {
+            byte[] ip4Suffix = parseIPv4Literal(s.substring(x + 1));
+            if (ip4Suffix == null) {
+                return null;
+            }
+            s = s.substring(0, x) + ":" + ip4ToHex(ip4Suffix);
+        }
+
+        // Check that we only have a single occurence of "::".
+        x = s.indexOf("::");
+        if (x >= 0) {
+            if (s.indexOf("::", x + 1) >= 0) {
+                return null;
+            }
+        }
+
+        // This array helps us expand the "::" into the zeroes it represents.
+        String[] raw = new String[]{"0000", "0000", "0000", "0000", "0000", "0000", "0000", "0000"};
+        if (s.indexOf("::") >= 0) {
+            String[] split = s.split("::", -1);
+            String[] prefix = splitOnColon(split[0]);
+            String[] suffix = splitOnColon(split[1]);
+
+            // Make sure the "::" zero-expander has some room to expand!
+            if (prefix.length + suffix.length > 7) {
+                return null;
+            }
+            for (int i = 0; i < prefix.length; i++) {
+                raw[i] = prependZeroes(prefix[i]);
+            }
+            int startPos = raw.length - suffix.length;
+            for (int i = 0; i < suffix.length; i++) {
+                raw[startPos + i] = prependZeroes(suffix[i]);
+            }
+        } else {
+            // Okay, whew, no "::" zero-expander, but we still have to make sure
+            // each element contains 4 hex characters.
+            raw = splitOnColon(s);
+            if (raw.length != 8) {
+                return null;
+            }
+            for (int i = 0; i < raw.length; i++) {
+                raw[i] = prependZeroes(raw[i]);
+            }
+        }
+
+        byte[] ip6 = new byte[16];
+        int i = 0;
+        for (int j = 0; j < raw.length; j++) {
+            String tok = raw[j];
+            if (tok.length() > 4) {
+                return null;
+            }
+            String prefix = tok.substring(0, 2);
+            String suffix = tok.substring(2, 4);
+            try {
+                ip6[i++] = (byte) Integer.parseInt(prefix, 16);
+                ip6[i++] = (byte) Integer.parseInt(suffix, 16);
+            } catch (NumberFormatException nfe) {
+                return null;
+            }
+        }
+        return ip6;
+    }
+
+    private static String prependZeroes(String s) {
+        switch (s.length()) {
+            case 0: return "0000";
+            case 1: return "000" + s;
+            case 2: return "00" + s;
+            case 3: return "0" + s;
+            default: return s;
+        }
+    }
+
+    private static String[] splitOnColon(String s) {
+        if ("".equals(s)) {
+            return new String[]{};
+        } else {
+            return s.split(":");
+        }
+    }
+
+    private static String ip4ToHex(byte[] b) {
+        return b2s(b[0]) + b2s(b[1]) + ":" + b2s(b[2]) + b2s(b[3]);
+    }
+
+    private static String b2s(byte b) {
+        String s = Integer.toHexString(b >= 0 ? b : 256 + b);
+        if (s.length() < 2) {
+            s = "0" + s;
+        }
+        return s;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/PublicKeyDeriver.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/PublicKeyDeriver.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/PublicKeyDeriver.java
new file mode 100644
index 0000000..1ff15a0
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/PublicKeyDeriver.java
@@ -0,0 +1,82 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/trunk/src/java/org/apache/commons/ssl/Certificates.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.util;
+
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyException;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+/**
+ * Utility class for deriving a public key from a given private key.
+ *
+ * @author Chad La Joie <lajoie OF georgetown.edu>
+ * @since November 14th, 2007
+ */
+public class PublicKeyDeriver {
+
+    /**
+     * Utility method for deriving a public key from a given private key.
+     *
+     * @param key private key for which we need a public key (DSA or RSA).
+     * @return the corresponding public key
+     * @throws java.security.GeneralSecurityException if it didn't work
+     */
+    public static PublicKey derivePublicKey(PrivateKey key) throws GeneralSecurityException {
+        if (key instanceof DSAPrivateKey) {
+            DSAPrivateKey dsaKey = (DSAPrivateKey) key;
+            DSAParams keyParams = dsaKey.getParams();
+            BigInteger g = keyParams.getG();
+            BigInteger p = keyParams.getP();
+            BigInteger q = keyParams.getQ();
+            BigInteger x = dsaKey.getX();
+            BigInteger y = q.modPow(x, p);
+            DSAPublicKeySpec keySpec = new DSAPublicKeySpec(y, p, q, g);
+            return KeyFactory.getInstance("DSA").generatePublic(keySpec);
+        } else if (key instanceof RSAPrivateCrtKey) {
+            RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
+            BigInteger modulus = rsaKey.getModulus();
+            BigInteger exponent = rsaKey.getPublicExponent();
+            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
+            return KeyFactory.getInstance("RSA").generatePublic(keySpec);
+        } else {
+            throw new KeyException("Private key was not a DSA or RSA key");
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ReadLine.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ReadLine.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ReadLine.java
new file mode 100644
index 0000000..ee68016
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/util/ReadLine.java
@@ -0,0 +1,91 @@
+package org.apache.commons.ssl.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author Julius Davies
+ * @author 23-Dec-2007
+ */
+public class ReadLine {
+
+    final InputStream in;
+    final byte[] bytes = new byte[8192];
+    int pos = 0;
+    int avail = 0;
+
+    public ReadLine(InputStream in) { this.in = in; }
+
+    public String next() throws IOException { return next(1); }
+
+    public String next(int lines) throws IOException {
+        if (lines < 1) {
+            lines = 1;
+        }
+        StringBuffer buf = new StringBuffer(128 * lines);
+        if (avail <= 0 || pos >= avail) {
+            pos = 0;
+            avail = in.read(bytes);
+        }
+        while (avail >= 0) {
+            while (pos < avail) {
+                char c = (char) bytes[pos++];
+                switch (c) {
+                    case '\n':
+                    case '\r':
+                        lines--;
+                        if (lines < 1 && buf.length() > 0) {
+                            return buf.toString();
+                        }
+                        break;
+                    default:
+                        buf.append(c);
+                        break;
+                }
+            }
+            pos = 0;
+            avail = in.read(bytes);
+        }
+        return buf.length() > 0 ? buf.toString() : null;
+    }
+
+    public byte[] nextAsBytes() throws IOException { return nextAsBytes(1); }
+
+    public byte[] nextAsBytes(int lines) throws IOException {
+        if (lines < 1) {
+            lines = 1;
+        }
+        byte[] buf = new byte[8192];
+        int bufPos = 0;
+        if (avail <= 0 || pos >= avail) {
+            pos = 0;
+            avail = in.read(bytes);
+        }
+        while (avail >= 0) {
+            while (pos < avail) {
+                byte b = bytes[pos++];
+                switch (b) {
+                    case '\n':
+                    case '\r':
+                        lines--;
+                        if (lines == 0 && bufPos > 0) {
+                            return buf;
+                        }
+                        break;
+                    default:
+                        if (bufPos >= buf.length) {
+                            byte[] moreBuff = new byte[buf.length * 2];
+                            System.arraycopy(buf, 0, moreBuff, 0, buf.length);
+                            buf = moreBuff;
+                        }
+                        buf[bufPos++] = b;
+                        break;
+                }
+            }
+            pos = 0;
+            avail = in.read(bytes);
+        }
+        return bufPos > 0 ? buf : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/JUnitConfig.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/JUnitConfig.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/JUnitConfig.java
new file mode 100644
index 0000000..2318737
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/JUnitConfig.java
@@ -0,0 +1,46 @@
+package org.apache.commons.ssl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+public class JUnitConfig {
+
+    public final static String TEST_HOME;
+
+    static {
+        String home = "";
+        File f = new File(System.getProperty("user.home") + "/.commons-ssl.test.properties");
+        if (f.exists()) {
+            Properties p = new Properties();
+
+            boolean loaded = false;
+            FileInputStream fin = null;
+            try {
+                fin = new FileInputStream(f);
+                p.load(fin);
+                loaded = true;
+            } catch (IOException ioe) {
+                System.err.println("Failed to load: " + f);
+            } finally {
+                if (fin != null) {
+                    try {
+                        fin.close();
+                    } catch (IOException ioe) {
+                        System.err.println("Failed to close: " + f);
+                    }
+                }
+            }
+
+            if (loaded) {
+                home = p.getProperty("commons-ssl.home");
+                if (!home.endsWith("/")) {
+                    home = home + "/";
+                }
+            }
+        }
+        TEST_HOME = home;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestBase64.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestBase64.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestBase64.java
new file mode 100644
index 0000000..9bb9074
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestBase64.java
@@ -0,0 +1,92 @@
+package org.apache.commons.ssl;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.kerby.util.Base64;
+import org.apache.kerby.util.Base64InputStream;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+import java.util.Random;
+
+
+public class TestBase64 {
+
+    @Test
+    public void testOrigBase64() throws Exception {
+        Random random = new Random();
+        for (int i = 0; i < 4567; i++) {
+            byte[] buf = new byte[i];
+            random.nextBytes(buf);
+            byte[] enc = Base64.encodeBase64(buf);
+            ByteArrayInputStream in = new ByteArrayInputStream(enc);
+            enc = Util.streamToBytes(in);
+            byte[] dec = Base64.decodeBase64(enc);
+            boolean result = Arrays.equals(buf, dec);
+            if (!result) {
+                System.out.println();
+                System.out.println("testOrigBase64 Failed on : " + i);
+            }
+            assertTrue(result);
+        }
+        for (int i = 5; i < 50; i++) {
+            int testSize = (i * 1000) + 123;
+            byte[] buf = new byte[testSize];
+            random.nextBytes(buf);
+            byte[] enc = Base64.encodeBase64(buf);
+            ByteArrayInputStream in = new ByteArrayInputStream(enc);
+            enc = Util.streamToBytes(in);            
+            byte[] dec = Base64.decodeBase64(enc);
+            boolean result = Arrays.equals(buf, dec);
+            if (!result) {
+                System.out.println();
+                System.out.println("testOrigBase64 Failed on : " + testSize);
+            }
+            assertTrue(result);
+        }
+    }
+
+    @Test
+    public void testBase64() throws Exception {
+        Random random = new Random();
+        for (int i = 0; i < 4567; i++) {
+            byte[] buf = new byte[i];
+            random.nextBytes(buf);
+
+            ByteArrayInputStream in = new ByteArrayInputStream( buf );
+            Base64InputStream base64 = new Base64InputStream(in,true);
+            byte[] enc = Util.streamToBytes(base64);
+            in = new ByteArrayInputStream( enc );
+            base64 = new Base64InputStream(in);
+            byte[] dec = Util.streamToBytes(base64);
+
+            boolean result = Arrays.equals(buf, dec);
+            if (!result) {
+                System.out.println();
+                System.out.println("testBase64 Failed on : " + i);                                
+            }
+            assertTrue(result);
+        }
+        for (int i = 5; i < 50; i++) {
+            int testSize = (i * 1000) + 123;
+            byte[] buf = new byte[testSize];
+            random.nextBytes(buf);
+
+            ByteArrayInputStream in = new ByteArrayInputStream( buf );
+            Base64InputStream base64 = new Base64InputStream(in,true);
+            byte[] enc = Util.streamToBytes(base64);
+            in = new ByteArrayInputStream( enc );
+            base64 = new Base64InputStream(in);
+            byte[] dec = Util.streamToBytes(base64);
+
+            boolean result = Arrays.equals(buf, dec);
+            if (!result) {
+                System.out.println();
+                System.out.println("testBase64 Failed on : " + testSize);
+            }
+            assertTrue(result);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestCertificates.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestCertificates.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestCertificates.java
new file mode 100644
index 0000000..cc90191
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestCertificates.java
@@ -0,0 +1,87 @@
+package org.apache.commons.ssl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import static org.apache.commons.ssl.JUnitConfig.TEST_HOME;
+import static org.mockito.Mockito.when;
+
+/**
+ * Created by julius on 06/09/14.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class TestCertificates {
+
+    @Mock
+    private X509Certificate x509;
+
+    @Test
+    public void testGetCNsMocked() {
+        X500Principal normal = new X500Principal("CN=abc,OU=ou,O=o,C=canada,EMAILADDRESS=bob@bob.com");
+        X500Principal bad1 = new X500Principal("CN=\"abc,CN=foo.com,\",OU=ou,O=o,C=canada,EMAILADDRESS=bob@bob.com");
+        X500Principal bad2 = new X500Principal("ou=\",CN=evil.ca,\",  CN=good.net");
+
+        when(x509.getSubjectX500Principal()).thenReturn(normal);
+        String[] cns = Certificates.getCNs(x509);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("abc", cns[0]);
+
+        when(x509.getSubjectX500Principal()).thenReturn(bad2);
+        cns = Certificates.getCNs(x509);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("good.net", cns[0]);
+
+        when(x509.getSubjectX500Principal()).thenReturn(bad1);
+        cns = Certificates.getCNs(x509);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("abc,CN=foo.com,", cns[0]);
+    }
+
+    @Test
+    public void testGetCNsReal() throws IOException, GeneralSecurityException {
+        String samplesDir = TEST_HOME + "samples/x509";
+
+        TrustMaterial tm = new TrustMaterial(samplesDir + "/x509_three_cns_foo_bar_hanako.pem");
+        X509Certificate c = (X509Certificate) tm.getCertificates().first();
+        String[] cns = Certificates.getCNs(c);
+        Assert.assertEquals(3, cns.length);
+        Assert.assertEquals("foo.com", cns[0]);
+        Assert.assertEquals("bar.com", cns[1]);
+        Assert.assertEquals("花子.co.jp", cns[2]);
+
+        tm = new TrustMaterial(samplesDir + "/x509_foo_bar_hanako.pem");
+        c = (X509Certificate) tm.getCertificates().first();
+        cns = Certificates.getCNs(c);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("foo.com", cns[0]);
+
+        tm = new TrustMaterial(samplesDir + "/x509_wild_co_jp.pem");
+        c = (X509Certificate) tm.getCertificates().first();
+        cns = Certificates.getCNs(c);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("*.co.jp", cns[0]);
+
+        tm = new TrustMaterial(samplesDir + "/x509_wild_foo_bar_hanako.pem");
+        c = (X509Certificate) tm.getCertificates().first();
+        cns = Certificates.getCNs(c);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("*.foo.com", cns[0]);
+
+        tm = new TrustMaterial(samplesDir + "/x509_wild_foo.pem");
+        c = (X509Certificate) tm.getCertificates().first();
+        cns = Certificates.getCNs(c);
+        Assert.assertEquals(1, cns.length);
+        Assert.assertEquals("*.foo.com", cns[0]);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestIPAddressParser.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestIPAddressParser.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestIPAddressParser.java
new file mode 100644
index 0000000..4c3cfa0
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestIPAddressParser.java
@@ -0,0 +1,77 @@
+package org.apache.commons.ssl;
+
+import static org.apache.commons.ssl.util.IPAddressParser.*;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class TestIPAddressParser {
+
+    @Test
+    public void theTest() {
+
+        // bad ones
+        assertNull("ip6 invalid", parseIPv6Literal(":::"));
+        assertNull("ip6 too many zero-expanders", parseIPv6Literal("1::1::"));
+        assertNull("ip6 .256 invalid", parseIPv6Literal("1::1:255.254.253.256"));
+        assertNull("ip6 too small", parseIPv6Literal("1:2:3:4"));
+        assertNull("ip6 no zero-expander after ip4", parseIPv6Literal("1:255.254.253.252::"));
+        assertNull("ip6 no zero-expander if 7 colons (end)", parseIPv6Literal("1:2:3:4:5:6:7:8::"));
+        assertNull("ip6 no zero-expander if 7 colons (begin)", parseIPv6Literal("::1:2:3:4:5:6:7:8"));
+        assertNull("ip6 88888 too many digits", parseIPv6Literal("1:2:3:4:5:6:7:88888"));
+        assertNull("ip6 missing colons", parseIPv6Literal("abcd"));
+        assertNull("ip6 umm, no", parseIPv6Literal("cookie monster"));
+        assertNull("ip6 empty string is invalid", parseIPv6Literal(""));
+        assertNull("ip6 null is invalid", parseIPv6Literal(null));
+
+        assertNull("ip4 not enough dots", parseIPv4Literal("abcd"));
+        assertNull("ip4 umm, no", parseIPv4Literal("cookie monster"));
+        assertNull("ip4 empty string is invalid", parseIPv4Literal(""));
+        assertNull("ip4 null is invalid", parseIPv4Literal(null));
+        assertNull("ip4 not enough dots 0", parseIPv4Literal("1"));
+        assertNull("ip4 not enough dots 1", parseIPv4Literal("1.2"));
+        assertNull("ip4 not enough dots 2", parseIPv4Literal("1.2.3"));
+        assertNull("ip4 needs digit after final dot", parseIPv4Literal("1.2.3."));
+        assertNull("ip4 [0-9] digits only", parseIPv4Literal("1.2.3.a"));
+        assertNull("ip4 too many dots", parseIPv4Literal("1.2.3.4.5"));
+        assertNull("ip4 0-255 range", parseIPv4Literal("1.2.3.444"));
+        assertNull("ip4 no negatives", parseIPv4Literal("1.2.-3.4"));
+        assertNull("ip4 no brackets", parseIPv4Literal("[1.2.3.4]"));
+
+        // good ones
+        assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, parseIPv6Literal("::"));
+        assertArrayEquals(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, parseIPv6Literal("1::"));
+        assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, parseIPv6Literal("::1"));
+        assertArrayEquals(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, parseIPv6Literal("1::1"));
+        assertArrayEquals(new byte[]{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, parseIPv6Literal("100::1"));
+
+        assertArrayEquals(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -2, -3, -4},
+                parseIPv6Literal("1::1:255.254.253.252"));
+
+        assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -4},
+                parseIPv6Literal("::255.254.253.252"));
+
+        assertArrayEquals(new byte[]{0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, -1, -2, -3, -4},
+                parseIPv6Literal("1:2:3:4:5:6:255.254.253.252"));
+
+        assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4}, parseIPv6Literal("::1:2:3:4"));
+        assertArrayEquals(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 4}, parseIPv6Literal("1::2:3:4"));
+        assertArrayEquals(new byte[]{0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4}, parseIPv6Literal("1:2::3:4"));
+        assertArrayEquals(new byte[]{0, 1, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}, parseIPv6Literal("1:2:3::4"));
+        assertArrayEquals(new byte[]{0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, parseIPv6Literal("1:2:3:4::"));
+
+        assertArrayEquals(new byte[]{0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8},
+                parseIPv6Literal("1:2:3:4:5:6:7:8"));
+
+        assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, parseIPv6Literal("[::]"));
+
+        assertArrayEquals(new byte[]{0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8},
+                parseIPv6Literal("[1:2:3:4:5:6:7:8]"));
+
+        assertArrayEquals(new byte[]{17, 17, 34, 34, 51, 51, 68, 68, 85, 85, 102, 102, 119, 119, -120, -120},
+                parseIPv6Literal("1111:2222:3333:4444:5555:6666:7777:8888"));
+
+        assertArrayEquals(new byte[]{0, 0, 0, 0}, parseIPv4Literal("0.0.0.0"));
+        assertArrayEquals(new byte[]{1, 2, 3, 4}, parseIPv4Literal("1.2.3.4"));
+        assertArrayEquals(new byte[]{-1, -1, -1, -1}, parseIPv4Literal("255.255.255.255"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestKeyMaterial.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestKeyMaterial.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestKeyMaterial.java
new file mode 100644
index 0000000..01932ec
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestKeyMaterial.java
@@ -0,0 +1,118 @@
+package org.apache.commons.ssl;
+
+import static org.apache.commons.ssl.JUnitConfig.TEST_HOME;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import javax.net.ssl.SSLSocket;
+
+public class TestKeyMaterial {
+    public static final char[] PASSWORD1 = "changeit".toCharArray();
+    public static final char[] PASSWORD2 = "itchange".toCharArray();
+
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    @Test
+    public void testKeystores() throws Exception {
+        String samplesDir = TEST_HOME + "samples/keystores";
+        File dir = new File(samplesDir);
+        String[] files = dir.list();
+        Arrays.sort(files, String.CASE_INSENSITIVE_ORDER);
+        for (String f : files) {
+            String F = f.toUpperCase(Locale.ENGLISH);
+            if (F.endsWith(".KS") || F.contains("PKCS12")) {
+                examineKeyStore(samplesDir, f, null);
+            } else if (F.endsWith(".PEM")) {
+                examineKeyStore(samplesDir, f, "rsa.key");
+            }
+        }
+    }
+
+    private static void examineKeyStore(String dir, String fileName, String file2) throws Exception {
+        String FILENAME = fileName.toUpperCase(Locale.ENGLISH);
+        boolean hasMultiPassword = FILENAME.contains(".2PASS.");
+
+        System.out.print("Testing KeyMaterial: " + dir + "/" + fileName);        
+        char[] pass1 = PASSWORD1;
+        char[] pass2 = PASSWORD1;
+        if (hasMultiPassword) {
+            pass2 = PASSWORD2;
+        }
+
+        file2 = file2 != null ? dir + "/" + file2 : null;
+
+        Date today = new Date();
+        KeyMaterial km;
+        try {
+            km = new KeyMaterial(dir + "/" + fileName, file2, pass1, pass2);
+        } catch (ProbablyBadPasswordException pbpe) {
+            System.out.println("  WARN:  " + pbpe);
+            return;
+        }
+        assertEquals("keymaterial-contains-1-alias", 1, km.getAliases().size());
+        for (X509Certificate[] cert : (List<X509Certificate[]>) km.getAssociatedCertificateChains()) {
+            for (X509Certificate c : cert) {
+                assertTrue("certchain-valid-dates", c.getNotAfter().after(today));
+            }
+        }
+
+        SSLServer server = new SSLServer();
+        server.setKeyMaterial(km);
+        ServerSocket ss = server.createServerSocket(0);
+        int port = ss.getLocalPort();
+        startServerThread(ss);
+        Thread.sleep(1);
+
+
+        SSLClient client = new SSLClient();
+        client.setTrustMaterial(TrustMaterial.TRUST_ALL);
+        client.setCheckHostname(false);
+        SSLSocket s = (SSLSocket) client.createSocket("localhost", port);
+        s.getSession().getPeerCertificates();
+        InputStream in = s.getInputStream();
+        Util.streamToBytes(in);
+        in.close();
+        // System.out.println(Certificates.toString((X509Certificate) certs[0]));
+        s.close();
+
+        System.out.println("\t SUCCESS! ");
+    }
+
+
+    private static void startServerThread(final ServerSocket ss) {
+        Runnable r = new Runnable() {
+            public void run() {
+                try {
+                    Socket s = ss.accept();
+                    OutputStream out = s.getOutputStream();
+                    Thread.sleep(1);
+                    out.write("Hello From Server\n".getBytes());
+                    Thread.sleep(1);
+                    out.close();
+                    s.close();
+                } catch (Exception e) {
+
+                    System.out.println("Test ssl server exception: " + e);
+
+                }
+            }
+        };
+
+        new Thread(r).start();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestOpenSSL.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestOpenSSL.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestOpenSSL.java
new file mode 100644
index 0000000..d44a260
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestOpenSSL.java
@@ -0,0 +1,150 @@
+package org.apache.commons.ssl;
+
+import static org.apache.commons.ssl.JUnitConfig.TEST_HOME;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Random;
+
+public class TestOpenSSL {
+
+    public void encTest(String cipher) throws Exception {
+        Random random = new Random();
+        char[] pwd = {'!', 'E', 'i', 'k', 'o', '?'};
+
+        for (int i = 0; i < 4567; i++) {
+            byte[] buf = new byte[i];
+            random.nextBytes(buf);
+            byte[] enc = OpenSSL.encrypt(cipher, pwd, buf);
+            byte[] dec = OpenSSL.decrypt(cipher, pwd, enc);
+            boolean result = Arrays.equals(buf, dec);
+            if (!result) {
+                System.out.println();
+                System.out.println("Failed on : " + i);
+            }
+            assertTrue(result);
+        }
+
+        for (int i = 5; i < 50; i++) {
+            int testSize = (i * 1000) + 123;
+            byte[] buf = new byte[testSize];
+            random.nextBytes(buf);
+            byte[] enc = OpenSSL.encrypt(cipher, pwd, buf);
+            byte[] dec = OpenSSL.decrypt(cipher, pwd, enc);
+            boolean result = Arrays.equals(buf, dec);
+            if (!result) {
+                System.out.println();
+                System.out.println("Failed on : " + testSize);
+            }
+            assertTrue(result);
+        }
+
+    }
+
+    @Test
+    public void testDES3Bytes() throws Exception {
+        encTest("des3");
+    }
+
+    @Test
+    public void testAES128Bytes() throws Exception {
+        encTest("aes128");
+    }
+
+    @Test
+    public void testRC2Bytes() throws Exception {
+        encTest("rc2");
+    }
+
+    @Test
+    public void testDESBytes() throws Exception {
+        encTest("des");
+    }
+
+    @Test
+    public void testDecryptPBE() throws Exception {
+        File d = new File(TEST_HOME + "samples/pbe");
+        File[] files = d.listFiles();
+        if (files == null) {
+            fail("No testDecryptPBE() files to test!");
+        }
+        int testCount = 0;
+        Arrays.sort(files);
+        for (File f : files) {
+            testCount += process(f, 0);
+        }
+        System.out.println(testCount + " pbe test files successfully decrypted.");
+    }
+
+    private static int process(File f, int depth) throws Exception {
+        int sum = 0;
+        String name = f.getName();
+        if ("CVS".equalsIgnoreCase(name)) {
+            return 0;
+        }
+        if (".svn".equalsIgnoreCase(name)) {
+            return 0;
+        }
+        if (name.toUpperCase().startsWith("README")) {
+            return 0;
+        }
+
+        if (f.isDirectory()) {
+            if (depth <= 7) {
+                File[] files = f.listFiles();
+                if (files == null) {
+                    return 0;
+                }
+                Arrays.sort(files);
+                for (File ff : files) {
+                    sum += process(ff, depth + 1);
+                }
+            } else {
+                System.out.println("IGNORING [" + f + "].  Directory too deep (" + depth + ").");
+            }
+        } else {
+            if (f.isFile() && f.canRead()) {
+                String fileName = f.getName();
+                int x = fileName.indexOf('.');
+                if (x < 0) {
+                    return 0;
+                }
+                String cipher = fileName.substring(0, x);
+                String cipherPadded = Util.pad(cipher, 20, false);
+                String filePadded = Util.pad(fileName, 25, false);
+                FileInputStream in = null;
+                try {
+                    in = new FileInputStream(f);
+                    byte[] encrypted = Util.streamToBytes(in);
+                    char[] pwd = "changeit".toCharArray();
+                    try {
+                        byte[] result = OpenSSL.decrypt(cipher, pwd, encrypted);
+                        String s = new String(result, "ISO-8859-1");
+                        assertTrue(cipherPadded + "." + filePadded + " decrypts to 'Hello World!'", "Hello World!".equals(s));
+                        return 1;
+                    } catch (NoSuchAlgorithmException nsae) {
+                        System.out.println("Warn: " + cipherPadded + filePadded + " NoSuchAlgorithmException");
+                        return 0;
+                    } catch (ArithmeticException ae) {
+                        if (cipherPadded.contains("cfb1")) {
+                            System.out.println("Warn: " + cipherPadded + filePadded + " BouncyCastle can't handle cfb1 " + ae);
+                            return 0;
+                        } else {
+                            throw ae;
+                        }
+                    }
+                } finally {
+                    if (in != null) {
+                        in.close();
+                    }
+                }
+            }
+        }
+        return sum;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/6eb9f15e/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestPKCS8Key.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestPKCS8Key.java b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestPKCS8Key.java
new file mode 100644
index 0000000..91d6c17
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/test/java/org/apache/commons/ssl/TestPKCS8Key.java
@@ -0,0 +1,57 @@
+package org.apache.commons.ssl;
+
+import static org.apache.commons.ssl.JUnitConfig.TEST_HOME;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class TestPKCS8Key {
+
+    @Test
+    public void testDSA() throws Exception {
+        checkFiles("dsa");
+    }
+
+    @Test
+    public void testRSA() throws Exception {
+        checkFiles("rsa");
+    }
+
+    private static void checkFiles(String type) throws Exception {
+        String password = "changeit";
+        File dir = new File(TEST_HOME + "samples/" + type);
+        File[] files = dir.listFiles();
+        if (files == null) {
+            fail("No files to test!");
+            return;
+        }
+        byte[] original = null;
+        for (File f : files) {
+            String filename = f.getName();
+            String FILENAME = filename.toUpperCase(Locale.ENGLISH);
+            if (!FILENAME.endsWith(".PEM") && !FILENAME.endsWith(".DER")) {
+                // not a sample file
+                continue;
+            }
+
+            System.out.println("Checking PKCS file:" + filename);
+            if (filename.equals("pkcs8v1_rsa_md2_des1.der")) {
+                FileInputStream in = new FileInputStream(f);
+                byte[] bytes = Util.streamToBytes(in);
+                PKCS8Key key = new PKCS8Key(bytes, password.toCharArray());
+                byte[] decrypted = key.getDecryptedBytes();
+                if (original == null) {
+                    original = decrypted;
+                } else {
+                    boolean identical = Arrays.equals(original, decrypted);
+                    assertTrue(f.getCanonicalPath() + " - all " + type + " samples decrypt to same key", identical);
+                }
+            }
+        }
+
+    }
+}


Mime
View raw message