You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/01/10 14:31:10 UTC

[26/42] directory-kerberos git commit: Initially import Haox codebase (https://github.com/drankye/haox)

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Certificates.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Certificates.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Certificates.java
new file mode 100644
index 0000000..99259c8
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Certificates.java
@@ -0,0 +1,591 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Certificates.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.naming.InvalidNameException;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import javax.security.auth.x500.X500Principal;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.*;
+import java.math.BigInteger;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.HttpURLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.lang.reflect.Method;
+
+/**
+ * @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-Aug-2005
+ */
+public class Certificates {
+
+    public final static CertificateFactory CF;
+    public final static String LINE_ENDING = System.getProperty("line.separator");
+
+    private final static HashMap crl_cache = new HashMap();
+
+    public final static String CRL_EXTENSION = "2.5.29.31";
+    public final static String OCSP_EXTENSION = "1.3.6.1.5.5.7.1.1";
+    private final static DateFormat DF = new SimpleDateFormat("yyyy/MMM/dd");
+
+    public interface SerializableComparator extends Comparator, Serializable {
+    }
+
+    public final static SerializableComparator COMPARE_BY_EXPIRY =
+        new SerializableComparator() {
+            public int compare(Object o1, Object o2) {
+                X509Certificate c1 = (X509Certificate) o1;
+                X509Certificate c2 = (X509Certificate) o2;
+                if (c1 == c2) // this deals with case where both are null
+                {
+                    return 0;
+                }
+                if (c1 == null)  // non-null is always bigger than null
+                {
+                    return -1;
+                }
+                if (c2 == null) {
+                    return 1;
+                }
+                if (c1.equals(c2)) {
+                    return 0;
+                }
+                Date d1 = c1.getNotAfter();
+                Date d2 = c2.getNotAfter();
+                int c = d1.compareTo(d2);
+                if (c == 0) {
+                    String s1 = JavaImpl.getSubjectX500(c1);
+                    String s2 = JavaImpl.getSubjectX500(c2);
+                    c = s1.compareTo(s2);
+                    if (c == 0) {
+                        s1 = JavaImpl.getIssuerX500(c1);
+                        s2 = JavaImpl.getIssuerX500(c2);
+                        c = s1.compareTo(s2);
+                        if (c == 0) {
+                            BigInteger big1 = c1.getSerialNumber();
+                            BigInteger big2 = c2.getSerialNumber();
+                            c = big1.compareTo(big2);
+                            if (c == 0) {
+                                try {
+                                    byte[] b1 = c1.getEncoded();
+                                    byte[] b2 = c2.getEncoded();
+                                    int len1 = b1.length;
+                                    int len2 = b2.length;
+                                    int i = 0;
+                                    for (; i < len1 && i < len2; i++) {
+                                        c = ((int) b1[i]) - ((int) b2[i]);
+                                        if (c != 0) {
+                                            break;
+                                        }
+                                    }
+                                    if (c == 0) {
+                                        c = b1.length - b2.length;
+                                    }
+                                }
+                                catch (CertificateEncodingException cee) {
+                                    // I give up.  They can be equal if they
+                                    // really want to be this badly.
+                                    c = 0;
+                                }
+                            }
+                        }
+                    }
+                }
+                return c;
+            }
+        };
+
+    static {
+        CertificateFactory cf = null;
+        try {
+            cf = CertificateFactory.getInstance("X.509");
+        }
+        catch (CertificateException ce) {
+            ce.printStackTrace(System.out);
+        }
+        finally {
+            CF = cf;
+        }
+    }
+
+    public static String toPEMString(X509Certificate cert)
+        throws CertificateEncodingException {
+        return toString(cert.getEncoded());
+    }
+
+    public static String toString(byte[] x509Encoded) {
+        byte[] encoded = Base64.encodeBase64(x509Encoded);
+        StringBuffer buf = new StringBuffer(encoded.length + 100);
+        buf.append("-----BEGIN CERTIFICATE-----\n");
+        for (int i = 0; i < encoded.length; i += 64) {
+            if (encoded.length - i >= 64) {
+                buf.append(new String(encoded, i, 64));
+            } else {
+                buf.append(new String(encoded, i, encoded.length - i));
+            }
+            buf.append(LINE_ENDING);
+        }
+        buf.append("-----END CERTIFICATE-----");
+        buf.append(LINE_ENDING);
+        return buf.toString();
+    }
+
+    public static String toString(X509Certificate cert) {
+        return toString(cert, false);
+    }
+
+    public static String toString(X509Certificate cert, boolean htmlStyle) {
+        String cn = getCN(cert);
+        String startStart = DF.format(cert.getNotBefore());
+        String endDate = DF.format(cert.getNotAfter());
+        String subject = JavaImpl.getSubjectX500(cert);
+        String issuer = JavaImpl.getIssuerX500(cert);
+        Iterator crls = getCRLs(cert).iterator();
+        if (subject.equals(issuer)) {
+            issuer = "self-signed";
+        }
+        StringBuffer buf = new StringBuffer(128);
+        if (htmlStyle) {
+            buf.append("<strong class=\"cn\">");
+        }
+        buf.append(cn);
+        if (htmlStyle) {
+            buf.append("</strong>");
+        }
+        buf.append(LINE_ENDING);
+        buf.append("Valid: ");
+        buf.append(startStart);
+        buf.append(" - ");
+        buf.append(endDate);
+        buf.append(LINE_ENDING);
+        buf.append("s: ");
+        buf.append(subject);
+        buf.append(LINE_ENDING);
+        buf.append("i: ");
+        buf.append(issuer);
+        while (crls.hasNext()) {
+            buf.append(LINE_ENDING);
+            buf.append("CRL: ");
+            buf.append((String) crls.next());
+        }
+        buf.append(LINE_ENDING);
+        return buf.toString();
+    }
+
+    public static List getCRLs(X509Extension cert) {
+        // What follows is a poor man's CRL extractor, for those lacking
+        // a BouncyCastle "bcprov.jar" in their classpath.
+
+        // It's a very basic state-machine:  look for a standard URL scheme
+        // (such as http), and then start looking for a terminator.  After
+        // running hexdump a few times on these things, it looks to me like
+        // the UTF-8 value "65533" seems to happen near where these things
+        // terminate.  (Of course this stuff is ASN.1 and not UTF-8, but
+        // I happen to like some of the functions available to the String
+        // object).    - juliusdavies@cucbc.com, May 10th, 2006
+        byte[] bytes = cert.getExtensionValue(CRL_EXTENSION);
+        LinkedList httpCRLS = new LinkedList();
+        LinkedList ftpCRLS = new LinkedList();
+        LinkedList otherCRLS = new LinkedList();
+        if (bytes == null) {
+            // just return empty list
+            return httpCRLS;
+        } else {
+            String s;
+            try {
+                s = new String(bytes, "UTF-8");
+            }
+            catch (UnsupportedEncodingException uee) {
+                // We're screwed if this thing has more than one CRL, because
+                // the "indeOf( (char) 65533 )" below isn't going to work.
+                s = new String(bytes);
+            }
+            int pos = 0;
+            while (pos >= 0) {
+                int x = -1, y;
+                int[] indexes = new int[4];
+                indexes[0] = s.indexOf("http", pos);
+                indexes[1] = s.indexOf("ldap", pos);
+                indexes[2] = s.indexOf("file", pos);
+                indexes[3] = s.indexOf("ftp", pos);
+                Arrays.sort(indexes);
+                for (int i = 0; i < indexes.length; i++) {
+                    if (indexes[i] >= 0) {
+                        x = indexes[i];
+                        break;
+                    }
+                }
+                if (x >= 0) {
+                    y = s.indexOf((char) 65533, x);
+                    String crl = y > x ? s.substring(x, y - 1) : s.substring(x);
+                    if (y > x && crl.endsWith("0")) {
+                        crl = crl.substring(0, crl.length() - 1);
+                    }
+                    String crlTest = crl.trim().toLowerCase();
+                    if (crlTest.startsWith("http")) {
+                        httpCRLS.add(crl);
+                    } else if (crlTest.startsWith("ftp")) {
+                        ftpCRLS.add(crl);
+                    } else {
+                        otherCRLS.add(crl);
+                    }
+                    pos = y;
+                } else {
+                    pos = -1;
+                }
+            }
+        }
+
+        httpCRLS.addAll(ftpCRLS);
+        httpCRLS.addAll(otherCRLS);
+        return httpCRLS;
+    }
+
+    public static void checkCRL(X509Certificate cert)
+        throws CertificateException {
+        // String name = cert.getSubjectX500Principal().toString();
+        byte[] bytes = cert.getExtensionValue("2.5.29.31");
+        if (bytes == null) {
+            // log.warn( "Cert doesn't contain X509v3 CRL Distribution Points (2.5.29.31): " + name );
+        } else {
+            List crlList = getCRLs(cert);
+            Iterator it = crlList.iterator();
+            while (it.hasNext()) {
+                String url = (String) it.next();
+                CRLHolder holder = (CRLHolder) crl_cache.get(url);
+                if (holder == null) {
+                    holder = new CRLHolder(url);
+                    crl_cache.put(url, holder);
+                }
+                // success == false means we couldn't actually load the CRL
+                // (probably due to an IOException), so let's try the next one in
+                // our list.
+                boolean success = holder.checkCRL(cert);
+                if (success) {
+                    break;
+                }
+            }
+        }
+
+    }
+
+    public static BigInteger getFingerprint(X509Certificate x509)
+        throws CertificateEncodingException {
+        return getFingerprint(x509.getEncoded());
+    }
+
+    public static BigInteger getFingerprint(byte[] x509)
+        throws CertificateEncodingException {
+        MessageDigest sha1;
+        try {
+            sha1 = MessageDigest.getInstance("SHA1");
+        }
+        catch (NoSuchAlgorithmException nsae) {
+            throw JavaImpl.newRuntimeException(nsae);
+        }
+
+        sha1.reset();
+        byte[] result = sha1.digest(x509);
+        return new BigInteger(result);
+    }
+
+    private static class CRLHolder {
+        private final String urlString;
+
+        private File tempCRLFile;
+        private long creationTime;
+        private Set passedTest = new HashSet();
+        private Set failedTest = new HashSet();
+
+        CRLHolder(String urlString) {
+            if (urlString == null) {
+                throw new NullPointerException("urlString can't be null");
+            }
+            this.urlString = urlString;
+        }
+
+        public synchronized boolean checkCRL(X509Certificate cert)
+            throws CertificateException {
+            CRL crl = null;
+            long now = System.currentTimeMillis();
+            if (now - creationTime > 24 * 60 * 60 * 1000) {
+                // Expire cache every 24 hours
+                if (tempCRLFile != null && tempCRLFile.exists()) {
+                    tempCRLFile.delete();
+                }
+                tempCRLFile = null;
+                passedTest.clear();
+
+                /*
+                      Note:  if any certificate ever fails the check, we will
+                      remember that fact.
+
+                      This breaks with temporary "holds" that CRL's can issue.
+                      Apparently a certificate can have a temporary "hold" on its
+                      validity, but I'm not interested in supporting that.  If a "held"
+                      certificate is suddenly "unheld", you're just going to need
+                      to restart your JVM.
+                    */
+                // failedTest.clear();  <-- DO NOT UNCOMMENT!
+            }
+
+            BigInteger fingerprint = getFingerprint(cert);
+            if (failedTest.contains(fingerprint)) {
+                throw new CertificateException("Revoked by CRL (cached response)");
+            }
+            if (passedTest.contains(fingerprint)) {
+                return true;
+            }
+
+            if (tempCRLFile == null) {
+                try {
+                    // log.info( "Trying to load CRL [" + urlString + "]" );
+
+                    // java.net.URL blocks forever by default, so CRL-checking
+                    // is freezing some systems.  Below we go to great pains
+                    // to enforce timeouts for CRL-checking (5 seconds).
+                    URL url = new URL(urlString);
+                    URLConnection urlConn = url.openConnection();
+                    if (urlConn instanceof HttpsURLConnection) {
+
+                        // HTTPS sites will use special CRLSocket.getInstance() SocketFactory
+                        // that is configured to timeout after 5 seconds:
+                        HttpsURLConnection httpsConn = (HttpsURLConnection) urlConn;
+                        httpsConn.setSSLSocketFactory(CRLSocket.getSecureInstance());
+
+                    } else if (urlConn instanceof HttpURLConnection) {
+
+                        // HTTP timeouts can only be set on Java 1.5 and up.  :-(
+                        // The code required to set it for Java 1.4 and Java 1.3 is just too painful.
+                        HttpURLConnection httpConn = (HttpURLConnection) urlConn;
+                        try {
+                            // Java 1.5 and up support these, so using reflection.  UGH!!!
+                            Class c = httpConn.getClass();
+                            Method setConnTimeOut = c.getDeclaredMethod("setConnectTimeout", new Class[]{Integer.TYPE});
+                            Method setReadTimeout = c.getDeclaredMethod("setReadTimeout", new Class[]{Integer.TYPE});
+                            setConnTimeOut.invoke(httpConn, Integer.valueOf(5000));
+                            setReadTimeout.invoke(httpConn, Integer.valueOf(5000));
+                        } catch (NoSuchMethodException nsme) {
+                            // oh well, java 1.4 users can suffer.
+                        } catch (Exception e) {
+                            throw new RuntimeException("can't set timeout", e);
+                        }
+                    }
+
+                    File tempFile = File.createTempFile("crl", ".tmp");
+                    tempFile.deleteOnExit();
+
+                    OutputStream out = new FileOutputStream(tempFile);
+                    out = new BufferedOutputStream(out);
+                    InputStream in = new BufferedInputStream(urlConn.getInputStream());
+                    try {
+                        Util.pipeStream(in, out);
+                    }
+                    catch (IOException ioe) {
+                        // better luck next time
+                        tempFile.delete();
+                        throw ioe;
+                    }
+                    this.tempCRLFile = tempFile;
+                    this.creationTime = System.currentTimeMillis();
+                }
+                catch (IOException ioe) {
+                    // log.warn( "Cannot check CRL: " + e );
+                }
+            }
+
+            if (tempCRLFile != null && tempCRLFile.exists()) {
+                try {
+                    InputStream in = new FileInputStream(tempCRLFile);
+                    in = new BufferedInputStream(in);
+                    synchronized (CF) {
+                        crl = CF.generateCRL(in);
+                    }
+                    in.close();
+                    if (crl.isRevoked(cert)) {
+                        // log.warn( "Revoked by CRL [" + urlString + "]: " + name );
+                        passedTest.remove(fingerprint);
+                        failedTest.add(fingerprint);
+                        throw new CertificateException("Revoked by CRL");
+                    } else {
+                        passedTest.add(fingerprint);
+                    }
+                }
+                catch (IOException ioe) {
+                    // couldn't load CRL that's supposed to be stored in Temp file.
+                    // log.warn(  );
+                }
+                catch (CRLException crle) {
+                    // something is wrong with the CRL
+                    // log.warn(  );
+                }
+            }
+            return crl != null;
+        }
+    }
+
+    public static String getCN(X509Certificate cert) {
+        String[] cns = getCNs(cert);
+        boolean foundSomeCNs = cns != null && cns.length >= 1;
+        return foundSomeCNs ? cns[0] : null;
+    }
+
+    public static String[] getCNs(X509Certificate cert) {
+        try {
+            final String subjectPrincipal = cert.getSubjectX500Principal().getName(X500Principal.RFC2253);
+            final LinkedList<String> cnList = new LinkedList<String>();
+            final LdapName subjectDN = new LdapName(subjectPrincipal);
+            for (final Rdn rds : subjectDN.getRdns()) {
+                final Attributes attributes = rds.toAttributes();
+                final Attribute cn = attributes.get("cn");
+                if (cn != null) {
+                    try {
+                        final Object value = cn.get();
+                        if (value != null) {
+                            cnList.add(value.toString());
+                        }
+                    } catch (NoSuchElementException ignore) {
+                    } catch (NamingException ignore) {
+                    }
+                }
+            }
+            if (!cnList.isEmpty()) {
+                return cnList.toArray(new String[cnList.size()]);
+            }
+        } catch (InvalidNameException ignore) {
+        }
+        return null;
+    }
+
+    /**
+     * Extracts the array of SubjectAlt DNS names from an X509Certificate.
+     * Returns null if there aren't any.
+     * <p/>
+     * Note:  Java doesn't appear able to extract international characters
+     * from the SubjectAlts.  It can only extract international characters
+     * from the CN field.
+     * <p/>
+     * (Or maybe the version of OpenSSL I'm using to test isn't storing the
+     * international characters correctly in the SubjectAlts?).
+     *
+     * @param cert X509Certificate
+     * @return Array of SubjectALT DNS names stored in the certificate.
+     */
+    public static String[] getDNSSubjectAlts(X509Certificate cert) {
+        LinkedList subjectAltList = new LinkedList();
+        Collection c = null;
+        try {
+            c = cert.getSubjectAlternativeNames();
+        }
+        catch (CertificateParsingException cpe) {
+            // Should probably log.debug() this?
+            cpe.printStackTrace();
+        }
+        if (c != null) {
+            Iterator it = c.iterator();
+            while (it.hasNext()) {
+                List list = (List) it.next();
+                int type = ((Integer) list.get(0)).intValue();
+                // If type is 2, then we've got a dNSName
+                if (type == 2) {
+                    String s = (String) list.get(1);
+                    subjectAltList.add(s);
+                }
+            }
+        }
+        if (!subjectAltList.isEmpty()) {
+            String[] subjectAlts = new String[subjectAltList.size()];
+            subjectAltList.toArray(subjectAlts);
+            return subjectAlts;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Trims off any null entries on the array.  Returns a shrunk array.
+     *
+     * @param chain X509Certificate[] chain to trim
+     * @return Shrunk array with all trailing null entries removed.
+     */
+    public static Certificate[] trimChain(Certificate[] chain) {
+        for (int i = 0; i < chain.length; i++) {
+            if (chain[i] == null) {
+                X509Certificate[] newChain = new X509Certificate[i];
+                System.arraycopy(chain, 0, newChain, 0, i);
+                return newChain;
+            }
+        }
+        return chain;
+    }
+
+    /**
+     * Returns a chain of type X509Certificate[].
+     *
+     * @param chain Certificate[] chain to cast to X509Certificate[]
+     * @return chain of type X509Certificate[].
+     */
+    public static X509Certificate[] x509ifyChain(Certificate[] chain) {
+        if (chain instanceof X509Certificate[]) {
+            return (X509Certificate[]) chain;
+        } else {
+            X509Certificate[] x509Chain = new X509Certificate[chain.length];
+            System.arraycopy(chain, 0, x509Chain, 0, chain.length);
+            return x509Chain;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        for (int i = 0; i < args.length; i++) {
+            FileInputStream in = new FileInputStream(args[i]);
+            TrustMaterial tm = new TrustMaterial(in);
+            Iterator it = tm.getCertificates().iterator();
+            while (it.hasNext()) {
+                X509Certificate x509 = (X509Certificate) it.next();
+                System.out.println(toString(x509));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/ComboInputStream.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/ComboInputStream.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/ComboInputStream.java
new file mode 100644
index 0000000..54d5dde
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/ComboInputStream.java
@@ -0,0 +1,96 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/ComboInputStream.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 java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @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 22-Feb-2007
+ */
+public class ComboInputStream extends InputStream {
+    private boolean headDone;
+    private InputStream head;
+    private InputStream tail;
+
+    public ComboInputStream(InputStream head, InputStream tail) {
+        this.head = head != null ? head : tail;
+        this.tail = tail != null ? tail : head;
+    }
+
+    public int read() throws IOException {
+        int c;
+        if (headDone) {
+            c = tail.read();
+        } else {
+            c = head.read();
+            if (c == -1) {
+                headDone = true;
+                c = tail.read();
+            }
+        }
+        return c;
+    }
+
+    public int available() throws IOException {
+        return tail.available() + head.available();
+    }
+
+    public void close() throws IOException {
+        try {
+            head.close();
+        }
+        finally {
+            if (head != tail) {
+                tail.close();
+            }
+        }
+    }
+
+    public int read(byte b[], int off, int len) throws IOException {
+        int c;
+        if (headDone) {
+            c = tail.read(b, off, len);
+        } else {
+            c = head.read(b, off, len);
+            if (c == -1) {
+                headDone = true;
+                c = tail.read(b, off, len);
+            }
+        }
+        return c;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/DerivedKey.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/DerivedKey.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/DerivedKey.java
new file mode 100644
index 0000000..7005187
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/DerivedKey.java
@@ -0,0 +1,49 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/DerivedKey.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;
+
+/**
+ * @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 7-Nov-2006
+ */
+public class DerivedKey {
+    public final byte[] key;
+    public final byte[] iv;
+
+    DerivedKey(byte[] key, byte[] iv) {
+        this.key = key;
+        this.iv = iv;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostPort.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostPort.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostPort.java
new file mode 100644
index 0000000..56a8139
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostPort.java
@@ -0,0 +1,57 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/HostPort.java $
+ * $Revision: 166 $
+ * $Date: 2014-04-28 11:40:25 -0700 (Mon, 28 Apr 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.IPAddressParser;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * @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-July-2006
+ */
+public class HostPort {
+    public final String host;
+    public final int port;
+    public final InetAddress addr;
+
+    public HostPort(String host, int port) throws UnknownHostException {
+        this.host = host;
+        this.port = port;
+        this.addr = Util.toInetAddress(host);
+    }
+
+    public String toString() { return host + ":" + port; }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostnameVerifier.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostnameVerifier.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostnameVerifier.java
new file mode 100644
index 0000000..e797abe
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HostnameVerifier.java
@@ -0,0 +1,481 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/HostnameVerifier.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.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+/**
+ * Interface for checking if a hostname matches the names stored inside the
+ * server's X.509 certificate.  Correctly implements
+ * javax.net.ssl.HostnameVerifier, but that interface is not recommended.
+ * Instead we added several check() methods that take SSLSocket,
+ * or X509Certificate, or ultimately (they all end up calling this one),
+ * String.  (It's easier to supply JUnit with Strings instead of mock
+ * SSLSession objects!)
+ * </p><p>Our check() methods throw exceptions if the name is
+ * invalid, whereas javax.net.ssl.HostnameVerifier just returns true/false.
+ * <p/>
+ * We provide the HostnameVerifier.DEFAULT, HostnameVerifier.STRICT, and
+ * HostnameVerifier.ALLOW_ALL implementations.  We also provide the more
+ * specialized HostnameVerifier.DEFAULT_AND_LOCALHOST, as well as
+ * HostnameVerifier.STRICT_IE6.  But feel free to define your own
+ * implementations!
+ * <p/>
+ * Inspired by Sebastian Hauer's original StrictSSLProtocolSocketFactory in the
+ * HttpClient "contrib" repository.
+ *
+ * @author Julius Davies
+ * @author <a href="mailto:hauer@psicode.com">Sebastian Hauer</a>
+ * @since 8-Dec-2006
+ */
+public interface HostnameVerifier extends javax.net.ssl.HostnameVerifier {
+
+    boolean verify(String host, SSLSession session);
+
+    void check(String host, SSLSocket ssl) throws IOException;
+
+    void check(String host, X509Certificate cert) throws SSLException;
+
+    void check(String host, String[] cns, String[] subjectAlts)
+        throws SSLException;
+
+    void check(String[] hosts, SSLSocket ssl) throws IOException;
+
+    void check(String[] hosts, X509Certificate cert) throws SSLException;
+
+
+    /**
+     * Checks to see if the supplied hostname matches any of the supplied CNs
+     * or "DNS" Subject-Alts.  Most implementations only look at the first CN,
+     * and ignore any additional CNs.  Most implementations do look at all of
+     * the "DNS" Subject-Alts. The CNs or Subject-Alts may contain wildcards
+     * according to RFC 2818.
+     *
+     * @param cns         CN fields, in order, as extracted from the X.509
+     *                    certificate.
+     * @param subjectAlts Subject-Alt fields of type 2 ("DNS"), as extracted
+     *                    from the X.509 certificate.
+     * @param hosts       The array of hostnames to verify.
+     * @throws javax.net.ssl.SSLException If verification failed.
+     */
+    void check(String[] hosts, String[] cns, String[] subjectAlts)
+        throws SSLException;
+
+
+    /**
+     * The DEFAULT HostnameVerifier works the same way as Curl and Firefox.
+     * <p/>
+     * The hostname must match either the first CN, or any of the subject-alts.
+     * A wildcard can occur in the CN, and in any of the subject-alts.
+     * <p/>
+     * The only difference between DEFAULT and STRICT is that a wildcard (such
+     * as "*.foo.com") with DEFAULT matches all subdomains, including
+     * "a.b.foo.com".
+     */
+    public final static HostnameVerifier DEFAULT =
+        new AbstractVerifier() {
+            public final void check(final String[] hosts, final String[] cns,
+                                    final String[] subjectAlts)
+                throws SSLException {
+                check(hosts, cns, subjectAlts, false, false);
+            }
+
+            public final String toString() { return "DEFAULT"; }
+        };
+
+
+    /**
+     * The DEFAULT_AND_LOCALHOST HostnameVerifier works like the DEFAULT
+     * one with one additional relaxation:  a host of "localhost",
+     * "localhost.localdomain", "127.0.0.1", "::1" will always pass, no matter
+     * what is in the server's certificate.
+     */
+    public final static HostnameVerifier DEFAULT_AND_LOCALHOST =
+        new AbstractVerifier() {
+            public final void check(final String[] hosts, final String[] cns,
+                                    final String[] subjectAlts)
+                throws SSLException {
+                if (isLocalhost(hosts[0])) {
+                    return;
+                }
+                check(hosts, cns, subjectAlts, false, false);
+            }
+
+            public final String toString() { return "DEFAULT_AND_LOCALHOST"; }
+        };
+
+    /**
+     * The STRICT HostnameVerifier works the same way as java.net.URL in Sun
+     * Java 1.4, Sun Java 5, Sun Java 6.  It's also pretty close to IE6.
+     * This implementation appears to be compliant with RFC 2818 for dealing
+     * with wildcards.
+     * <p/>
+     * The hostname must match either the first CN, or any of the subject-alts.
+     * A wildcard can occur in the CN, and in any of the subject-alts.  The
+     * one divergence from IE6 is how we only check the first CN.  IE6 allows
+     * a match against any of the CNs present.  We decided to follow in
+     * Sun Java 1.4's footsteps and only check the first CN.
+     * <p/>
+     * A wildcard such as "*.foo.com" matches only subdomains in the same
+     * level, for example "a.foo.com".  It does not match deeper subdomains
+     * such as "a.b.foo.com".
+     */
+    public final static HostnameVerifier STRICT =
+        new AbstractVerifier() {
+            public final void check(final String[] host, final String[] cns,
+                                    final String[] subjectAlts)
+                throws SSLException {
+                check(host, cns, subjectAlts, false, true);
+            }
+
+            public final String toString() { return "STRICT"; }
+        };
+
+    /**
+     * The STRICT_IE6 HostnameVerifier works just like the STRICT one with one
+     * minor variation:  the hostname can match against any of the CN's in the
+     * server's certificate, not just the first one.  This behaviour is
+     * identical to IE6's behaviour.
+     */
+    public final static HostnameVerifier STRICT_IE6 =
+        new AbstractVerifier() {
+            public final void check(final String[] host, final String[] cns,
+                                    final String[] subjectAlts)
+                throws SSLException {
+                check(host, cns, subjectAlts, true, true);
+            }
+
+            public final String toString() { return "STRICT_IE6"; }
+        };
+
+    /**
+     * The ALLOW_ALL HostnameVerifier essentially turns hostname verification
+     * off.  This implementation is a no-op, and never throws the SSLException.
+     */
+    public final static HostnameVerifier ALLOW_ALL =
+        new AbstractVerifier() {
+            public final void check(final String[] host, final String[] cns,
+                                    final String[] subjectAlts) {
+                // Allow everything - so never blowup.
+            }
+
+            public final String toString() { return "ALLOW_ALL"; }
+        };
+
+    abstract class AbstractVerifier implements HostnameVerifier {
+
+        /**
+         * This contains a list of 2nd-level domains that aren't allowed to
+         * have wildcards when combined with country-codes.
+         * For example: [*.co.uk].
+         * <p/>
+         * The [*.co.uk] problem is an interesting one.  Should we just hope
+         * that CA's would never foolishly allow such a certificate to happen?
+         * Looks like we're the only implementation guarding against this.
+         * Firefox, Curl, Sun Java 1.4, 5, 6 don't bother with this check.
+         */
+        private final static String[] BAD_COUNTRY_2LDS =
+            {"ac", "co", "com", "ed", "edu", "go", "gouv", "gov", "info",
+                "lg", "ne", "net", "or", "org"};
+
+        private final static String[] LOCALHOSTS = {"::1", "127.0.0.1",
+            "localhost",
+            "localhost.localdomain"};
+
+
+        static {
+            // Just in case developer forgot to manually sort the array.  :-)
+            Arrays.sort(BAD_COUNTRY_2LDS);
+            Arrays.sort(LOCALHOSTS);
+        }
+
+        protected AbstractVerifier() {}
+
+        /**
+         * The javax.net.ssl.HostnameVerifier contract.
+         *
+         * @param host    'hostname' we used to create our socket
+         * @param session SSLSession with the remote server
+         * @return true if the host matched the one in the certificate.
+         */
+        public boolean verify(String host, SSLSession session) {
+            try {
+                Certificate[] certs = session.getPeerCertificates();
+                X509Certificate x509 = (X509Certificate) certs[0];
+                check(new String[]{host}, x509);
+                return true;
+            }
+            catch (SSLException e) {
+                return false;
+            }
+        }
+
+        public void check(String host, SSLSocket ssl) throws IOException {
+            check(new String[]{host}, ssl);
+        }
+
+        public void check(String host, X509Certificate cert)
+            throws SSLException {
+            check(new String[]{host}, cert);
+        }
+
+        public void check(String host, String[] cns, String[] subjectAlts)
+            throws SSLException {
+            check(new String[]{host}, cns, subjectAlts);
+        }
+
+        public void check(String host[], SSLSocket ssl)
+            throws IOException {
+            if (host == null) {
+                throw new NullPointerException("host to verify is null");
+            }
+
+            SSLSession session = ssl.getSession();
+            if (session == null) {
+                // In our experience this only happens under IBM 1.4.x when
+                // spurious (unrelated) certificates show up in the server'
+                // chain.  Hopefully this will unearth the real problem:
+                InputStream in = ssl.getInputStream();
+                in.available();
+                /*
+                  If you're looking at the 2 lines of code above because
+                  you're running into a problem, you probably have two
+                  options:
+
+                    #1.  Clean up the certificate chain that your server
+                         is presenting (e.g. edit "/etc/apache2/server.crt"
+                         or wherever it is your server's certificate chain
+                         is defined).
+
+                                               OR
+
+                    #2.   Upgrade to an IBM 1.5.x or greater JVM, or switch
+                          to a non-IBM JVM.
+                */
+
+                // If ssl.getInputStream().available() didn't cause an
+                // exception, maybe at least now the session is available?
+                session = ssl.getSession();
+                if (session == null) {
+                    // If it's still null, probably a startHandshake() will
+                    // unearth the real problem.
+                    ssl.startHandshake();
+
+                    // Okay, if we still haven't managed to cause an exception,
+                    // might as well go for the NPE.  Or maybe we're okay now?
+                    session = ssl.getSession();
+                }
+            }
+            Certificate[] certs;
+            try {
+                certs = session.getPeerCertificates();
+            } catch (SSLPeerUnverifiedException spue) {
+                InputStream in = ssl.getInputStream();
+                in.available();
+                // Didn't trigger anything interesting?  Okay, just throw
+                // original.
+                throw spue;
+            }
+            X509Certificate x509 = (X509Certificate) certs[0];
+            check(host, x509);
+        }
+
+        public void check(String[] host, X509Certificate cert)
+            throws SSLException {
+            String[] cns = Certificates.getCNs(cert);
+            String[] subjectAlts = Certificates.getDNSSubjectAlts(cert);
+            check(host, cns, subjectAlts);
+        }
+
+        public void check(final String[] hosts, final String[] cns,
+                          final String[] subjectAlts, final boolean ie6,
+                          final boolean strictWithSubDomains)
+            throws SSLException {
+            // Build up lists of allowed hosts For logging/debugging purposes.
+            StringBuffer buf = new StringBuffer(32);
+            buf.append('<');
+            for (int i = 0; i < hosts.length; i++) {
+                String h = hosts[i];
+                h = h != null ? h.trim().toLowerCase() : "";
+                hosts[i] = h;
+                if (i > 0) {
+                    buf.append('/');
+                }
+                buf.append(h);
+            }
+            buf.append('>');
+            String hostnames = buf.toString();
+            // Build the list of names we're going to check.  Our DEFAULT and
+            // STRICT implementations of the HostnameVerifier only use the
+            // first CN provided.  All other CNs are ignored.
+            // (Firefox, wget, curl, Sun Java 1.4, 5, 6 all work this way).
+            TreeSet names = new TreeSet();
+            if (cns != null && cns.length > 0 && cns[0] != null) {
+                names.add(cns[0]);
+                if (ie6) {
+                    for (int i = 1; i < cns.length; i++) {
+                        names.add(cns[i]);
+                    }
+                }
+            }
+            if (subjectAlts != null) {
+                for (int i = 0; i < subjectAlts.length; i++) {
+                    if (subjectAlts[i] != null) {
+                        names.add(subjectAlts[i]);
+                    }
+                }
+            }
+            if (names.isEmpty()) {
+                String msg = "Certificate for " + hosts[0] + " doesn't contain CN or DNS subjectAlt";
+                throw new SSLException(msg);
+            }
+
+            // StringBuffer for building the error message.
+            buf = new StringBuffer();
+
+            boolean match = false;
+            out:
+            for (Iterator it = names.iterator(); it.hasNext();) {
+                // Don't trim the CN, though!
+                String cn = (String) it.next();
+                cn = cn.toLowerCase();
+                // Store CN in StringBuffer in case we need to report an error.
+                buf.append(" <");
+                buf.append(cn);
+                buf.append('>');
+                if (it.hasNext()) {
+                    buf.append(" OR");
+                }
+
+                // The CN better have at least two dots if it wants wildcard
+                // action.  It also can't be [*.co.uk] or [*.co.jp] or
+                // [*.org.uk], etc...
+                boolean doWildcard = cn.startsWith("*.") &&
+                                     cn.lastIndexOf('.') >= 0 &&
+                                     !isIP4Address(cn) &&
+                                     acceptableCountryWildcard(cn);
+
+                for (int i = 0; i < hosts.length; i++) {
+                    final String hostName = hosts[i].trim().toLowerCase();
+                    if (doWildcard) {
+                        match = hostName.endsWith(cn.substring(1));
+                        if (match && strictWithSubDomains) {
+                            // If we're in strict mode, then [*.foo.com] is not
+                            // allowed to match [a.b.foo.com]
+                            match = countDots(hostName) == countDots(cn);
+                        }
+                    } else {
+                        match = hostName.equals(cn);
+                    }
+                    if (match) {
+                        break out;
+                    }
+                }
+            }
+            if (!match) {
+                throw new SSLException("hostname in certificate didn't match: " + hostnames + " !=" + buf);
+            }
+        }
+
+        public static boolean isIP4Address(final String cn) {
+            boolean isIP4 = true;
+            String tld = cn;
+            int x = cn.lastIndexOf('.');
+            // We only bother analyzing the characters after the final dot
+            // in the name.
+            if (x >= 0 && x + 1 < cn.length()) {
+                tld = cn.substring(x + 1);
+            }
+            for (int i = 0; i < tld.length(); i++) {
+                if (!Character.isDigit(tld.charAt(0))) {
+                    isIP4 = false;
+                    break;
+                }
+            }
+            return isIP4;
+        }
+
+        public static boolean acceptableCountryWildcard(final String cn) {
+            int cnLen = cn.length();
+            if (cnLen >= 7 && cnLen <= 9) {
+                // Look for the '.' in the 3rd-last position:
+                if (cn.charAt(cnLen - 3) == '.') {
+                    // Trim off the [*.] and the [.XX].
+                    String s = cn.substring(2, cnLen - 3);
+                    // And test against the sorted array of bad 2lds:
+                    int x = Arrays.binarySearch(BAD_COUNTRY_2LDS, s);
+                    return x < 0;
+                }
+            }
+            return true;
+        }
+
+        public static boolean isLocalhost(String host) {
+            host = host != null ? host.trim().toLowerCase() : "";
+            if (host.startsWith("::1")) {
+                int x = host.lastIndexOf('%');
+                if (x >= 0) {
+                    host = host.substring(0, x);
+                }
+            }
+            int x = Arrays.binarySearch(LOCALHOSTS, host);
+            return x >= 0;
+        }
+
+        /**
+         * Counts the number of dots "." in a string.
+         *
+         * @param s string to count dots from
+         * @return number of dots
+         */
+        public static int countDots(final String s) {
+            int count = 0;
+            for (int i = 0; i < s.length(); i++) {
+                if (s.charAt(i) == '.') {
+                    count++;
+                }
+            }
+            return count;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HttpSecureProtocol.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HttpSecureProtocol.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HttpSecureProtocol.java
new file mode 100644
index 0000000..5ae3060
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/HttpSecureProtocol.java
@@ -0,0 +1,93 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/HttpSecureProtocol.java $
+ * $Revision: 165 $
+ * $Date: 2014-04-24 16:48:09 -0700 (Thu, 24 Apr 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.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+
+/**
+ * Hook into HttpClient.
+ *
+ * @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 HttpSecureProtocol extends SSLClient
+    implements SecureProtocolSocketFactory {
+
+    public HttpSecureProtocol()
+        throws GeneralSecurityException, IOException {
+        super();
+    }
+
+    /**
+     * Attempts to get a new socket connection to the given host within the
+     * given time limit.
+     * <p/>
+     * To circumvent the limitations of older JREs that do not support connect
+     * timeout a controller thread is executed. The controller thread attempts
+     * to create a new socket within the given limit of time. If socket
+     * constructor does not return until the timeout expires, the controller
+     * terminates and throws an
+     * {@link org.apache.commons.httpclient.ConnectTimeoutException}
+     * </p>
+     *
+     * @param host         the host name/IP
+     * @param port         the port on the host
+     * @param localAddress the local host name/IP to bind the socket to
+     * @param localPort    the port on the local machine
+     * @param params       {@link org.apache.commons.httpclient.params.HttpConnectionParams Http connection parameters}
+     * @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(final String host,
+                               final int port,
+                               final InetAddress localAddress,
+                               final int localPort,
+                               final HttpConnectionParams params)
+        throws IOException {
+        if (params == null) {
+            throw new IllegalArgumentException("Parameters may not be null");
+        }
+        int timeout = params.getConnectionTimeout();
+        return super.createSocket(host, port, localAddress, localPort, timeout);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13.java
new file mode 100644
index 0000000..1a2fb47
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13.java
@@ -0,0 +1,303 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Java13.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 com.sun.net.ssl.KeyManager;
+import com.sun.net.ssl.KeyManagerFactory;
+import com.sun.net.ssl.SSLContext;
+import com.sun.net.ssl.TrustManager;
+import com.sun.net.ssl.TrustManagerFactory;
+import com.sun.net.ssl.X509KeyManager;
+import com.sun.net.ssl.X509TrustManager;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+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 30-Jun-2006
+ */
+public final class Java13 extends JavaImpl {
+    private final static Java13 instance = new Java13();
+
+    private Java13() {
+        try {
+            Class c = Class.forName("javax.crypto.Cipher");
+            Class[] sig = {String.class};
+            String[] args = {"DES/CBC/PKCS5Padding"};
+            Method m = c.getMethod("getInstance", sig);
+            m.invoke(null, (Object[]) args);
+        }
+        catch (Exception e) {
+            try {
+                Class c = Class.forName("com.sun.crypto.provider.SunJCE");
+                Security.addProvider((Provider) c.newInstance());
+                // System.out.println( "jce not loaded: " + e + " - loading SunJCE!" );
+                //e.printStackTrace( System.out );
+            }
+            catch (Exception e2) {
+                System.out.println("com.sun.crypto.provider.SunJCE unavailable: " + e2);
+                // e2.printStackTrace( System.out );
+            }
+        }
+        try {
+            URL u = new URL("https://vancity.com/");
+            u.openConnection();
+        }
+        catch (Exception e) {
+            // System.out.println( "java.net.URL support of https not loaded: " + e + " - attempting to load com.sun.net.ssl.internal.ssl.Provider!" );
+            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+            System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
+        }
+        // System.out.println( "old HANDLER: " + HANDLER );
+    }
+
+    public static Java13 getInstance() {
+        return instance;
+    }
+
+    public final String getVersion() {
+        return "Java13";
+    }
+
+    protected final String retrieveSubjectX500(X509Certificate cert) {
+        return cert.getSubjectDN().toString();
+    }
+
+    protected final String retrieveIssuerX500(X509Certificate cert) {
+        return cert.getIssuerDN().toString();
+    }
+
+    protected final Certificate[] retrievePeerCerts(SSLSession sslSession)
+        throws SSLPeerUnverifiedException {
+        javax.security.cert.X509Certificate[] chain;
+        chain = sslSession.getPeerCertificateChain();
+        X509Certificate[] newChain = new X509Certificate[chain.length];
+        try {
+            for (int i = 0; i < chain.length; i++) {
+                javax.security.cert.X509Certificate javaxCert = chain[i];
+                byte[] encoded = javaxCert.getEncoded();
+                ByteArrayInputStream in = new ByteArrayInputStream(encoded);
+                synchronized (Certificates.CF) {
+                    Certificate c = Certificates.CF.generateCertificate(in);
+                    newChain[i] = (X509Certificate) c;
+                }
+            }
+        }
+        catch (Exception e) {
+            throw buildRuntimeException(e);
+        }
+        return newChain;
+    }
+
+    protected final Object buildKeyManagerFactory(KeyStore ks, char[] password)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        UnrecoverableKeyException {
+        String alg = KeyManagerFactory.getDefaultAlgorithm();
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
+        kmf.init(ks, password);
+        return kmf;
+    }
+
+    protected final Object buildTrustManagerFactory(KeyStore ks)
+        throws NoSuchAlgorithmException, KeyStoreException {
+        String alg = TrustManagerFactory.getDefaultAlgorithm();
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(alg);
+        tmf.init(ks);
+        return tmf;
+    }
+
+
+    protected final Object[] retrieveKeyManagers(Object keyManagerFactory) {
+        KeyManagerFactory kmf = (KeyManagerFactory) keyManagerFactory;
+        return kmf.getKeyManagers();
+    }
+
+    protected final Object[] retrieveTrustManagers(Object trustManagerFactory) {
+        TrustManagerFactory tmf = (TrustManagerFactory) trustManagerFactory;
+        return tmf.getTrustManagers();
+    }
+
+    protected final SSLSocketFactory buildSSLSocketFactory(Object ssl) {
+        return ((SSLContext) ssl).getSocketFactory();
+    }
+
+    protected final SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl) {
+        return ((SSLContext) ssl).getServerSocketFactory();
+    }
+
+    protected final RuntimeException buildRuntimeException(Exception cause) {
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream(512);
+        PrintStream ps = new PrintStream(byteOut);
+        ps.println(cause.toString());
+        cause.printStackTrace(ps);
+        ps.flush();
+        String originalCause = byteOut.toString();
+        return new RuntimeException(originalCause);
+    }
+
+    protected final SSLSocket buildSocket(SSL ssl) {
+        // Not supported in Java 1.3.
+        throw new UnsupportedOperationException();
+    }
+
+    protected final SSLSocket buildSocket(SSL ssl, String remoteHost,
+                                          int remotePort, InetAddress localHost,
+                                          int localPort, int connectTimeout)
+        throws IOException {
+        // Connect Timeout ignored for Java 1.3
+        SSLSocketFactory sf = ssl.getSSLSocketFactory();
+        SSLSocket s = (SSLSocket) connectSocket(
+                null, sf, remoteHost, remotePort, localHost, localPort, -1, ssl
+        );
+        ssl.doPreConnectSocketStuff(s);
+        ssl.doPostConnectSocketStuff(s, remoteHost);
+        return s;
+    }
+
+    protected final Socket buildPlainSocket(
+            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int connectTimeout
+    )
+        throws IOException {
+        // Connect Timeout ignored for Java 1.3
+        SocketFactory sf = SocketFactory.getDefault();
+        Socket s = connectSocket(
+                null, sf, remoteHost, remotePort, localHost, localPort, -1, ssl
+        );
+        ssl.doPreConnectSocketStuff(s);
+        ssl.doPostConnectSocketStuff(s, remoteHost);
+        return s;
+    }
+    
+    protected final Socket connectSocket(Socket s, SocketFactory sf,
+                                         String remoteHost, int remotePort,
+                                         InetAddress localHost, int localPort,
+                                         int timeout, SSL ssl)
+        throws IOException {
+
+        remoteHost = ssl.dnsOverride(remoteHost);
+
+        // Connect Timeout ignored for Java 1.3
+        if (s == null) {
+            if (sf == null) {
+                s = new Socket(remoteHost, remotePort, localHost, localPort);
+            } else {
+                s = sf.createSocket(remoteHost, remotePort, localHost, localPort);
+            }
+        }
+        return s;
+    }
+
+
+    protected final SSLServerSocket buildServerSocket(SSL ssl) {
+        // Not supported in Java 1.3.
+        throw new UnsupportedOperationException();
+    }
+
+    protected final void wantClientAuth(Object o, boolean wantClientAuth) {
+        // Not supported in Java 1.3.
+    }
+
+    protected final void enabledProtocols(Object o, String[] enabledProtocols) {
+        // Not supported in Java 1.3.
+    }
+
+    protected void checkTrusted(Object trustManager, X509Certificate[] chain,
+                                String authType)
+        throws CertificateException {
+        X509TrustManager tm = (X509TrustManager) trustManager;
+        boolean result = tm.isServerTrusted(chain);
+        if (!result) {
+            throw new CertificateException("commons-ssl java13 mode: certificate chain not trusted");
+        }
+    }
+
+
+    protected final Object initSSL(SSL ssl, TrustChain tc, KeyMaterial k)
+        throws NoSuchAlgorithmException, KeyStoreException,
+        CertificateException, KeyManagementException, IOException {
+        SSLContext context = SSLContext.getInstance(ssl.getDefaultProtocol());
+        TrustManager[] trustManagers = null;
+        KeyManager[] keyManagers = null;
+        if (tc != null) {
+            trustManagers = (TrustManager[]) tc.getTrustManagers();
+        }
+        if (k != null) {
+            keyManagers = (KeyManager[]) k.getKeyManagers();
+        }
+        if (keyManagers != null) {
+            for (int i = 0; i < keyManagers.length; i++) {
+                if (keyManagers[i] instanceof X509KeyManager) {
+                    X509KeyManager km = (X509KeyManager) keyManagers[i];
+                    keyManagers[i] = new Java13KeyManagerWrapper(km, k, ssl);
+                }
+            }
+        }
+        if (trustManagers != null) {
+            for (int i = 0; i < trustManagers.length; i++) {
+                if (trustManagers[i] instanceof X509TrustManager) {
+                    X509TrustManager tm = (X509TrustManager) trustManagers[i];
+                    trustManagers[i] = new Java13TrustManagerWrapper(tm, tc, ssl);
+                }
+            }
+        }
+        context.init(keyManagers, trustManagers, null);
+        return context;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java
new file mode 100644
index 0000000..81111b8
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java
@@ -0,0 +1,82 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.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 com.sun.net.ssl.X509KeyManager;
+
+import java.security.Principal;
+import java.security.PrivateKey;
+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 30-Jun-2006
+ */
+public class Java13KeyManagerWrapper implements X509KeyManager {
+
+    private final X509KeyManager keyManager;
+    // private final KeyMaterial keyMaterial;   <-- maybe use one day in the
+    // private final SSL ssl;                   <-- in the future?
+
+    public Java13KeyManagerWrapper(X509KeyManager m, KeyMaterial km, SSL h) {
+        this.keyManager = m;
+        // this.keyMaterial = km;   <-- maybe use one day in the
+        // this.ssl = h;            <-- in the future?
+    }
+
+    public String chooseClientAlias(String keyType, Principal[] issuers) {
+        return keyManager.chooseClientAlias(keyType, issuers);
+    }
+
+    public String chooseServerAlias(String keyType, Principal[] issuers) {
+        return keyManager.chooseServerAlias(keyType, issuers);
+    }
+
+    public X509Certificate[] getCertificateChain(String alias) {
+        return keyManager.getCertificateChain(alias);
+    }
+
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        return keyManager.getClientAliases(keyType, issuers);
+    }
+
+    public PrivateKey getPrivateKey(String alias) {
+        return keyManager.getPrivateKey(alias);
+    }
+
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        return keyManager.getServerAliases(keyType, issuers);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/23c1fd12/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java
----------------------------------------------------------------------
diff --git a/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java
new file mode 100644
index 0000000..ad86ee9
--- /dev/null
+++ b/3rdparty/not-yet-commons-ssl/src/main/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java
@@ -0,0 +1,103 @@
+/*
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.16/src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.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 com.sun.net.ssl.X509TrustManager;
+
+import java.security.cert.CertificateException;
+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 30-Jun-2006
+ */
+public class Java13TrustManagerWrapper implements X509TrustManager {
+
+    private final X509TrustManager trustManager;
+    private final TrustChain trustChain;
+    private final SSL ssl;
+
+    public Java13TrustManagerWrapper(X509TrustManager m, TrustChain tc, SSL h) {
+        this.trustManager = m;
+        this.trustChain = tc;
+        this.ssl = h;
+    }
+
+    public boolean isClientTrusted(X509Certificate[] chain) {
+        ssl.setCurrentClientChain(chain);
+        boolean firstTest = trustManager.isClientTrusted(chain);
+        return test(firstTest, chain);
+    }
+
+    public boolean isServerTrusted(X509Certificate[] chain) {
+        ssl.setCurrentServerChain(chain);
+        boolean firstTest = trustManager.isServerTrusted(chain);
+        return test(firstTest, chain);
+    }
+
+    public X509Certificate[] getAcceptedIssuers() {
+        if ( trustChain.containsTrustAll()) {
+            // This means we accept all issuers.
+            return new X509Certificate[0];
+        } else {
+            return trustManager.getAcceptedIssuers();
+        }
+    }
+
+    private boolean test(boolean firstTest, X509Certificate[] chain) {
+        // Even if the first test failed, we might still be okay as long as
+        // this SSLServer or SSLClient is setup to trust all certificates.
+        if (!firstTest) {
+            if (!trustChain.contains(TrustMaterial.TRUST_ALL)) {
+                return false;
+            }
+        }
+        try {
+            for (int i = 0; i < chain.length; i++) {
+                X509Certificate c = chain[i];
+                if (ssl.getCheckExpiry()) {
+                    c.checkValidity();
+                }
+                if (ssl.getCheckCRL()) {
+                    Certificates.checkCRL(c);
+                }
+            }
+            return true;
+        }
+        catch (CertificateException ce) {
+            return false;
+        }
+    }
+
+}