[not-yet-commons-ssl] 01/08: Imported Upstream version 0.3.15

Tony Mancill tmancill at moszumanska.debian.org
Thu Sep 11 06:15:38 UTC 2014


This is an automated email from the git hooks/post-receive script.

tmancill pushed a commit to branch master
in repository not-yet-commons-ssl.

commit 93a4fe438b2af8d409de00003f7f4c3aa28aed76
Author: tony mancill <tmancill at debian.org>
Date:   Tue Sep 9 22:16:55 2014 -0700

    Imported Upstream version 0.3.15
---
 build.xml                                          |   76 +-
 docs/404.html                                      |   17 +-
 docs/404.html~                                     |   51 -
 docs/about.html                                    |    2 +-
 docs/download.html                                 |  124 +-
 docs/download.html~                                |  229 ----
 docs/index.html                                    |   19 +-
 docs/openssl/compare.txt                           |   28 +
 docs/openssl/profile.3.10                          |   72 ++
 docs/openssl/profile.3.9                           |   72 ++
 docs/ping.html                                     |   27 +-
 docs/pkcs8.html                                    |    2 +-
 docs/roadmap.html                                  |   86 ++
 docs/tree.html                                     | 1289 +++++++++++++++++---
 docs/utilities.html                                |    6 +-
 samples/ca/CA.sh                                   |   76 ++
 samples/ca/clean.sh                                |    6 +
 samples/ca/dsa-intermediate/cacert.pem             |  137 +++
 samples/ca/dsa-intermediate/dsa.params             |   34 +
 samples/ca/dsa-intermediate/private/cakey.pem      |   20 +
 samples/ca/openssl.cnf                             |  313 +++++
 samples/ca/root/cacert.pem                         |   85 ++
 samples/ca/root/private/cakey.pem                  |   27 +
 samples/ca/rsa-intermediate/cacert.pem             |   86 ++
 samples/ca/rsa-intermediate/private/cakey.pem      |   27 +
 samples/ca/rsa.key                                 |   27 +
 samples/ca/test-dsa-cert.pem                       |   67 +
 samples/ca/test-dsa-chain.pem                      |  289 +++++
 samples/ca/test-rsa-cert.pem                       |   83 ++
 samples/ca/test-rsa-chain.pem                      |  254 ++++
 ...cacerts-with-78-entries-and-one-private-key.jks |  Bin 0 -> 84754 bytes
 samples/cacerts-with-78-entries.jks                |  Bin 0 -> 82586 bytes
 samples/dsa.html                                   |  221 ++--
 samples/keystores/BC.BKS.ks                        |  Bin 0 -> 2204 bytes
 samples/keystores/BC.PKCS12-3DES-3DES.ks           |  Bin 0 -> 2588 bytes
 samples/keystores/BC.PKCS12-DEF-3DES-3DES.ks       |  Bin 0 -> 2596 bytes
 samples/keystores/BC.PKCS12-DEF.ks                 |  Bin 0 -> 2580 bytes
 samples/keystores/BC.PKCS12.ks                     |  Bin 0 -> 2658 bytes
 samples/keystores/BC.UBER.ks                       |  Bin 0 -> 2208 bytes
 samples/keystores/README.txt                       |    8 +
 samples/keystores/Sun.2pass.jks.ks                 |  Bin 0 -> 2214 bytes
 samples/keystores/Sun.jks.ks                       |  Bin 0 -> 2200 bytes
 samples/keystores/SunJCE.jceks.ks                  |  Bin 0 -> 2182 bytes
 samples/keystores/chain-rsa_dsa_rsa.ks             |  Bin 0 -> 5058 bytes
 samples/keystores/chain-rsa_dsa_rsa.pem            |  289 +++++
 samples/keystores/chain-rsa_dsa_rsa.pkcs12.der     |  Bin 0 -> 5373 bytes
 samples/keystores/chain-rsa_dsa_rsa.pkcs12.pem     |  112 ++
 samples/keystores/chain-rsa_rsa_rsa.ks             |  Bin 0 -> 4740 bytes
 samples/keystores/chain-rsa_rsa_rsa.pem            |  254 ++++
 samples/keystores/chain-rsa_rsa_rsa.pkcs12.der     |  Bin 0 -> 5061 bytes
 samples/keystores/chain-rsa_rsa_rsa.pkcs12.pem     |  105 ++
 samples/keystores/generate.sh                      |   63 +
 samples/keystores/rsa.key                          |   30 +
 samples/rsa.html                                   |  221 ++--
 .../contrib/ssl/AuthSSLProtocolSocketFactory.java  |   16 +-
 .../contrib/ssl/TrustSSLProtocolSocketFactory.java |   12 +-
 src/java/org/apache/commons/ssl/ASN1Structure.java |    2 +-
 src/java/org/apache/commons/ssl/ASN1Util.java      |    2 +-
 src/java/org/apache/commons/ssl/Base64.java        | 1247 +++++++++++++------
 .../org/apache/commons/ssl/Base64InputStream.java  |  222 ++--
 .../org/apache/commons/ssl/Base64OutputStream.java |  198 +++
 src/java/org/apache/commons/ssl/CRLSocket.java     |  100 ++
 src/java/org/apache/commons/ssl/CRLUtil.java       |    2 +-
 src/java/org/apache/commons/ssl/Certificates.java  |  146 +--
 .../org/apache/commons/ssl/ComboInputStream.java   |    2 +-
 src/java/org/apache/commons/ssl/DerivedKey.java    |    2 +-
 src/java/org/apache/commons/ssl/HostPort.java      |   10 +-
 .../org/apache/commons/ssl/HostnameVerifier.java   |    2 +-
 .../org/apache/commons/ssl/HttpSecureProtocol.java |    6 +-
 src/java/org/apache/commons/ssl/Java13.java        |   37 +-
 .../commons/ssl/Java13KeyManagerWrapper.java       |    2 +-
 .../commons/ssl/Java13TrustManagerWrapper.java     |   14 +-
 src/java/org/apache/commons/ssl/Java14.java        |   60 +-
 .../commons/ssl/Java14KeyManagerWrapper.java       |    2 +-
 .../commons/ssl/Java14TrustManagerWrapper.java     |   13 +-
 src/java/org/apache/commons/ssl/JavaImpl.java      |   35 +-
 src/java/org/apache/commons/ssl/KeyMaterial.java   |  184 ++-
 .../org/apache/commons/ssl/KeyStoreBuilder.java    |  473 ++++---
 src/java/org/apache/commons/ssl/LDAPSocket.java    |    6 +-
 src/java/org/apache/commons/ssl/LogHelper.java     |    2 +-
 src/java/org/apache/commons/ssl/LogWrapper.java    |    2 +-
 src/java/org/apache/commons/ssl/OpenSSL.java       |   26 +-
 src/java/org/apache/commons/ssl/OpenSSLTest.java   |   92 --
 src/java/org/apache/commons/ssl/PEMItem.java       |    2 +-
 src/java/org/apache/commons/ssl/PEMUtil.java       |   44 +-
 src/java/org/apache/commons/ssl/PKCS8Key.java      |   67 +-
 src/java/org/apache/commons/ssl/Ping.java          |   34 +-
 .../commons/ssl/ProbablyBadPasswordException.java  |    2 +-
 .../commons/ssl/ProbablyNotPKCS8Exception.java     |    2 +-
 .../apache/commons/ssl/RMISocketFactoryImpl.java   |   10 +-
 src/java/org/apache/commons/ssl/SSL.java           |  210 ++--
 src/java/org/apache/commons/ssl/SSLClient.java     |   17 +-
 src/java/org/apache/commons/ssl/SSLEchoServer.java |   24 +-
 .../org/apache/commons/ssl/SSLProxyServer.java     |   11 +-
 src/java/org/apache/commons/ssl/SSLServer.java     |   19 +-
 .../apache/commons/ssl/SSLServerSocketWrapper.java |    2 +-
 .../org/apache/commons/ssl/SSLSocketWrapper.java   |  181 ++-
 .../org/apache/commons/ssl/SSLWrapperFactory.java  |   13 +-
 .../org/apache/commons/ssl/TomcatServerXML.java    |    2 +-
 src/java/org/apache/commons/ssl/TrustChain.java    |   19 +-
 src/java/org/apache/commons/ssl/TrustMaterial.java |   43 +-
 src/java/org/apache/commons/ssl/Util.java          |   74 +-
 src/java/org/apache/commons/ssl/Version.java       |    6 +-
 .../commons/ssl/X509CertificateChainBuilder.java   |   69 +-
 src/java/org/apache/commons/ssl/rmi/DateRMI.java   |    2 +-
 .../org/apache/commons/ssl/rmi/IntegerRMI.java     |    2 +-
 .../org/apache/commons/ssl/rmi/RemoteDate.java     |    2 +-
 .../org/apache/commons/ssl/rmi/RemoteInteger.java  |    2 +-
 src/java/org/apache/commons/ssl/rmi/Test.java      |    2 +-
 .../apache/commons/ssl/util/ByteArrayReadLine.java |   32 +
 src/java/org/apache/commons/ssl/util/Hex.java      |    2 +-
 .../apache/commons/ssl/util/IPAddressParser.java   |  183 +++
 src/java/org/apache/commons/ssl/util/ReadLine.java |   91 ++
 src/java/org/apache/commons/ssl/util/UTF8.java     |   22 +
 .../contrib/ssl/TestHttpclientContrib.java         |   42 +
 src/test/org/apache/commons/ssl/JUnitConfig.java   |   46 +
 src/test/org/apache/commons/ssl/TestBase64.java    |   89 ++
 .../org/apache/commons/ssl/TestCertificates.java   |   87 ++
 .../apache/commons/ssl/TestIPAddressParser.java    |   77 ++
 .../org/apache/commons/ssl/TestKeyMaterial.java    |  118 ++
 src/test/org/apache/commons/ssl/TestOpenSSL.java   |  150 +++
 src/test/org/apache/commons/ssl/TestPKCS8Key.java  |   54 +
 .../org/apache/commons/ssl/TestTrustMaterial.java  |   16 +
 version.txt                                        |    4 +-
 124 files changed, 7655 insertions(+), 2070 deletions(-)

diff --git a/build.xml b/build.xml
index a5854e2..9be38af 100644
--- a/build.xml
+++ b/build.xml
@@ -11,10 +11,8 @@
 
     Default target: jar
 -->
-<project name="commons-ssl" default="jar" basedir=".">
+<project name="not-yet-commons-ssl" default="jar" basedir=".">
 
-  <property name="httpclient-jar" value="commons-httpclient-3.0.jar"/>
-  <property name="log4j-jar" value="log4j-1.2.13.jar"/>
   <property name="src" location="./src/java"/>
   <property name="build" location="./build"/>
   <property name="lib" location="./lib"/>
@@ -23,13 +21,66 @@
   <property name="javadocs" value="${build}/javadocs"/>
   <property name="rmic.includes" value="**/*RMI.class"/>
 
+  <property name="test-src" location="./src/test"/>
+  <property name="test-classes" value="${build}/test-classes"/>
+  <property name="test-jar-file" value="${ant.project.name}-tests.jar"/>
+  <property name="test.report.dir" value="${build}/test-report"/>   
+
   <path id="compile-classpath">
+    <fileset dir="lib">
+      <include name="*.jar"/>
+    </fileset>
+    <pathelement location="."/>    
     <pathelement location="${classes}"/>
-    <pathelement location="${lib}/${httpclient-jar}"/>
-    <pathelement location="${lib}/${log4j-jar}"/>
+    <pathelement location="${test-classes}"/>            
   </path>
 
+  <target name="test-jar" depends="jar">
+    <mkdir dir="${test-classes}"/>
+    <javac
+      includeAntRuntime="false"
+      destdir="${test-classes}"
+      debug="true"
+      optimize="false"
+      srcdir="${test-src}"
+    >
+      <classpath refid="compile-classpath"/>
+    </javac>
+    <copy todir="${test-classes}">
+      <fileset dir="${test-src}" excludes="**/*.java"/>
+    </copy>
+    <jar
+      basedir="${test-classes}"
+      destfile="${build}/${test-jar-file}"
+      index="true"
+      whenempty="create"
+    />      
+  </target>
+
+  <target name="test" depends="test-jar">
+      <mkdir dir="${test.report.dir}"/>
+      <junit printsummary="on" haltonfailure="false" errorProperty="junit.failed"
+        failureProperty="junit.failed" fork="on" forkMode="perBatch"
+        timeout="600000" showoutput="on">
+        <syspropertyset><propertyref builtin="commandline"/></syspropertyset>
+        <formatter type="xml"/>
+        <classpath refid="compile-classpath"/>
+        <batchtest todir="${test.report.dir}">
+          <fileset dir="${test-src}" includes="**/Test*.java"/>
+        </batchtest>
+      </junit>
+      <junitreport todir="${test.report.dir}">
+        <fileset dir="${test.report.dir}">
+          <include name="TEST-*.xml"/>
+        </fileset>
+        <report todir="${test.report.dir}"/>
+      </junitreport>
+      <fail message="JUnit tests failed." if="test.failed"/>
+  </target>
+
   <target name="init">
+    <echo>${ant.version}</echo>
+    <echo>Java version: ${java.version}</echo>
     <tstamp>
       <format property="date" pattern="zzz:yyyy-MM-dd/HH:mm:ss" locale="en"/>
     </tstamp>
@@ -39,12 +90,12 @@
   <target name="javac" depends="init" description="Compiles java source code.">
     <mkdir dir="${classes}"/>
     <javac
+      compiler="extJavac"
       includeAntRuntime="false"
       destdir="${classes}"
       debug="true"
       optimize="false"
       srcdir="${src}"
-      excludes="${javac.exclude}"
     >
       <classpath refid="compile-classpath"/>
     </javac>
@@ -69,8 +120,8 @@
       duplicate="fail"
     >
       <manifest>
-        <attribute name="Built-By" value="cucbc.com"/>
-        <attribute name="Created-By" value="cucbc.com"/>
+        <attribute name="Built-By" value="Julius Davies"/>
+        <attribute name="Created-By" value="Julius Davies"/>
         <attribute name="Main-Class" value="org.apache.commons.ssl.Ping"/>
       </manifest>
      </jar>
@@ -102,5 +153,14 @@
 
   <target name="all" depends="clean,jar"/>
 
+  <target name="classpath" depends="cp"/>
+
+  <target name='cp' depends='jar' description='Generates classpath.sh file'>
+    <property name='classdump' refid='compile-classpath'/>
+    <echo file='classpath.sh'>export CLASSPATH=${classdump}
+</echo>
+    <echo>Created classpath.sh file.</echo>
+  </target>
+
 
 </project>
diff --git a/docs/404.html b/docs/404.html
index 92d9bad..f59027e 100644
--- a/docs/404.html
+++ b/docs/404.html
@@ -20,12 +20,14 @@ li { padding-bottom: 6px; }
 <div class="nav">
 <a href="/commons-ssl/index.html">main</a> |
 <a href="/commons-ssl/ssl.html">ssl</a> |
+
 <a href="/commons-ssl/pkcs8.html">pkcs8</a> |
 <a href="/commons-ssl/pbe.html">pbe</a> |
 <a href="/commons-ssl/rmi.html">rmi</a> |
 <a href="/commons-ssl/utilities.html">utilities</a> |
 <a href="/commons-ssl/source.html">source</a> |
 <a href="/commons-ssl/javadocs/">javadocs</a> |
+
 <a href="/commons-ssl/download.html">download</a>
 </div>
 <br clear="all"/>
@@ -33,15 +35,16 @@ li { padding-bottom: 6px; }
 <h2>404 - Page Not Found</h2>
 <p>The path you requested is not available.</p>
 <table cellpadding="6" cellspacing="0" border="0" style="margin-top: 9px;">
-<tr><th colspan="3">Current Version (November 14th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.zip">not-yet-commons-ssl-0.3.9.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 8063831d05fc6204a7c0c23a0f86b086</td></tr>
-<tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.jar">not-yet-commons-ssl-0.3.9.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 34996468b477e3a6c81d7feec213288b</td></tr>
-<tr><th colspan="3">Previous Version (July 4th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.zip">not-yet-commons-ssl-0.3.8.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 6c709837f9fef310a69f8659f1697c81</td></tr>
-<tr><td>Binary only:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.jar">not-yet-commons-ssl-0.3.8.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 34996468b477e3a6c81d7feec213288b</td></tr>
+<tr><th colspan="3">Current Version (September 8th, 2014):</th></tr>
+<tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.15.zip">not-yet-commons-ssl-0.3.15.zip</a></td><td>5.1MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: </td></tr>
+<tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.15.jar">not-yet-commons-ssl-0.3.15.jar</a></td><td>267KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: cebc58b8367c253688426043fdf08221</td></tr>
+<tr><th colspan="3">Previous Version (May 8th, 2014):</th></tr>
+<tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.13.zip">not-yet-commons-ssl-0.3.13.zip</a></td><td>5.1MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 14f2f7edeaf2bbab550d63a51868e432</td></tr>
+<tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.13.jar">not-yet-commons-ssl-0.3.13.jar</a></td><td>268KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 3dd6c487e1ce53221aa13811e0bc6207</td></tr>
+
 </table>
 <br/><b>Warning:</b>
- <span style="color: red; font-weight: bold;">not-yet-commons-ssl-0.3.9 should be considered to be of "Alpha" quality!
+ <span style="color: red; font-weight: bold;">All versions (to date) of not-yet-commons-ssl should be considered to be of "Alpha" quality!
 This code probably contains bugs.  This code may have security issues.</span>
 <p>Future versions will definitely break the current API in a non-reverse compatible way.  After commons-ssl-0.5.0, though, we
 plan on always being reverse compatible with ourselves.
diff --git a/docs/404.html~ b/docs/404.html~
deleted file mode 100644
index e6e28ab..0000000
--- a/docs/404.html~
+++ /dev/null
@@ -1,51 +0,0 @@
-<html>
-<head>
-<title>Not-Yet-Commons-SSL - 404 Page Not Found</title>
-<style type="text/css">
-dl, h1, h2, h3, h4 { margin: 0; border: 0; padding: 0; font-size: 100%; }
-h1 { float: left; color: red; }
-b.n { font-family: arial; font-weight: bold; }
-span.hl { color: white; background-color: green; }
-div.nav { float: left; margin-left: 20px; font-weight: bold; }
-.nav a, .nav span { padding: 0 5px; }
-.nav a { color: blue; }
-td.v { text-align: center; }
-dt { padding: 8px 0 8px 5px; }
-dd { padding-left: 15px; }
-li { padding-bottom: 6px; }
-</style>
-</head>
-<body>
-<h1>not-yet-commons-ssl</h1>
-<div class="nav">
-<a href="/commons-ssl/index.html">main</a> |
-<a href="/commons-ssl/ssl.html">ssl</a> |
-<a href="/commons-ssl/pkcs8.html">pkcs8</a> |
-<a href="/commons-ssl/pbe.html">pbe</a> |
-<a href="/commons-ssl/rmi.html">rmi</a> |
-<a href="/commons-ssl/utilities.html">utilities</a> |
-<a href="/commons-ssl/source.html">source</a> |
-<a href="/commons-ssl/javadocs/">javadocs</a> |
-<a href="/commons-ssl/download.html">download</a>
-</div>
-<br clear="all"/>
-<hr/>
-<h2>404 - Page Not Found</h2>
-<p>The path you requested is not available.</p>
-<table cellpadding="6" cellspacing="0" border="0" style="margin-top: 9px;">
-<tr><th colspan="3">Current Version (November 14th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.zip">not-yet-commons-ssl-0.3.9.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 6c709837f9fef310a69f8659f1697c81</td></tr>
-<tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.jar">not-yet-commons-ssl-0.3.9.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 34996468b477e3a6c81d7feec213288b</td></tr>
-<tr><th colspan="3">Previous Version (July 4th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.zip">not-yet-commons-ssl-0.3.8.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 6c709837f9fef310a69f8659f1697c81</td></tr>
-<tr><td>Binary only:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.jar">not-yet-commons-ssl-0.3.8.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 34996468b477e3a6c81d7feec213288b</td></tr>
-</table>
-<br/><b>Warning:</b>
- <span style="color: red; font-weight: bold;">not-yet-commons-ssl-0.3.9 should be considered to be of "Alpha" quality!
-This code probably contains bugs.  This code may have security issues.</span>
-<p>Future versions will definitely break the current API in a non-reverse compatible way.  After commons-ssl-0.5.0, though, we
-plan on always being reverse compatible with ourselves.
-<hr/>
-
-</body>
-</html>
diff --git a/docs/about.html b/docs/about.html
index 3b61f22..5ef231e 100644
--- a/docs/about.html
+++ b/docs/about.html
@@ -38,7 +38,7 @@ li { padding-bottom: 6px; }
 <ol>
 <li  style="margin-top: 6px;"><b>Make SSL and Java Easier.</b>  Ever wanted to work with self-signed
 certificates in your Java application in a secure fashion?  Ever wanted to use more than one client
-certificte in a single running JVM?  You can edit your <code>$JAVA_HOME/jre/lib/security/cacerts</code>
+certificate in a single running JVM?  You can edit your <code>$JAVA_HOME/jre/lib/security/cacerts</code>
 file, and you can invoke Java with <code>-Djavax.net.ssl.keyStore=/path/to/keystore</code>.  Both of
 these approaches are great at first, but they don't scale well.  Do you really want to pollute every
 SSL socket in your JVM (HTTP, LDAP, JDBC, RMI, etc...) with those system-wide changes?  Commons-SSL let's you
diff --git a/docs/download.html b/docs/download.html
index 9eb706b..4ca6bb7 100644
--- a/docs/download.html
+++ b/docs/download.html
@@ -21,12 +21,14 @@ tr.released td, tr.released th { background-color: yellow; font-weight: bold; }
 <div class="nav">
 <a href="index.html">main</a> |
 <a href="ssl.html">ssl</a> |
+
 <a href="pkcs8.html">pkcs8</a> |
 <a href="pbe.html">pbe</a> |
 <a href="rmi.html">rmi</a> |
 <a href="utilities.html">utilities</a> |
 <a href="source.html">source</a> |
 <a href="javadocs/">javadocs</a> |
+
 <span class="hl" href="download.html">download</span>
 </div>
 <br clear="all"/>
@@ -35,25 +37,80 @@ tr.released td, tr.released th { background-color: yellow; font-weight: bold; }
 <p>Not-Yet-Commons-SSL currently has NO affiliation with the <a href="http://apache.org/">Apache Software Foundation</a> (apache.org), but we're hoping
 to start <a href="http://incubator.apache.org/incubation/Incubation_Policy.html">Incubation</a> one day.
 <table cellpadding="6" cellspacing="0" border="0" style="margin-top: 9px;">
-<tr><th colspan="3">Current Version (November 14th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.zip">not-yet-commons-ssl-0.3.9.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 8063831d05fc6204a7c0c23a0f86b086</td></tr>
-<tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.jar">not-yet-commons-ssl-0.3.9.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: </td></tr>
-<tr><th colspan="3">Previous Version (July 4th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.zip">not-yet-commons-ssl-0.3.8.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 6c709837f9fef310a69f8659f1697c81</td></tr>
-<tr><td>Binary only:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.jar">not-yet-commons-ssl-0.3.8.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 34996468b477e3a6c81d7feec213288b</td></tr>
+    <tr><th colspan="3">Current Version (September 8th, 2014):</th></tr>
+    <tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.15.zip">not-yet-commons-ssl-0.3.15.zip</a></td><td>5.1MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: </td></tr>
+    <tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.15.jar">not-yet-commons-ssl-0.3.15.jar</a></td><td>267KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: cebc58b8367c253688426043fdf08221</td></tr>
+    <tr><th colspan="3">Previous Version (May 8th, 2014):</th></tr>
+    <tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.13.zip">not-yet-commons-ssl-0.3.13.zip</a></td><td>5.1MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 14f2f7edeaf2bbab550d63a51868e432</td></tr>
+    <tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.13.jar">not-yet-commons-ssl-0.3.13.jar</a></td><td>268KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 3dd6c487e1ce53221aa13811e0bc6207</td></tr>
 </table>
 <br/><b>Warning:</b>
- <span style="color: red; font-weight: bold;">not-yet-commons-ssl-0.3.9 should be considered to be of "Alpha" quality!
+ <span style="color: red; font-weight: bold;">All versions of not-yet-commons-ssl should be considered to be of "Alpha" quality!
 This code probably contains bugs.  This code may have security issues.</span>
 <p>Future versions will definitely break the current API in a non-reverse compatible way.  After commons-ssl-0.5.0, though, we
 plan on always being reverse compatible with ourselves.
 <hr/>
+<h3>Changelog for not-yet-commons-ssl-0.3.15:</h3>
+<dl>
+    <dt>1. Security patch from Redhat for CVE alert.</dt>
+    <dd>The way we parse the Principal (e.g., "CN=a,OU=b,O=c") from an X509 Certificate had a serious security flaw.
+    Thanks to Redhat, Arun Babu Neelicattu, and David Jorm for notifying us, and for the patch they submitted.</dd></dd>
+    <dt>2. Upgrade to Java 1.5.</dt>
+    <dd>Not-yet-commons-ssl now requires at least Java 1.5 to run (a.k.a. Java 5).
+    If you really need Java 1.3 or Java 1.4 compatibility, please email the mailing list; it's not too late for us to
+    rejig things to bring that back, but we're not going to bother unless someone actually needs it.
+    </dd>
+</dl>
+<h3>Changelog for not-yet-commons-ssl-0.3.13:</h3>
+<dl>
+<dt>1. Fix bugs in AuthSSLProtocolSocketFactory and TrustSSLProtocolSocketFactory.</dt>
+<dd>KeyMaterial's constructor has been checking that KeyMaterial contains at least one
+private key, but this assumption was invalid with these guys.  The fall-back to the
+TrustMaterial constructor if necessary.   (Wonder how long this has been broken!   Oops!)</dd>
+
+<dt>2. Upgraded from JUnit3 to JUnit4.  Added some extra unit tests.</dt>
+</dl>
+<h3>Changelog for not-yet-commons-ssl-0.3.12:</h3>
+<dl>
+<dt>1. Avoid reverse-DNS lookups with literal IP address connections.</dt>
+<dd>Based on my own investigation, InetAddress.getByAddress(String, byte[]) does not do the reverse-DNS lookup that plagues Java SSL users, so we call that whenever possible.</dd>
+</dl>
+<h3>Changelog for not-yet-commons-ssl-0.3.11:</h3>
+<dl>
+<dt>1.  Fixed KeyStoreBuilder.</dt>
+<dd>It really can handle KeyStores now where the store-password and key-password differ.  It can
+also now handle all the things 0.3.9 couuld handle, too.  Whoops.  Sorry about 0.3.10, everyone.</dd>
+
+<dt>2.  KeyStoreBuilder auto-detects BouncyCastle BKS and UBER keystore types.</dt>
+
+<dt>3.  CRL checking no longer blocks forever in bad network situations (Java 5 and newer).</dt>
+<dd>CRL checking was using default java.net.URL behaviour, which unfortunately can
+cause infinite blocking.  CRL checking now waits at most 5 seconds for the CRL server
+to respond.  <b>Note:  Only works on Java 1.5 and above.</b></dd>
+
+<dt>4.  Lot's more unit tests.  Especially for KeyStoreBuilder.</dt>
+
+<dt>5.  Base64InputStream's default behaviour changed to DECODE.  VERY SORRY!</dt>
+
+<dt>6.  PKCS8Key.getPublicKey() and PEMUtil.toPEM() methods added. </dt>
+</dl>
+<br/>
+<h3>Features as of not-yet-commons-ssl-0.3.10:</h3>
+<dl>
+<dt>1. <a href="utilities.html#KSB">KeyStoreBuilder</a> broken.
+<dd>
+<b>Version 0.3.10 should be avoided!</b>
+</dd>
+</dl>
+
+<br/>
 <h3>Features as of not-yet-commons-ssl-0.3.9:</h3>
 <dl>
 <dt>1. <a href="pbe.html">PBE</a> is now Compatible with <code>openssl enc -K [key] -iv [IV]</code>.</dt>
 <dd>People were asking for this.  See the PBE page for more details.</dd>
 <dt>2. DES2 with PBE was broken.</dt>
 <dd>Fixed.</dd>
+
 <dt>3. directory.apache.org didn't write the ASN.1 code.  BouncyCastle did.</dt>
 <dd>Now using latest ASN.1 parsing code from BC, and attributing it properly.</dd>
 <dt>4. The "ping" utility has a few more options.</dt>
@@ -66,6 +123,7 @@ independant of the target host/ip.</dd>
 <dt>1. useDefaultJavaCiphers() actually works now.</dt>
 <dd>When you want to allow 40 bit, 56 bit, and MD5 based SSL ciphers, use this.  It was 99% functional in 0.3.7, but there was a
 rare situation where setting ciphers was causing SSL handshake errors.</dd>
+
 <dt>2. <a href="pbe.html">PBE</a> (password-based-encryption) improved.</dt>
 <dd>PBE now has its own <a href="pbe.html">HTML page</a>.  Support for all of OpenSSL's PBE ciphers implemented and tested, including
 IDEA and RC5.  (DES-X might work, but couldn't find a JCE provider that supported it).  Threw in support for some
@@ -73,6 +131,7 @@ additional BouncyCastle ciphers even though OpenSSL doesn't support them (cast6,
 skipjack, tea, twofish, xtea).  Around <a href="samples/pbe/">650 test files</a> created to make sure PBE is working properly.
 </dd>
 <dt>3. PBE API changed on <a href="javadocs/org/apache/commons/ssl/OpenSSL.html#encrypt(java.lang.String,%20char[],%20java.io.InputStream)">OpenSSL.encrypt()</a> and <a href="javadocs/org/apache/commons/ssl/OpenSSL.html#decrypt(java.lang.String,%20char[],%20java.io.InputStream)">OpenSSL.decrypt()</a>.</dt>
+
 <dd>The password is now char[] instead of byte[] (sorry!).  Encrypt/decrypt on byte[] introduced.  Encrypt/decrypt on InputStream
 is still available, and is properly streamed so that even extremely large files can be encrypted/decrypted.</dd>
 </dl>
@@ -88,6 +147,7 @@ Here's a code example using "cucbc.com" to connect, but anticipating "www.cucbc.
 SSLClient client = new SSLClient();
 client.addAllowedName( "www.cucbc.com" );
 Socket s = client.createSocket( "cucbc.com", 443 );
+
 </pre>
 This technique is also useful if you don't want to use DNS, and want to
 connect using the IP address.
@@ -109,6 +169,7 @@ job on the hostname verification!
 <dt>5. KeyMaterial constructor blows up earlier.</dt>
 <dd>If a JKS or PKCS12 file is provided that isn't going to work (e.g. no private keys),
 the KeyMaterial constructor throws an exception right away.</dd>
+
 <dt>6. getSSLContext() now available to help inter-op with Java 5 SSL-NIO libraries.</dt>
 <dd>Oleg has been working hard on SSL-NIO for the Apache httpcomponents library.  Go
 check it out!</dd>
@@ -128,12 +189,14 @@ Silly Java - I'm still using <em>your</em> JSSE implementation, I'm just wrappin
 </dd>
 </dl>
 <br/>
+
 <h3>Features as of not-yet-commons-ssl-0.3.4:</h3>
 <dl>
 <dt>1.  <code>"javax.net.ssl.keyStore"</code> and <code>"javax.net.ssl.trustStore"</code></dt>
 <dd>SSLClient and SSLServer now set their default TrustMaterial and KeyMaterial from these
  system properties if they are present.</dd>
 <dt>2.  <code>ssl.setCheckCRL( true/false )</code> <em>Note: <a href="http://en.wikipedia.org/wiki/Certificate_revocation_list">CRL</a> is an abbreviation for "Certificate Revocation List"</em></dt>
+
 <dd>Set to <code>true</code> by default.  If you're using SSLClient, then the remote
 server's certificate chain is checked.  If you're using SSLServer, CRL checking is ignored <em>unless</em>
 client certificates are presented.  Commons-SSL tries to perform the CRL check against each certificate in
@@ -147,6 +210,7 @@ certificate as the key.  The cached "pass" result is discarded every 24 hours.
 until the JVM restarts.
 </p>
 </dd>
+
 <dt>3.  <code>ssl.setCheckExpiry( true/false )</code></dt>
 <dd>Certificate expiry checking can be turned off.  Turned on by default.  For Java 1.4 and newer we're
 intercepting the CertificateException thrown by the TrustManager.  But we still implemented our own
@@ -170,6 +234,7 @@ i: CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US
 </pre>
 </p>
 </dd>
+
 <dt>5.  PKCS8 support.</dt>
 <dd>Support for OpenSSL "Traditional" and PKCS8 encrypted private keys added.
 Private keys can be RSA or DSA.  See our <a href="pkcs8.html">pkcs8 page</a> for more details.</dt>
@@ -177,53 +242,10 @@ Private keys can be RSA or DSA.  See our <a href="pkcs8.html">pkcs8 page</a> for
 <dd>Command line utility converts an OpenSSL pair (private key + certificate) into a Java Keystore ("JKS")
 file.  To see the command-line options, visit our <a href="utilities.html">utilities page</a>, or just run:
 <pre style="font-style: 90%; padding: 0 30px;">
+
 java -cp commons-ssl-0.3.4.jar org.apache.commons.ssl.KeyStoreBuilder
 </pre></dd>
 </dl>
 
-<hr/>
-<h3><a name="roadmap">Road Map For Future Versions</a></h3>
-<p>0.3.10 - 0.3.11 are just some feature ideas.  They might not be feasible.  <b style="background-color: yellow;">0.3.9 is the current version.</b></p>
-<table cellspacing="0" cellpadding="4" border="1">
-<tr><th>Version</th><th>Release Date?</th><th>Description</th></tr>
-<tr><td class="v">0.3.4</td><td class="v">Nov 2006</td><td>90% feature complete.  Probably contains some bugs.</td></tr>
-<tr><td class="v">0.3.5</td><td class="v">Dec 2006</td><td>PKCS8Key constructor is public now.  Whoops.  Hostname verification
-knows about more than just CN's now - also checks subjectAlts in the server's certificate.</td></tr>
-<tr><td class="v">0.3.6</td><td class="v">Jan 2007</td><td>Fixed Java 1.4 bug with HttpsURLConnection.</td></tr>
-<tr><td class="v">0.3.7</td><td class="v">Feb 2007</td><td>40 bit and 56 bit ciphers disabled by default.  RMI-SSL improved.  getSSLContext() added.  Various other improvements.</td></tr>
-<tr class="v"><td class="v">0.3.8</td><td class="v">Nov 2007</td><td>PBE (password-based-encryption) formally introduced and improved.  40 bit and 56 bit ciphers still disabled by default, but working better when re-enabled.</td></tr>
-<tr class="released"><td class="v">0.3.9</td><td class="v">May 2008</td><td>Some PBE fixes.  Using latest ASN.1 code from BouncyCastle.</td></tr>
-<tr class="unreleased"><td class="v">0.3.10</td><td class="v">May 2008</td><td>
-<p>
-Socket monitoring.  Make it easier for long-running server applications to warn
-about impending certificate expiries.
-</p>
-<p>
-<a href="http://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol">OCSP</a> - Online Certificate Status Protocol
-</p>
-<p>
-NotQuiteSoEasySSLProtocolSocketFactory will trust any server The First Time, and store that server's cert on disk for future accesses.
-</p>
-</td></tr>
-<tr><td class="v">0.3.11</td><td class="v">Jun 2008</td><td><code>TrustMaterial.setAutoReload( true / false )</code>, and <code>KeyMaterial.setAutoReload( true / false )</code>,
-but only if no password, or "changeit" was provided.  (Question:  should this "reload" tear down all open sockets?).
-</td></tr>
-<tr><td class="v">0.4.0</td><td class="v">Jul 2008</td><td>Non-public code (protected, private, etc) moved into a separate "impl" package where possible.</td></tr>
-<tr><td class="v">0.5.0</td><td class="v">Aug 2008</td><td>API froven.  All future versions must be reverse-compatible with 0.5.0 (except for any parts of 0.5.0 later found to be insecure).</td></tr>
-<tr><td class="v">0.7.0</td><td class="v">Nov 2008</td><td>JavaDocs written for all public methods and classes.</td></tr>
-<tr><td class="v">0.7.5</td><td class="v">Mar 2009</td><td>JUnit tests written for all classes.</td></tr>
-<tr><td class="v">0.9.0</td><td class="v">May 2009</td><td>First BETA release.  JUnit tests passing on all targetted platforms:
-<ol>
-<li>Intel/AMD: (Sun, IBM, BEA) x (Linux, Mac, Windows) x (1.3, 1.4, 5, 6, 7)</li>
-<li>All of the above with and without BouncyCastle.</li>
-<li>PowerPC:  Mac OS X 10.4, 10.5</li>
-<li>Linux: Latest GCJ, Kaffe, and Blackdown releases.  BouncyCastle added if necessary to get tests to pass.</li>
-<li>Anyone got an IBM mainframe we can test on?</li>
-</td></tr>
-<tr><td class="v">0.9.1 - 0.9.9</td><td class="v">Aug 2009</td><td>Bug fixes.</td></tr>
-<tr><td class="v">1.0.0</td><td class="v">Jan 2010</td><td>Development mostly stops.</td></tr>
-</table>
-<p>The problem we're solving with Commons-SSL
-is quite small, so I don't see any reason to ever go beyond 1.0.0, except for fixing bugs.</p>
 </body>
 </html>
diff --git a/docs/download.html~ b/docs/download.html~
deleted file mode 100644
index 9eb706b..0000000
--- a/docs/download.html~
+++ /dev/null
@@ -1,229 +0,0 @@
-<html>
-<head>
-<title>Not-Yet-Commons-SSL - Downloads, Features, Future Directions</title>
-<style type="text/css">
-dl, h1, h2, h3, h4 { margin: 0; border: 0; padding: 0; font-size: 100%; }
-h1 { float: left; color: red; }
-b.n { font-family: arial; font-weight: bold; }
-span.hl { color: white; background-color: green; }
-div.nav { float: left; margin-left: 20px; font-weight: bold; }
-.nav a, .nav span { padding: 0 5px; }
-.nav a { color: blue; }
-td.v { text-align: center; }
-dt { padding: 8px 0 8px 5px; }
-dd { padding-left: 15px; }
-li { padding-bottom: 6px; }
-tr.released td, tr.released th { background-color: yellow; font-weight: bold; }
-</style>
-</head>
-<body>
-<h1>not-yet-commons-ssl</h1>
-<div class="nav">
-<a href="index.html">main</a> |
-<a href="ssl.html">ssl</a> |
-<a href="pkcs8.html">pkcs8</a> |
-<a href="pbe.html">pbe</a> |
-<a href="rmi.html">rmi</a> |
-<a href="utilities.html">utilities</a> |
-<a href="source.html">source</a> |
-<a href="javadocs/">javadocs</a> |
-<span class="hl" href="download.html">download</span>
-</div>
-<br clear="all"/>
-<hr/>
-<h2>Download Not-Yet-Commons-SSL!</em></h2>
-<p>Not-Yet-Commons-SSL currently has NO affiliation with the <a href="http://apache.org/">Apache Software Foundation</a> (apache.org), but we're hoping
-to start <a href="http://incubator.apache.org/incubation/Incubation_Policy.html">Incubation</a> one day.
-<table cellpadding="6" cellspacing="0" border="0" style="margin-top: 9px;">
-<tr><th colspan="3">Current Version (November 14th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.zip">not-yet-commons-ssl-0.3.9.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 8063831d05fc6204a7c0c23a0f86b086</td></tr>
-<tr><td>Binary only:</td><td><a href="/commons-ssl/not-yet-commons-ssl-0.3.9.jar">not-yet-commons-ssl-0.3.9.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: </td></tr>
-<tr><th colspan="3">Previous Version (July 4th, 2007):</th></tr>
-<tr><td>Full source:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.zip">not-yet-commons-ssl-0.3.8.zip</a></td><td>2.3MB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 6c709837f9fef310a69f8659f1697c81</td></tr>
-<tr><td>Binary only:</td><td><a href="/not-yet-commons-ssl-0.3.8/not-yet-commons-ssl-0.3.8.jar">not-yet-commons-ssl-0.3.8.jar</a></td><td>189KB</td><td><span style="color: red;">Alpha</span></td><td>MD5: 34996468b477e3a6c81d7feec213288b</td></tr>
-</table>
-<br/><b>Warning:</b>
- <span style="color: red; font-weight: bold;">not-yet-commons-ssl-0.3.9 should be considered to be of "Alpha" quality!
-This code probably contains bugs.  This code may have security issues.</span>
-<p>Future versions will definitely break the current API in a non-reverse compatible way.  After commons-ssl-0.5.0, though, we
-plan on always being reverse compatible with ourselves.
-<hr/>
-<h3>Features as of not-yet-commons-ssl-0.3.9:</h3>
-<dl>
-<dt>1. <a href="pbe.html">PBE</a> is now Compatible with <code>openssl enc -K [key] -iv [IV]</code>.</dt>
-<dd>People were asking for this.  See the PBE page for more details.</dd>
-<dt>2. DES2 with PBE was broken.</dt>
-<dd>Fixed.</dd>
-<dt>3. directory.apache.org didn't write the ASN.1 code.  BouncyCastle did.</dt>
-<dd>Now using latest ASN.1 parsing code from BC, and attributing it properly.</dd>
-<dt>4. The "ping" utility has a few more options.</dt>
-<dd>For those who need more than just a "HEAD /" request.  You can also set the HTTP host header,
-independant of the target host/ip.</dd>
-</dl>
-<br/>
-<h3>Features as of not-yet-commons-ssl-0.3.8:</h3>
-<dl>
-<dt>1. useDefaultJavaCiphers() actually works now.</dt>
-<dd>When you want to allow 40 bit, 56 bit, and MD5 based SSL ciphers, use this.  It was 99% functional in 0.3.7, but there was a
-rare situation where setting ciphers was causing SSL handshake errors.</dd>
-<dt>2. <a href="pbe.html">PBE</a> (password-based-encryption) improved.</dt>
-<dd>PBE now has its own <a href="pbe.html">HTML page</a>.  Support for all of OpenSSL's PBE ciphers implemented and tested, including
-IDEA and RC5.  (DES-X might work, but couldn't find a JCE provider that supported it).  Threw in support for some
-additional BouncyCastle ciphers even though OpenSSL doesn't support them (cast6, gost28147, rc6, seed, serpent,
-skipjack, tea, twofish, xtea).  Around <a href="samples/pbe/">650 test files</a> created to make sure PBE is working properly.
-</dd>
-<dt>3. PBE API changed on <a href="javadocs/org/apache/commons/ssl/OpenSSL.html#encrypt(java.lang.String,%20char[],%20java.io.InputStream)">OpenSSL.encrypt()</a> and <a href="javadocs/org/apache/commons/ssl/OpenSSL.html#decrypt(java.lang.String,%20char[],%20java.io.InputStream)">OpenSSL.decrypt()</a>.</dt>
-<dd>The password is now char[] instead of byte[] (sorry!).  Encrypt/decrypt on byte[] introduced.  Encrypt/decrypt on InputStream
-is still available, and is properly streamed so that even extremely large files can be encrypted/decrypted.</dd>
-</dl>
-<br/>
-<h3>Features as of not-yet-commons-ssl-0.3.7:</h3>
-<dl>
-<dt>1. useStrongCiphers() used by default.</dt>
-<dd>40 bit and 56 bit ciphers are now disabled by default.  To turn them back on call useDefaultJavaCiphers().</dd>
-<dt>2. addAllowedName() adds some flexibility to the CN verification.</dt>
-<dd>
-Here's a code example using "cucbc.com" to connect, but anticipating "www.cucbc.com" in the server's certificate:
-<pre>
-SSLClient client = new SSLClient();
-client.addAllowedName( "www.cucbc.com" );
-Socket s = client.createSocket( "cucbc.com", 443 );
-</pre>
-This technique is also useful if you don't want to use DNS, and want to
-connect using the IP address.
-</dd>
-<dt>3. SSLServer can re-use a Tomcat-8443 private key if running from inside Tomcat.</dt>
-<dd>
-<pre>
-SSLClient server = new SSLServer();
-server.useTomcatSSLMaterial();
-</pre>
-</dd>
-<dt>4. RMI-SSL support improved.</dt>
-<dd>Attempts to re-use the Tomcat-8443 private key for all RMI SSL Server sockets.
-Anonymous server-sockets (port 0) will always be set to port 31099.  Analyzes the
-server certificate CN field and tries to set "java.rmi.server.hostname" to something
-compatible with that.  Probably the only free implementation around that does a good
-job on the hostname verification!
-</dd>
-<dt>5. KeyMaterial constructor blows up earlier.</dt>
-<dd>If a JKS or PKCS12 file is provided that isn't going to work (e.g. no private keys),
-the KeyMaterial constructor throws an exception right away.</dd>
-<dt>6. getSSLContext() now available to help inter-op with Java 5 SSL-NIO libraries.</dt>
-<dd>Oleg has been working hard on SSL-NIO for the Apache httpcomponents library.  Go
-check it out!</dd>
-<dt>7. Fixed bug where SSLClient couldn't be used with javax.net.ssl.HttpsURLConnection
-on Java 1.4.x</dt>
-<dd>I was wrapping the SSLSocket, but Java 1.4.x guards against that inside HttpsURLConnection
-and throws this exciting exception:
-<pre>
-java.lang.RuntimeException: Export restriction: this JSSE implementation is non-pluggable.
-  at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.checkCreate(DashoA6275)
-  at sun.net.www.protocol.https.HttpsClient.afterConnect(DashoA6275)
-  at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(DashoA6275)
-  at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:560)
-  at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(DashoA6275)
-</pre>
-Silly Java - I'm still using <em>your</em> JSSE implementation, I'm just wrapping it!
-</dd>
-</dl>
-<br/>
-<h3>Features as of not-yet-commons-ssl-0.3.4:</h3>
-<dl>
-<dt>1.  <code>"javax.net.ssl.keyStore"</code> and <code>"javax.net.ssl.trustStore"</code></dt>
-<dd>SSLClient and SSLServer now set their default TrustMaterial and KeyMaterial from these
- system properties if they are present.</dd>
-<dt>2.  <code>ssl.setCheckCRL( true/false )</code> <em>Note: <a href="http://en.wikipedia.org/wiki/Certificate_revocation_list">CRL</a> is an abbreviation for "Certificate Revocation List"</em></dt>
-<dd>Set to <code>true</code> by default.  If you're using SSLClient, then the remote
-server's certificate chain is checked.  If you're using SSLServer, CRL checking is ignored <em>unless</em>
-client certificates are presented.  Commons-SSL tries to perform the CRL check against each certificate in
-the chain, but we're not sure if we always know the entire chain.
-<p><em>Implementation note:</em>
-To reduce memory consumption all CRL's are saved to disk using
-<code>File.createTempFile()</code> and <code>File.deleteOnExit()</code>.
-CRL's are re-downloaded every 24 hours.  To reduce disk IO
-the "pass/fail" result of a CRL check for a given X.509 Certificate is cached using the 20 byte SHA1 hash of the
-certificate as the key.  The cached "pass" result is discarded every 24 hours.  The cached "fail" result is retained 
-until the JVM restarts.
-</p>
-</dd>
-<dt>3.  <code>ssl.setCheckExpiry( true/false )</code></dt>
-<dd>Certificate expiry checking can be turned off.  Turned on by default.  For Java 1.4 and newer we're
-intercepting the CertificateException thrown by the TrustManager.  But we still implemented our own
-expiry checking because Java 1.3 doesn't check expiry.  We check every certificate in
-the chain, but we're not sure if we always know the entire chain.</dd>
-<dt>4.  <code>ssl.setCheckHostname( true/false )</code></dt>
-<dd>Certificate hostname checking improved.  Turned on by default for SSLClient, but turned off by
-default for SSLServer.  If turned on for SSLServer, only applied to client certificates by checking
-against a reverse DNS lookup of the client's IP address.  Turning on for SSLServer will probably be
-quite rare.  We imagine that applications (such as Tomcat) will pass the client chain back up into
-the business layer where people can code in any kind of validation logic they like.  But we put
-it in anyway to keep things consistent.
-<p>Support added for certificates with wildcards in the CN field 
-(e.g. <a href="https://www.credential.com/">*.credential.com</a>). 
-Java already had this, to be fair.  We broke it
-by accident!
-<pre style="font-style: 90%; padding: 0 30px;">
-s: CN=*.credential.com, OU=Domain Control Validated - RapidSSL(R), OU=See www.rapidssl.com/cps (c)05,
-   OU=businessprofile.geotrust.com/get.jsp?GT27402892, O=*.credential.com, C=CA
-i: CN=Equifax Secure Global eBusiness CA-1, O=Equifax Secure Inc., C=US
-</pre>
-</p>
-</dd>
-<dt>5.  PKCS8 support.</dt>
-<dd>Support for OpenSSL "Traditional" and PKCS8 encrypted private keys added.
-Private keys can be RSA or DSA.  See our <a href="pkcs8.html">pkcs8 page</a> for more details.</dt>
-<dt>6.  New Utility: "<code>KeyStoreBuilder</code>"</dt>
-<dd>Command line utility converts an OpenSSL pair (private key + certificate) into a Java Keystore ("JKS")
-file.  To see the command-line options, visit our <a href="utilities.html">utilities page</a>, or just run:
-<pre style="font-style: 90%; padding: 0 30px;">
-java -cp commons-ssl-0.3.4.jar org.apache.commons.ssl.KeyStoreBuilder
-</pre></dd>
-</dl>
-
-<hr/>
-<h3><a name="roadmap">Road Map For Future Versions</a></h3>
-<p>0.3.10 - 0.3.11 are just some feature ideas.  They might not be feasible.  <b style="background-color: yellow;">0.3.9 is the current version.</b></p>
-<table cellspacing="0" cellpadding="4" border="1">
-<tr><th>Version</th><th>Release Date?</th><th>Description</th></tr>
-<tr><td class="v">0.3.4</td><td class="v">Nov 2006</td><td>90% feature complete.  Probably contains some bugs.</td></tr>
-<tr><td class="v">0.3.5</td><td class="v">Dec 2006</td><td>PKCS8Key constructor is public now.  Whoops.  Hostname verification
-knows about more than just CN's now - also checks subjectAlts in the server's certificate.</td></tr>
-<tr><td class="v">0.3.6</td><td class="v">Jan 2007</td><td>Fixed Java 1.4 bug with HttpsURLConnection.</td></tr>
-<tr><td class="v">0.3.7</td><td class="v">Feb 2007</td><td>40 bit and 56 bit ciphers disabled by default.  RMI-SSL improved.  getSSLContext() added.  Various other improvements.</td></tr>
-<tr class="v"><td class="v">0.3.8</td><td class="v">Nov 2007</td><td>PBE (password-based-encryption) formally introduced and improved.  40 bit and 56 bit ciphers still disabled by default, but working better when re-enabled.</td></tr>
-<tr class="released"><td class="v">0.3.9</td><td class="v">May 2008</td><td>Some PBE fixes.  Using latest ASN.1 code from BouncyCastle.</td></tr>
-<tr class="unreleased"><td class="v">0.3.10</td><td class="v">May 2008</td><td>
-<p>
-Socket monitoring.  Make it easier for long-running server applications to warn
-about impending certificate expiries.
-</p>
-<p>
-<a href="http://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol">OCSP</a> - Online Certificate Status Protocol
-</p>
-<p>
-NotQuiteSoEasySSLProtocolSocketFactory will trust any server The First Time, and store that server's cert on disk for future accesses.
-</p>
-</td></tr>
-<tr><td class="v">0.3.11</td><td class="v">Jun 2008</td><td><code>TrustMaterial.setAutoReload( true / false )</code>, and <code>KeyMaterial.setAutoReload( true / false )</code>,
-but only if no password, or "changeit" was provided.  (Question:  should this "reload" tear down all open sockets?).
-</td></tr>
-<tr><td class="v">0.4.0</td><td class="v">Jul 2008</td><td>Non-public code (protected, private, etc) moved into a separate "impl" package where possible.</td></tr>
-<tr><td class="v">0.5.0</td><td class="v">Aug 2008</td><td>API froven.  All future versions must be reverse-compatible with 0.5.0 (except for any parts of 0.5.0 later found to be insecure).</td></tr>
-<tr><td class="v">0.7.0</td><td class="v">Nov 2008</td><td>JavaDocs written for all public methods and classes.</td></tr>
-<tr><td class="v">0.7.5</td><td class="v">Mar 2009</td><td>JUnit tests written for all classes.</td></tr>
-<tr><td class="v">0.9.0</td><td class="v">May 2009</td><td>First BETA release.  JUnit tests passing on all targetted platforms:
-<ol>
-<li>Intel/AMD: (Sun, IBM, BEA) x (Linux, Mac, Windows) x (1.3, 1.4, 5, 6, 7)</li>
-<li>All of the above with and without BouncyCastle.</li>
-<li>PowerPC:  Mac OS X 10.4, 10.5</li>
-<li>Linux: Latest GCJ, Kaffe, and Blackdown releases.  BouncyCastle added if necessary to get tests to pass.</li>
-<li>Anyone got an IBM mainframe we can test on?</li>
-</td></tr>
-<tr><td class="v">0.9.1 - 0.9.9</td><td class="v">Aug 2009</td><td>Bug fixes.</td></tr>
-<tr><td class="v">1.0.0</td><td class="v">Jan 2010</td><td>Development mostly stops.</td></tr>
-</table>
-<p>The problem we're solving with Commons-SSL
-is quite small, so I don't see any reason to ever go beyond 1.0.0, except for fixing bugs.</p>
-</body>
-</html>
diff --git a/docs/index.html b/docs/index.html
index eafed68..0a82fa9 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -23,21 +23,23 @@ th { text-align: right; }
 <h1>not-yet-commons-ssl</h1>
 <div class="nav">
 <span class="hl">main</span> |
+
 <a href="ssl.html">ssl</a> |
 <a href="pkcs8.html">pkcs8</a> |
 <a href="pbe.html">pbe</a> |
 <a href="rmi.html">rmi</a> |
 <a href="utilities.html">utilities</a> |
 <a href="source.html">source</a> |
+
 <a href="javadocs/">javadocs</a> |
 <a href="download.html">download</a>
 </div>
 <br clear="all"/>
 <hr/>
 <h2>Not-Yet-Commons-SSL</h2>
-<p><a href="download.html">not-yet-commons-ssl-0.3.9</a> released! (November 14th, 2007)</p>
-<p>Requires Java 1.3.x or higher.
-<br/>Some features require Java 1.4.x or higher.   (<a href="rmi.html">RMI-SSL</a>, for example).</p>
+<p><a href="download.html">not-yet-commons-ssl-0.3.15</a> released! (September 8th, 2014)</p>
+<p>Requires Java 1.5.x or higher.
+
 <p>Please see our <a href="ssl.html">ssl page</a> for code examples on how to use this library.</a></p>
 
 <h3>Resources:</h3>
@@ -46,11 +48,13 @@ th { text-align: right; }
     <th>Design Goals:</th>
     <td><a href="about.html">about.html</a></td>
 </tr>
+
 <tr>
     <th>Code Examples:</th>
     <td><a href="ssl.html">SSL/TLS</a>  |  <a href="pkcs8.html">PKCS #8</a>  |  <a href="pbe.html">PBE</a></td>
 </tr>
 <tr>
+
     <th>Join Mailing List:</th>
     <td><a href="http://lists.juliusdavies.ca/listinfo.cgi/not-yet-commons-ssl-juliusdavies.ca/">http://lists.juliusdavies.ca/listinfo.cgi/not-yet-commons-ssl-juliusdavies.ca/</a></td>
 </tr>
@@ -58,6 +62,7 @@ th { text-align: right; }
     <th>Mailing List Archives:</th>
     <td><a href="http://lists.juliusdavies.ca/pipermail/not-yet-commons-ssl-juliusdavies.ca/">http://lists.juliusdavies.ca/pipermail/not-yet-commons-ssl-juliusdavies.ca/</a></td>
 </tr>    
+
 <tr>
     <th>Downloads:</th>
     <td><a href="download.html">http://juliusdavies.ca/commons-ssl/download.html</a></td>
@@ -65,14 +70,16 @@ th { text-align: right; }
 <tr>
     <th>Checkout From Subversion:</th>
     <td><code>svn co <a style="text-decoration: none;" href="http://juliusdavies.ca/svn/not-yet-commons-ssl/trunk">http://juliusdavies.ca/svn/not-yet-commons-ssl/trunk</a> not-yet-commons-ssl</code></td>
+
 </tr>
 <tr>
     <th>Browse Subversion (via viewvc):</th>
-    <td><a href="http://juliusdavies.ca/svn/viewvc.cgi">http://juliusdavies.ca/svn/not-yet-commons-ssl/viewvc.cgi</a></td>
+    <td><a href="http://juliusdavies.ca/svn/viewvc.cgi/not-yet-commons-ssl/">http://juliusdavies.ca/svn/not-yet-commons-ssl/viewvc.cgi/not-yet-commons-ssl/</a></td>
 </tr>
 <tr>
     <th>License (Apache 2.0):</th>
-    <td><a href="../LICENSE.txt">LICENSE.txt</a></td>
+    <td><a href="LICENSE.txt">LICENSE.txt</a></td>
+
 </tr>
 </table>
 <hr/>
@@ -84,6 +91,7 @@ The webpages, releases, and code here on <a href="http://juliusdavies.ca/">juliu
 the Apache Software Foundation, but all code is licensed under <a href="LICENSE.txt">ASL 2.0</a>.
 </p>
 <p>The <a href="http://juliusdavies.ca/svn/viewvc.cgi/trunk/src/java/org/apache/commons/ssl/asn1/">ASN.1 parsing code</a>
+
 comes directly from BouncyCastle (<a href="http://bouncycastle.org/">bouncycastle.org</a>).  Our only modification to this
 code was an accidental "reformat" to bring it inline with our code style.  Also, in two places, we switched the BC code
 to use <em>our</em> Hex.java
@@ -100,6 +108,7 @@ BouncyCastle maintains copyright over all the code used, but allows us to reuse
 example in the <a href="http://jakarta.apache.org/httpcomponents/">HttpComponents</a> SVN repository.
 His
 <a href="http://svn.apache.org/viewvc/jakarta/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java?view=markup">AuthSSLProtocolSocketFactory.java</a>
+
 and
 <a href="http://svn.apache.org/viewvc/jakarta/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/AuthSSLX509TrustManager.java?view=markup">AuthSSLX509TrustManager.java</a>
 examples
diff --git a/docs/openssl/compare.txt b/docs/openssl/compare.txt
new file mode 100644
index 0000000..40c469d
--- /dev/null
+++ b/docs/openssl/compare.txt
@@ -0,0 +1,28 @@
+
+Performance of org.apache.commons.ssl.OpenSSL.decrypt()
+
+Decrypting the same 946MB Base64 DES-3 encrypted file.
+
+
+OpenSSL 0.9.7l 28 Sep 2006
+--------------------
+real	1m40.578s
+user	1m34.223s
+sys	0m04.039s
+
+
+not-yet-commons-ssl-0.3.10
+(22% slower than OpenSSL!)
+--------------------
+real	2m03.270s
+user	1m56.959s
+sys	0m03.605s
+
+
+not-yet-commons-ssl-0.3.9
+(3,000% slower than OpenSSL!)
+--------------------
+real	50m47.424s
+user	18m47.687s
+sys	31m30.298s
+
diff --git a/docs/openssl/profile.3.10 b/docs/openssl/profile.3.10
new file mode 100644
index 0000000..d52bd7d
--- /dev/null
+++ b/docs/openssl/profile.3.10
@@ -0,0 +1,72 @@
+Flat profile of 140.04 secs (12528 total ticks): main
+
+  Interpreted + native   Method                        
+  0.7%     0  +    90    java.io.FileOutputStream.writeBytes
+  0.4%     0  +    56    java.io.FileInputStream.readBytes
+  0.2%     0  +    24    java.lang.System.arraycopy
+  0.0%     5  +     0    org.apache.commons.ssl.ComboInputStream.read
+  0.0%     4  +     0    com.sun.crypto.provider.SunJCE_h.a
+  0.0%     3  +     0    javax.crypto.CipherInputStream.available
+  0.0%     2  +     0    com.sun.crypto.provider.SunJCE_h.a
+  0.0%     2  +     0    org.apache.commons.ssl.Base64.decodeBase64
+  0.0%     0  +     2    java.io.FileInputStream.read
+  0.0%     2  +     0    java.io.PrintStream.write
+  0.0%     0  +     2    java.lang.String.intern
+  0.0%     2  +     0    com.sun.crypto.provider.SunJCE_e.a
+  0.0%     1  +     0    java.math.BigInteger.addOne
+  0.0%     1  +     0    java.util.HashMap.getEntry
+  0.0%     1  +     0    java.lang.String.<init>
+  0.0%     1  +     0    sun.security.x509.RDN.<init>
+  0.0%     0  +     1    java.lang.ClassLoader.defineClass1
+  0.0%     1  +     0    java.math.BigInteger.mulAdd
+  0.0%     0  +     1    java.util.zip.Inflater.inflateBytes
+  0.0%     0  +     1    java.util.zip.ZipFile.getEntry
+  0.0%     1  +     0    org.apache.commons.ssl.Util.pipeStream
+  0.0%     0  +     1    java.lang.Class.forName0
+  0.0%     1  +     0    java.lang.StringCoding$CharsetSD.decode
+  0.0%     1  +     0    java.util.HashMap.<init>
+  0.0%     0  +     1    java.lang.Object.clone
+  1.8%    46  +   180    Total interpreted (including elided)
+
+     Compiled + native   Method                        
+ 71.9%  8987  +     0    com.sun.crypto.provider.SunJCE_y.c
+  7.0%   706  +   167    org.apache.commons.ssl.util.ReadLine.nextAsBytes
+  3.1%   391  +     0    com.sun.crypto.provider.SunJCE_m.b
+  2.2%   252  +    28    org.apache.commons.ssl.Base64.decodeBase64
+  2.0%   249  +     0    org.apache.commons.ssl.Base64InputStream.getLine
+  1.3%     0  +   168    org.apache.commons.ssl.Base64.discardNonBase64
+  1.2%     8  +   144    javax.crypto.Cipher.update
+  0.8%     1  +    96    com.sun.crypto.provider.SunJCE_h.a
+  0.3%    37  +     0    javax.crypto.CipherInputStream.read
+  0.2%    22  +     0    org.apache.commons.ssl.Util.pipeStream
+  0.1%    13  +     0    java.io.BufferedInputStream.read1
+  0.1%     7  +     0    java.io.FilterInputStream.read
+  0.0%     2  +     0    adapters
+  0.0%     1  +     0    java.math.BigInteger.squareToLen
+ 90.3% 10676  +   603    Total compiled
+
+         Stub + native   Method                        
+  4.6%     0  +   575    java.io.FileOutputStream.writeBytes
+  3.0%     0  +   380    java.io.FileInputStream.readBytes
+  7.6%     0  +   955    Total stub
+
+  Thread-local ticks:
+  0.3%    36             Blocked (of total)
+  0.1%     7             Class loader
+  0.0%     1             Compilation
+  0.2%    24             Unknown: thread_state
+
+
+Flat profile of 0.01 secs (1 total ticks): DestroyJavaVM
+
+  Thread-local ticks:
+100.0%     1             Blocked (of total)
+
+
+Global summary of 140.06 seconds:
+100.0% 12563             Received ticks
+  0.2%    29             Received GC ticks
+  0.5%    65             Compilation
+  0.0%     4             Other VM operations
+  0.1%     7             Class loader
+  0.2%    24             Unknown code
diff --git a/docs/openssl/profile.3.9 b/docs/openssl/profile.3.9
new file mode 100644
index 0000000..cdff246
--- /dev/null
+++ b/docs/openssl/profile.3.9
@@ -0,0 +1,72 @@
+Flat profile of 3230.62 secs (320463 total ticks): main
+
+  Interpreted + native   Method                        
+  0.0%     0  +    17    java.lang.System.arraycopy
+  0.0%     0  +     7    java.io.FileOutputStream.writeBytes
+  0.0%     0  +     6    java.io.FileInputStream.read
+  0.0%     0  +     4    java.lang.Object.clone
+  0.0%     0  +     3    java.io.FileInputStream.readBytes
+  0.0%     2  +     0    com.sun.crypto.provider.SunJCE_e.<clinit>
+  0.0%     2  +     0    java.lang.StringCoding.trim
+  0.0%     0  +     2    java.util.zip.Inflater.inflateBytes
+  0.0%     2  +     0    java.math.BigInteger.multiplyToLen
+  0.0%     2  +     0    com.sun.crypto.provider.SunJCE_h.a
+  0.0%     1  +     0    sun.security.util.DerValue.init
+  0.0%     1  +     0    com.sun.crypto.provider.SunJCE_y.a
+  0.0%     1  +     0    org.apache.commons.ssl.Base64.decodeBase64
+  0.0%     1  +     0    com.sun.crypto.provider.SunJCE_y.c
+  0.0%     1  +     0    com.sun.crypto.provider.SunJCE_h.a
+  0.0%     1  +     0    java.lang.String.toLowerCase
+  0.0%     1  +     0    sun.security.pkcs.PKCS7.parse
+  0.0%     0  +     1    java.lang.ClassLoader.findBootstrapClass
+  0.0%     1  +     0    sun.misc.CharacterDecoder.decodeLinePrefix
+  0.0%     1  +     0    java.lang.String.lastIndexOf
+  0.0%     1  +     0    java.util.AbstractList.iterator
+  0.0%     1  +     0    java.util.HashMap.newValueIterator
+  0.0%     1  +     0    java.io.DataInputStream.<init>
+  0.0%     0  +     1    org.apache.commons.ssl.JavaImpl.<clinit>
+  0.0%     1  +     0    java.util.HashMap.resize
+  0.0%    28  +    42    Total interpreted (including elided)
+
+     Compiled + native   Method                        
+  0.0%   111  +     0    com.sun.crypto.provider.SunJCE_y.c
+  0.0%     0  +    76    javax.crypto.Cipher.update
+  0.0%    16  +     0    org.apache.commons.ssl.Util.readLine
+  0.0%    12  +     0    org.apache.commons.ssl.Base64.decodeBase64
+  0.0%    11  +     0    java.nio.charset.CharsetEncoder.encode
+  0.0%     9  +     0    org.apache.commons.ssl.Base64InputStream.getLine
+  0.0%     7  +     1    java.lang.StringCoding$CharsetSE.encode
+  0.0%     5  +     0    com.sun.crypto.provider.SunJCE_m.b
+  0.0%     3  +     0    org.apache.commons.ssl.Util.pipeStream
+  0.0%     1  +     0    javax.crypto.CipherInputStream.read
+  0.0%     0  +     1    org.apache.commons.ssl.Base64.discardNonBase64
+  0.0%     1  +     0    java.lang.StringCoding.encode
+  0.0%     1  +     0    java.math.BigInteger.squareToLen
+  0.1%   177  +    78    Total compiled
+
+         Stub + native   Method                        
+ 92.6%     0  + 296801   java.io.FileInputStream.read
+  7.3%     0  + 23277    java.io.FileOutputStream.writeBytes
+ 99.9%     0  + 320078   Total stub
+
+  Thread-local ticks:
+  0.0%    22             Blocked (of total)
+  0.0%     7             Class loader
+  0.0%     1             Compilation
+  0.0%     1             Unknown: no last frame
+  0.0%    29             Unknown: thread_state
+
+
+Flat profile of 0.01 secs (1 total ticks): DestroyJavaVM
+
+  Thread-local ticks:
+100.0%     1             Blocked (of total)
+
+
+Global summary of 3230.64 seconds:
+100.0% 320556            Received ticks
+  0.0%    73             Received GC ticks
+  0.0%    61             Compilation
+  0.0%    16             Other VM operations
+  0.0%     7             Class loader
+  0.0%    30             Unknown code
diff --git a/docs/ping.html b/docs/ping.html
index 9be48fd..3458d07 100644
--- a/docs/ping.html
+++ b/docs/ping.html
@@ -42,20 +42,23 @@ certificate even if your client certificate is bad (so even though the SSL
 handshake fails).  And unlike "openssl s_client", this utility can bind
 against any IP address available.
 
-$Name: commons-ssl-0_3_8 $ compiled=[EST:2007-02-22/10:12:26.000]
-Usage:  java -jar not-yet-commons-ssl-0.3.7.jar [options]
+Usage:  java -jar not-yet-commons-ssl-0.3.13.jar [options]
+Version: 0.3.13   Compiled: [PDT:2014-05-08/14:15:16.000]
 Options:   (*=required)
-*  -t  --target           [hostname[:port]]             default port=443
-   -b  --bind             [hostname[:port]]             default port=0 "ANY"
-   -r  --proxy            [hostname[:port]]             default port=80
-   -tm --trust-cert       [path to trust material]  *.{pem, der, crt, jks}
-   -km --client-cert      [path to client's private key]  *.{jks, pkcs12, pkcs8}
-   -cc --cert-chain       [path to client's cert chain if using pkcs8/OpenSSL key]
+*  -t  --target           [hostname[:port]]              default port=443
+   -b  --bind             [hostname[:port]]              default port=0 "ANY"
+   -r  --proxy            [hostname[:port]]              default port=80
+   -tm --trust-cert       [path to trust material]       {pem, der, crt, jks}
+   -km --client-cert      [path to client's private key] {jks, pkcs12, pkcs8}
+   -cc --cert-chain       [path to client's cert chain for pkcs8/OpenSSL key]
    -p  --password         [client cert password]
+   -h  --host-header      [http-host-header]      in case -t is an IP address
+   -u  --path             [path for GET/HEAD request]    default=/
+   -m  --method           [http method to use]           default=HEAD
 
 Example:
 
-java -jar commons-ssl.jar -t cucbc.com:443 -c ./client.pfx -p `cat ./pass.txt`</pre><br clear="all"/>
+java -jar commons-ssl.jar -t host.com:443 -c ./client.pfx -p `cat ./pass.txt` </pre><br clear="all"/>
 
 <p style="margin-top: 8px;"><b>TODO:</b><br/>Apparently Java 6.0 includes support for grabbing passwords from
 standard-in without echoing the typed characters.  Would be nice to use that feature when it's
@@ -63,10 +66,9 @@ available, instead of requiring the password to be specified as a command-line a
 
 <hr/>
 <h2>KeyStoreBuilder</em></h2>
-<p><code>java -cp commons-ssl-0.3.7.jar org.apache.commons.ssl.KeyStoreBuilder</code></p>
+<p><code>java -cp not-yet-commons-ssl-0.3.13.jar org.apache.commons.ssl.KeyStoreBuilder</code></p>
 
 <pre style="border: 1px solid red; padding: 10px; float: left;"><u><b>KeyStoreBuilder converts PKCS12 and PKCS8 to Java "Keystore", and vice versa.</b></u>
-
 KeyStoreBuilder:  creates '[alias].jks' (Java Key Store)
     -topk8 mode:  creates '[alias].pem' (x509 chain + unencrypted pkcs8)
 [alias] will be set to the first CN value of the X509 certificate.
@@ -77,8 +79,7 @@ Usage3: -topk8 [password] [file:jks]
 -------------------------------------------------------------------
 [private-key] can be openssl format, or pkcs8.
 [password] decrypts [private-key], and also encrypts outputted JKS file.
-All files can be PEM or DER.
-</pre><br clear="all"/>
+All files can be PEM or DER.</pre><br clear="all"/>
 
 <br/><b>Warning:</b>
  <span style="color: red; font-weight: bold;">-topk8 outputs the private key UNENCRYPTED!
diff --git a/docs/pkcs8.html b/docs/pkcs8.html
index 40b799f..2119983 100644
--- a/docs/pkcs8.html
+++ b/docs/pkcs8.html
@@ -66,7 +66,7 @@ else if ( pkcs8.isRSA() )
   pk = KeyFactory.getInstance( "RSA" ).generatePrivate( spec );
 }
 
-<em style="color: green;">// For lazier types (like me):</em>
+<em style="color: green;">// For lazier types:</em>
 pk = pkcs8.getPrivateKey();
 </pre>
 <br clear="all"/>
diff --git a/docs/roadmap.html b/docs/roadmap.html
new file mode 100644
index 0000000..3962540
--- /dev/null
+++ b/docs/roadmap.html
@@ -0,0 +1,86 @@
+<html>
+<head>
+<title>Not-Yet-Commons-SSL - Downloads, Features, Future Directions</title>
+<style type="text/css">
+dl, h1, h2, h3, h4 { margin: 0; border: 0; padding: 0; font-size: 100%; }
+h1 { float: left; color: red; }
+b.n { font-family: arial; font-weight: bold; }
+span.hl { color: white; background-color: green; }
+div.nav { float: left; margin-left: 20px; font-weight: bold; }
+.nav a, .nav span { padding: 0 5px; }
+.nav a { color: blue; }
+td.v { text-align: center; }
+dt { padding: 8px 0 8px 5px; }
+dd { padding-left: 15px; }
+li { padding-bottom: 6px; }
+tr.released td, tr.released th { background-color: yellow; font-weight: bold; }
+</style>
+</head>
+<body>
+<h1>not-yet-commons-ssl</h1>
+<div class="nav">
+<a href="index.html">main</a> |
+<a href="ssl.html">ssl</a> |
+
+<a href="pkcs8.html">pkcs8</a> |
+<a href="pbe.html">pbe</a> |
+<a href="rmi.html">rmi</a> |
+<a href="utilities.html">utilities</a> |
+<a href="source.html">source</a> |
+<a href="javadocs/">javadocs</a> |
+
+<span class="hl" href="download.html">download</span>
+</div>
+<br clear="all"/>
+<hr/>
+<h1>This page is out of date.  These days we just do maintenance releases to fix bugs reported on the mailing list.
+Current version is 0.3.15.</h1>
+<h3><a name="roadmap">Road Map For Future Versions</a></h3>
+<p>0.3.10 - 0.3.11 are just some feature ideas.  They might not be feasible.  <b style="background-color: yellow;">0.3.9 is the current version.</b></p>
+<table cellspacing="0" cellpadding="4" border="1">
+<tr><th>Version</th><th>Release Date?</th><th>Description</th></tr>
+<tr><td class="v">0.3.4</td><td class="v">Nov 2006</td><td>90% feature complete.  Probably contains some bugs.</td></tr>
+
+<tr><td class="v">0.3.5</td><td class="v">Dec 2006</td><td>PKCS8Key constructor is public now.  Whoops.  Hostname verification
+knows about more than just CN's now - also checks subjectAlts in the server's certificate.</td></tr>
+<tr><td class="v">0.3.6</td><td class="v">Jan 2007</td><td>Fixed Java 1.4 bug with HttpsURLConnection.</td></tr>
+<tr><td class="v">0.3.7</td><td class="v">Feb 2007</td><td>40 bit and 56 bit ciphers disabled by default.  RMI-SSL improved.  getSSLContext() added.  Various other improvements.</td></tr>
+<tr class="v"><td class="v">0.3.8</td><td class="v">Nov 2007</td><td>PBE (password-based-encryption) formally introduced and improved.  40 bit and 56 bit ciphers still disabled by default, but working better when re-enabled.</td></tr>
+
+<tr class="released"><td class="v">0.3.9</td><td class="v">May 2008</td><td>Some PBE fixes.  Using latest ASN.1 code from BouncyCastle.</td></tr>
+<tr class="unreleased"><td class="v">0.3.10</td><td class="v">May 2008</td><td>
+<p>
+Socket monitoring.  Make it easier for long-running server applications to warn
+about impending certificate expiries.
+</p>
+<p>
+<a href="http://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol">OCSP</a> - Online Certificate Status Protocol
+</p>
+
+<p>
+NotQuiteSoEasySSLProtocolSocketFactory will trust any server The First Time, and store that server's cert on disk for future accesses.
+</p>
+</td></tr>
+<tr><td class="v">0.3.11</td><td class="v">Jun 2008</td><td><code>TrustMaterial.setAutoReload( true / false )</code>, and <code>KeyMaterial.setAutoReload( true / false )</code>,
+but only if no password, or "changeit" was provided.  (Question:  should this "reload" tear down all open sockets?).
+</td></tr>
+<tr><td class="v">0.4.0</td><td class="v">Jul 2008</td><td>Non-public code (protected, private, etc) moved into a separate "impl" package where possible.</td></tr>
+
+<tr><td class="v">0.5.0</td><td class="v">Aug 2008</td><td>API froven.  All future versions must be reverse-compatible with 0.5.0 (except for any parts of 0.5.0 later found to be insecure).</td></tr>
+<tr><td class="v">0.7.0</td><td class="v">Nov 2008</td><td>JavaDocs written for all public methods and classes.</td></tr>
+<tr><td class="v">0.7.5</td><td class="v">Mar 2009</td><td>JUnit tests written for all classes.</td></tr>
+<tr><td class="v">0.9.0</td><td class="v">May 2009</td><td>First BETA release.  JUnit tests passing on all targetted platforms:
+
+<ol>
+<li>Intel/AMD: (Sun, IBM, BEA) x (Linux, Mac, Windows) x (1.3, 1.4, 5, 6, 7)</li>
+<li>All of the above with and without BouncyCastle.</li>
+<li>PowerPC:  Mac OS X 10.4, 10.5</li>
+<li>Linux: Latest GCJ, Kaffe, and Blackdown releases.  BouncyCastle added if necessary to get tests to pass.</li>
+<li>Anyone got an IBM mainframe we can test on?</li>
+</td></tr>
+<tr><td class="v">0.9.1 - 0.9.9</td><td class="v">Aug 2009</td><td>Bug fixes.</td></tr>
+
+<tr><td class="v">1.0.0</td><td class="v">Jan 2010</td><td>Development mostly stops.</td></tr>
+</table>
+<p>The problem we're solving with Commons-SSL
+is quite small, so I don't see any reason to ever go beyond 1.0.0, except for fixing bugs.</p>
diff --git a/docs/tree.html b/docs/tree.html
index 1e543b4..5d50525 100644
--- a/docs/tree.html
+++ b/docs/tree.html
@@ -1,156 +1,1137 @@
-<pre>
-   <a href=".">.</a>
-   |-- [2.5K]  <a href="./404.html">404.html</a>
-   |-- [9.9K]  <a href="./LICENSE.txt">LICENSE.txt</a>
-   |-- [ 441]  <a href="./NOTICE.txt">NOTICE.txt</a>
-   |-- [ 235]  <a href="./README.txt">README.txt</a>
-   |-- [4.8K]  <a href="./TrustExample.java">TrustExample.java</a>
-   |-- [ 23K]  <a href="./TrustExample.java.html">TrustExample.java.html</a>
-   |-- [3.0K]  <a href="./build.xml">build.xml</a>
-   |-- [ 13K]  <a href="./download.html">download.html</a>
-   |-- [6.2K]  <a href="./index.html">index.html</a>
-   |-- [4.0K]  <a href="./javadocs/">javadocs</a>
-   |-- [4.0K]  <a href="./lib/">lib</a>
-   |   |-- [ 46K]  <a href="./lib/commons-codec-1.3.jar">commons-codec-1.3.jar</a>
-   |   |-- [273K]  <a href="./lib/commons-httpclient-3.0.jar">commons-httpclient-3.0.jar</a>
-   |   |-- [ 37K]  <a href="./lib/commons-logging-1.0.4.jar">commons-logging-1.0.4.jar</a>
-   |   `-- [350K]  <a href="./lib/log4j-1.2.13.jar">log4j-1.2.13.jar</a>
-   |-- [189K]  <a href="./not-yet-commons-ssl-0.3.8.jar">not-yet-commons-ssl-0.3.8.jar</a>
-   |-- [2.3M]  <a href="./not-yet-commons-ssl-0.3.8.zip">not-yet-commons-ssl-0.3.8.zip</a>
-   |-- [1.3K]  <a href="./oscp.pem">oscp.pem</a>
-   |-- [7.4K]  <a href="./pbe.html">pbe.html</a>
-   |-- [3.9K]  <a href="./ping.html">ping.html</a>
-   |-- [5.7K]  <a href="./pkcs8.html">pkcs8.html</a>
-   |-- [4.9K]  <a href="./rmi.html">rmi.html</a>
-   |-- [4.0K]  <a href="./samples/">samples</a>
-   |   |-- [  66]  <a href="./samples/PASSWORD.txt">PASSWORD.txt</a>
-   |   |-- [  66]  <a href="./samples/README.txt">README.txt</a>
-   |   |-- [1.5K]  <a href="./samples/createPBESamples.sh">createPBESamples.sh</a>
-   |   |-- [4.0K]  <a href="./samples/dsa/">dsa</a>
-   |   |-- [ 14K]  <a href="./samples/dsa.html">dsa.html</a>
-   |   |-- [1.3K]  <a href="./samples/dsa_result.html">dsa_result.html</a>
-   |   |-- [4.0K]  <a href="./samples/pbe/">pbe</a>
-   |   |   |-- [1.3K]  <a href="./samples/pbe/README.txt">README.txt</a>
-   |   |   |-- [ 20K]  <a href="./samples/pbe/java/">java</a>
-   |   |   `-- [ 12K]  <a href="./samples/pbe/openssl/">openssl</a>
-   |   |-- [ 395]  <a href="./samples/pbe.tests">pbe.tests</a>
-   |   |-- [4.0K]  <a href="./samples/pkcs12/">pkcs12</a>
-   |   |-- [4.0K]  <a href="./samples/rsa/">rsa</a>
-   |   |-- [ 14K]  <a href="./samples/rsa.html">rsa.html</a>
-   |   |-- [1.3K]  <a href="./samples/rsa_result.html">rsa_result.html</a>
-   |   `-- [4.0K]  <a href="./samples/x509/">x509</a>
-   |-- [ 993]  <a href="./server.crt">server.crt</a>
-   |-- [1.1K]  <a href="./source.html">source.html</a>
-   |-- [4.0K]  <a href="./src/">src</a>
-   |   `-- [4.0K]  <a href="./src/java/">java</a>
-   |       `-- [4.0K]  <a href="./src/java/org/">org</a>
-   |           `-- [4.0K]  <a href="./src/java/org/apache/">apache</a>
-   |               `-- [4.0K]  <a href="./src/java/org/apache/commons/">commons</a>
-   |                   |-- [4.0K]  <a href="./src/java/org/apache/commons/httpclient/">httpclient</a>
-   |                   |   `-- [4.0K]  <a href="./src/java/org/apache/commons/httpclient/contrib/">contrib</a>
-   |                   |       `-- [4.0K]  <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/">ssl</a>
-   |                   |           |-- [7.2K]  <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java">AuthSSLProtocolSocketFactory.java</a>
-   |                   |           |-- [3.5K]  <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java">EasySSLProtocolSocketFactory.java</a>
-   |                   |           |-- [5.8K]  <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/StrictSSLProtocolSocketFactory.java">StrictSSLProtocolSocketFactory.java</a>
-   |                   |           `-- [8.8K]  <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/TrustSSLProtocolSocketFactory.java">TrustSSLProtocolSocketFactory.java</a>
-   |                   `-- [4.0K]  <a href="./src/java/org/apache/commons/ssl/">ssl</a>
-   |                       |-- [3.1K]  <a href="./src/java/org/apache/commons/ssl/ASN1Structure.java">ASN1Structure.java</a>
-   |                       |-- [7.1K]  <a href="./src/java/org/apache/commons/ssl/ASN1Util.java">ASN1Util.java</a>
-   |                       |-- [ 17K]  <a href="./src/java/org/apache/commons/ssl/Base64.java">Base64.java</a>
-   |                       |-- [3.5K]  <a href="./src/java/org/apache/commons/ssl/Base64InputStream.java">Base64InputStream.java</a>
-   |                       |-- [2.7K]  <a href="./src/java/org/apache/commons/ssl/CRLUtil.java">CRLUtil.java</a>
-   |                       |-- [ 18K]  <a href="./src/java/org/apache/commons/ssl/Certificates.java">Certificates.java</a>
-   |                       |-- [2.5K]  <a href="./src/java/org/apache/commons/ssl/ComboInputStream.java">ComboInputStream.java</a>
-   |                       |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/DerivedKey.java">DerivedKey.java</a>
-   |                       |-- [1.9K]  <a href="./src/java/org/apache/commons/ssl/HostPort.java">HostPort.java</a>
-   |                       |-- [ 19K]  <a href="./src/java/org/apache/commons/ssl/HostnameVerifier.java">HostnameVerifier.java</a>
-   |                       |-- [3.5K]  <a href="./src/java/org/apache/commons/ssl/HttpSecureProtocol.java">HttpSecureProtocol.java</a>
-   |                       |-- [9.9K]  <a href="./src/java/org/apache/commons/ssl/Java13.java">Java13.java</a>
-   |                       |-- [2.8K]  <a href="./src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java">Java13KeyManagerWrapper.java</a>
-   |                       |-- [3.1K]  <a href="./src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java">Java13TrustManagerWrapper.java</a>
-   |                       |-- [8.3K]  <a href="./src/java/org/apache/commons/ssl/Java14.java">Java14.java</a>
-   |                       |-- [2.8K]  <a href="./src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java">Java14KeyManagerWrapper.java</a>
-   |                       |-- [3.9K]  <a href="./src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java">Java14TrustManagerWrapper.java</a>
-   |                       |-- [8.4K]  <a href="./src/java/org/apache/commons/ssl/JavaImpl.java">JavaImpl.java</a>
-   |                       |-- [6.6K]  <a href="./src/java/org/apache/commons/ssl/KeyMaterial.java">KeyMaterial.java</a>
-   |                       |-- [ 21K]  <a href="./src/java/org/apache/commons/ssl/KeyStoreBuilder.java">KeyStoreBuilder.java</a>
-   |                       |-- [2.5K]  <a href="./src/java/org/apache/commons/ssl/LDAPSocket.java">LDAPSocket.java</a>
-   |                       |-- [3.0K]  <a href="./src/java/org/apache/commons/ssl/LogHelper.java">LogHelper.java</a>
-   |                       |-- [8.2K]  <a href="./src/java/org/apache/commons/ssl/LogWrapper.java">LogWrapper.java</a>
-   |                       |-- [ 23K]  <a href="./src/java/org/apache/commons/ssl/OpenSSL.java">OpenSSL.java</a>
-   |                       |-- [2.0K]  <a href="./src/java/org/apache/commons/ssl/OpenSSLTest.java">OpenSSLTest.java</a>
-   |                       |-- [2.2K]  <a href="./src/java/org/apache/commons/ssl/PBETestCreate.java">PBETestCreate.java</a>
-   |                       |-- [3.2K]  <a href="./src/java/org/apache/commons/ssl/PEMItem.java">PEMItem.java</a>
-   |                       |-- [8.4K]  <a href="./src/java/org/apache/commons/ssl/PEMUtil.java">PEMUtil.java</a>
-   |                       |-- [ 34K]  <a href="./src/java/org/apache/commons/ssl/PKCS8Key.java">PKCS8Key.java</a>
-   |                       |-- [ 14K]  <a href="./src/java/org/apache/commons/ssl/Ping.java">Ping.java</a>
-   |                       |-- [1.9K]  <a href="./src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java">ProbablyBadPasswordException.java</a>
-   |                       |-- [1.9K]  <a href="./src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java">ProbablyNotPKCS8Exception.java</a>
-   |                       |-- [ 20K]  <a href="./src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java">RMISocketFactoryImpl.java</a>
-   |                       |-- [ 24K]  <a href="./src/java/org/apache/commons/ssl/SSL.java">SSL.java</a>
-   |                       |-- [7.6K]  <a href="./src/java/org/apache/commons/ssl/SSLClient.java">SSLClient.java</a>
-   |                       |-- [4.1K]  <a href="./src/java/org/apache/commons/ssl/SSLEchoServer.java">SSLEchoServer.java</a>
-   |                       |-- [5.1K]  <a href="./src/java/org/apache/commons/ssl/SSLProxyServer.java">SSLProxyServer.java</a>
-   |                       |-- [9.8K]  <a href="./src/java/org/apache/commons/ssl/SSLServer.java">SSLServer.java</a>
-   |                       |-- [5.2K]  <a href="./src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java">SSLServerSocketWrapper.java</a>
-   |                       |-- [6.9K]  <a href="./src/java/org/apache/commons/ssl/SSLSocketWrapper.java">SSLSocketWrapper.java</a>
-   |                       |-- [3.8K]  <a href="./src/java/org/apache/commons/ssl/SSLWrapperFactory.java">SSLWrapperFactory.java</a>
-   |                       |-- [7.5K]  <a href="./src/java/org/apache/commons/ssl/TomcatServerXML.java">TomcatServerXML.java</a>
-   |                       |-- [6.7K]  <a href="./src/java/org/apache/commons/ssl/TrustChain.java">TrustChain.java</a>
-   |                       |-- [8.2K]  <a href="./src/java/org/apache/commons/ssl/TrustMaterial.java">TrustMaterial.java</a>
-   |                       |-- [ 11K]  <a href="./src/java/org/apache/commons/ssl/Util.java">Util.java</a>
-   |                       |-- [4.5K]  <a href="./src/java/org/apache/commons/ssl/Version.java">Version.java</a>
-   |                       |-- [7.1K]  <a href="./src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java">X509CertificateChainBuilder.java</a>
-   |                       |-- [4.0K]  <a href="./src/java/org/apache/commons/ssl/asn1/">asn1</a>
-   |                       |   |-- [ 10K]  <a href="./src/java/org/apache/commons/ssl/asn1/ASN1InputStream.java">ASN1InputStream.java</a>
-   |                       |   |-- [2.4K]  <a href="./src/java/org/apache/commons/ssl/asn1/ASN1OutputStream.java">ASN1OutputStream.java</a>
-   |                       |   |-- [4.1K]  <a href="./src/java/org/apache/commons/ssl/asn1/BERConstructedOctetString.java">BERConstructedOctetString.java</a>
-   |                       |   |-- [1.5K]  <a href="./src/java/org/apache/commons/ssl/asn1/BERNull.java">BERNull.java</a>
-   |                       |   |-- [1.7K]  <a href="./src/java/org/apache/commons/ssl/asn1/BERSequence.java">BERSequence.java</a>
-   |                       |   |-- [1.7K]  <a href="./src/java/org/apache/commons/ssl/asn1/BERSet.java">BERSet.java</a>
-   |                       |   |-- [2.9K]  <a href="./src/java/org/apache/commons/ssl/asn1/BERTaggedObject.java">BERTaggedObject.java</a>
-   |                       |   |-- [2.3K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERApplicationSpecific.java">DERApplicationSpecific.java</a>
-   |                       |   |-- [1.7K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERBMPString.java">DERBMPString.java</a>
-   |                       |   |-- [1.8K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERBitString.java">DERBitString.java</a>
-   |                       |   |-- [2.0K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERBoolean.java">DERBoolean.java</a>
-   |                       |   |-- [1.4K]  <a href="./src/java/org/apache/commons/ssl/asn1/DEREncodable.java">DEREncodable.java</a>
-   |                       |   |-- [2.2K]  <a href="./src/java/org/apache/commons/ssl/asn1/DEREnumerated.java">DEREnumerated.java</a>
-   |                       |   |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERGeneralString.java">DERGeneralString.java</a>
-   |                       |   |-- [2.4K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERGeneralizedTime.java">DERGeneralizedTime.java</a>
-   |                       |   |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERIA5String.java">DERIA5String.java</a>
-   |                       |   |-- [2.1K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERInteger.java">DERInteger.java</a>
-   |                       |   |-- [1.5K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERNull.java">DERNull.java</a>
-   |                       |   |-- [1.7K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERNumericString.java">DERNumericString.java</a>
-   |                       |   |-- [3.5K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERObject.java">DERObject.java</a>
-   |                       |   |-- [4.4K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERObjectIdentifier.java">DERObjectIdentifier.java</a>
-   |                       |   |-- [1.5K]  <a href="./src/java/org/apache/commons/ssl/asn1/DEROctetString.java">DEROctetString.java</a>
-   |                       |   |-- [1.7K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERPrintableString.java">DERPrintableString.java</a>
-   |                       |   |-- [2.4K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERSequence.java">DERSequence.java</a>
-   |                       |   |-- [2.2K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERSet.java">DERSet.java</a>
-   |                       |   |-- [2.3K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERString.java">DERString.java</a>
-   |                       |   |-- [3.6K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERTaggedObject.java">DERTaggedObject.java</a>
-   |                       |   |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERTeletexString.java">DERTeletexString.java</a>
-   |                       |   |-- [2.4K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERUTCTime.java">DERUTCTime.java</a>
-   |                       |   |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERUTF8String.java">DERUTF8String.java</a>
-   |                       |   |-- [2.2K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERUniversalString.java">DERUniversalString.java</a>
-   |                       |   |-- [1.5K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERUnknownTag.java">DERUnknownTag.java</a>
-   |                       |   |-- [1.7K]  <a href="./src/java/org/apache/commons/ssl/asn1/DERVisibleString.java">DERVisibleString.java</a>
-   |                       |   `-- [1.8K]  <a href="./src/java/org/apache/commons/ssl/asn1/OIDTokenizer.java">OIDTokenizer.java</a>
-   |                       `-- [4.0K]  <a href="./src/java/org/apache/commons/ssl/rmi/">rmi</a>
-   |                           |-- [2.1K]  <a href="./src/java/org/apache/commons/ssl/rmi/DateRMI.java">DateRMI.java</a>
-   |                           |-- [2.1K]  <a href="./src/java/org/apache/commons/ssl/rmi/IntegerRMI.java">IntegerRMI.java</a>
-   |                           |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/rmi/RemoteDate.java">RemoteDate.java</a>
-   |                           |-- [1.6K]  <a href="./src/java/org/apache/commons/ssl/rmi/RemoteInteger.java">RemoteInteger.java</a>
-   |                           `-- [6.1K]  <a href="./src/java/org/apache/commons/ssl/rmi/Test.java">Test.java</a>
-   |-- [5.4K]  <a href="./ssl.html">ssl.html</a>
-   |-- [   0]  <a href="./tree.html">tree.html</a>
-   |-- [2.8K]  <a href="./two-crls.pem">two-crls.pem</a>
-   |-- [3.8K]  <a href="./utilities.html">utilities.html</a>
-   `-- [  27]  <a href="./version.txt">version.txt</a>
 
-20 directories, 126 files
+<pre><a href=".">.</a>
+   |-- <a href="./LICENSE.txt">LICENSE.txt</a>
+   |-- <a href="./NOTICE.txt">NOTICE.txt</a>
+   |-- <a href="./README.txt">README.txt</a>
+   |-- <a href="./build.xml">build.xml</a>
+   |-- <a href="./docs/">docs</a>
+   |   |-- <a href="./docs/404.html">404.html</a>
+   |   |-- <a href="./docs/TrustExample.java">TrustExample.java</a>
+   |   |-- <a href="./docs/TrustExample.java.html">TrustExample.java.html</a>
+   |   |-- <a href="./docs/about.html">about.html</a>
+   |   |-- <a href="./docs/download.html">download.html</a>
+   |   |-- <a href="./docs/index.html">index.html</a>
+   |   |-- <a href="./docs/openssl/">openssl</a>
+   |   |   |-- <a href="./docs/openssl/compare.txt">compare.txt</a>
+   |   |   |-- <a href="./docs/openssl/profile.3.10">profile.3.10</a>
+   |   |   `-- <a href="./docs/openssl/profile.3.9">profile.3.9</a>
+   |   |-- <a href="./docs/pbe.html">pbe.html</a>
+   |   |-- <a href="./docs/ping.html">ping.html</a>
+   |   |-- <a href="./docs/pkcs8.html">pkcs8.html</a>
+   |   |-- <a href="./docs/rmi.html">rmi.html</a>
+   |   |-- <a href="./docs/roadmap.html">roadmap.html</a>
+   |   |-- <a href="./docs/source.html">source.html</a>
+   |   |-- <a href="./docs/ssl.html">ssl.html</a>
+   |   |-- <a href="./docs/tree.html">tree.html</a>
+   |   `-- <a href="./docs/utilities.html">utilities.html</a>
+   |-- <a href="./javadocs/">javadocs</a>
+   |-- <a href="./lib/">lib</a>
+   |   |-- <a href="./lib/bcprov-jdk16-143.jar">bcprov-jdk16-143.jar</a>
+   |   |-- <a href="./lib/commons-httpclient-3.0.jar">commons-httpclient-3.0.jar</a>
+   |   |-- <a href="./lib/commons-logging-1.0.4.jar">commons-logging-1.0.4.jar</a>
+   |   |-- <a href="./lib/junit-3.8.1.jar">junit-3.8.1.jar</a>
+   |   `-- <a href="./lib/log4j-1.2.13.jar">log4j-1.2.13.jar</a>
+   |-- <a href="./not-yet-commons-ssl-0.3.11.jar">not-yet-commons-ssl-0.3.11.jar</a>
+   |-- <a href="./not-yet-commons-ssl-0.3.11.zip">not-yet-commons-ssl-0.3.11.zip</a>
+   |-- <a href="./samples/">samples</a>
+   |   |-- <a href="./samples/PASSWORD.txt">PASSWORD.txt</a>
+   |   |-- <a href="./samples/README.txt">README.txt</a>
+   |   |-- <a href="./samples/ca/">ca</a>
+   |   |   |-- <a href="./samples/ca/CA.sh">CA.sh</a>
+   |   |   |-- <a href="./samples/ca/clean.sh">clean.sh</a>
+   |   |   |-- <a href="./samples/ca/dsa-intermediate/">dsa-intermediate</a>
+   |   |   |   |-- <a href="./samples/ca/dsa-intermediate/cacert.pem">cacert.pem</a>
+   |   |   |   |-- <a href="./samples/ca/dsa-intermediate/dsa.params">dsa.params</a>
+   |   |   |   |-- <a href="./samples/ca/dsa-intermediate/newcerts/">newcerts</a>
+   |   |   |   `-- <a href="./samples/ca/dsa-intermediate/private/">private</a>
+   |   |   |       `-- <a href="./samples/ca/dsa-intermediate/private/cakey.pem">cakey.pem</a>
+   |   |   |-- <a href="./samples/ca/openssl.cnf">openssl.cnf</a>
+   |   |   |-- <a href="./samples/ca/root/">root</a>
+   |   |   |   |-- <a href="./samples/ca/root/cacert.pem">cacert.pem</a>
+   |   |   |   |-- <a href="./samples/ca/root/newcerts/">newcerts</a>
+   |   |   |   `-- <a href="./samples/ca/root/private/">private</a>
+   |   |   |       `-- <a href="./samples/ca/root/private/cakey.pem">cakey.pem</a>
+   |   |   |-- <a href="./samples/ca/rsa-intermediate/">rsa-intermediate</a>
+   |   |   |   |-- <a href="./samples/ca/rsa-intermediate/cacert.pem">cacert.pem</a>
+   |   |   |   |-- <a href="./samples/ca/rsa-intermediate/newcerts/">newcerts</a>
+   |   |   |   `-- <a href="./samples/ca/rsa-intermediate/private/">private</a>
+   |   |   |       `-- <a href="./samples/ca/rsa-intermediate/private/cakey.pem">cakey.pem</a>
+   |   |   |-- <a href="./samples/ca/rsa.key">rsa.key</a>
+   |   |   |-- <a href="./samples/ca/test-dsa-cert.pem">test-dsa-cert.pem</a>
+   |   |   |-- <a href="./samples/ca/test-dsa-chain.pem">test-dsa-chain.pem</a>
+   |   |   |-- <a href="./samples/ca/test-rsa-cert.pem">test-rsa-cert.pem</a>
+   |   |   `-- <a href="./samples/ca/test-rsa-chain.pem">test-rsa-chain.pem</a>
+   |   |-- <a href="./samples/createPBESamples.sh">createPBESamples.sh</a>
+   |   |-- <a href="./samples/dsa/">dsa</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes128_cbc.pem">openssl_dsa_aes128_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes128_cfb.pem">openssl_dsa_aes128_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes128_ecb.pem">openssl_dsa_aes128_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes128_ofb.pem">openssl_dsa_aes128_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes192_cbc.pem">openssl_dsa_aes192_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes192_cfb.pem">openssl_dsa_aes192_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes192_ecb.pem">openssl_dsa_aes192_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes192_ofb.pem">openssl_dsa_aes192_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes256_cbc.pem">openssl_dsa_aes256_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes256_cfb.pem">openssl_dsa_aes256_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes256_ecb.pem">openssl_dsa_aes256_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_aes256_ofb.pem">openssl_dsa_aes256_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_blowfish_cbc.pem">openssl_dsa_blowfish_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_blowfish_cfb.pem">openssl_dsa_blowfish_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_blowfish_ecb.pem">openssl_dsa_blowfish_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_blowfish_ofb.pem">openssl_dsa_blowfish_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des1_cbc.pem">openssl_dsa_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des1_cfb.pem">openssl_dsa_des1_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des1_ecb.pem">openssl_dsa_des1_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des1_ofb.pem">openssl_dsa_des1_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des2_cbc.pem">openssl_dsa_des2_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des2_cfb.pem">openssl_dsa_des2_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des2_ecb.pem">openssl_dsa_des2_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des2_ofb.pem">openssl_dsa_des2_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des3_cbc.pem">openssl_dsa_des3_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des3_cfb.pem">openssl_dsa_des3_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des3_ecb.pem">openssl_dsa_des3_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_des3_ofb.pem">openssl_dsa_des3_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_rc2_128_cbc.pem">openssl_dsa_rc2_128_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_rc2_128_cfb.pem">openssl_dsa_rc2_128_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_rc2_128_ecb.pem">openssl_dsa_rc2_128_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_rc2_128_ofb.pem">openssl_dsa_rc2_128_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_rc2_40_cbc.pem">openssl_dsa_rc2_40_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_rc2_64_cbc.pem">openssl_dsa_rc2_64_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_unencrypted.der">openssl_dsa_unencrypted.der</a>
+   |   |   |-- <a href="./samples/dsa/openssl_dsa_unencrypted.pem">openssl_dsa_unencrypted.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8_dsa_unencrypted.der">pkcs8_dsa_unencrypted.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8_dsa_unencrypted.pem">pkcs8_dsa_unencrypted.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md2_des1_cbc.der">pkcs8v1_dsa_md2_des1_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md2_des1_cbc.pem">pkcs8v1_dsa_md2_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md2_rc2_64_cbc.der">pkcs8v1_dsa_md2_rc2_64_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md2_rc2_64_cbc.pem">pkcs8v1_dsa_md2_rc2_64_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md5_des1_cbc.der">pkcs8v1_dsa_md5_des1_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md5_des1_cbc.pem">pkcs8v1_dsa_md5_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md5_rc2_64_cbc.der">pkcs8v1_dsa_md5_rc2_64_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_md5_rc2_64_cbc.pem">pkcs8v1_dsa_md5_rc2_64_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_des1_cbc.der">pkcs8v1_dsa_sha1_des1_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_des1_cbc.pem">pkcs8v1_dsa_sha1_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_des2_cbc.der">pkcs8v1_dsa_sha1_des2_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_des2_cbc.pem">pkcs8v1_dsa_sha1_des2_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_des3_cbc.der">pkcs8v1_dsa_sha1_des3_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_des3_cbc.pem">pkcs8v1_dsa_sha1_des3_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.der">pkcs8v1_dsa_sha1_rc2_128_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.pem">pkcs8v1_dsa_sha1_rc2_128_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.der">pkcs8v1_dsa_sha1_rc2_40_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.pem">pkcs8v1_dsa_sha1_rc2_40_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.der">pkcs8v1_dsa_sha1_rc2_64_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.pem">pkcs8v1_dsa_sha1_rc2_64_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc4_128.der">pkcs8v1_dsa_sha1_rc4_128.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc4_128.pem">pkcs8v1_dsa_sha1_rc4_128.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc4_40.der">pkcs8v1_dsa_sha1_rc4_40.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v1_dsa_sha1_rc4_40.pem">pkcs8v1_dsa_sha1_rc4_40.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_cbc.der">pkcs8v2_dsa_aes128_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_cbc.pem">pkcs8v2_dsa_aes128_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_cfb.der">pkcs8v2_dsa_aes128_cfb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_cfb.pem">pkcs8v2_dsa_aes128_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_ecb.der">pkcs8v2_dsa_aes128_ecb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_ecb.pem">pkcs8v2_dsa_aes128_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_ofb.der">pkcs8v2_dsa_aes128_ofb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes128_ofb.pem">pkcs8v2_dsa_aes128_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_cbc.der">pkcs8v2_dsa_aes192_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_cbc.pem">pkcs8v2_dsa_aes192_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_cfb.der">pkcs8v2_dsa_aes192_cfb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_cfb.pem">pkcs8v2_dsa_aes192_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_ecb.der">pkcs8v2_dsa_aes192_ecb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_ecb.pem">pkcs8v2_dsa_aes192_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_ofb.der">pkcs8v2_dsa_aes192_ofb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes192_ofb.pem">pkcs8v2_dsa_aes192_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_cbc.der">pkcs8v2_dsa_aes256_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_cbc.pem">pkcs8v2_dsa_aes256_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_cfb.der">pkcs8v2_dsa_aes256_cfb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_cfb.pem">pkcs8v2_dsa_aes256_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_ecb.der">pkcs8v2_dsa_aes256_ecb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_ecb.pem">pkcs8v2_dsa_aes256_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_ofb.der">pkcs8v2_dsa_aes256_ofb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_aes256_ofb.pem">pkcs8v2_dsa_aes256_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_blowfish_cbc.der">pkcs8v2_dsa_blowfish_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_blowfish_cbc.pem">pkcs8v2_dsa_blowfish_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_cbc.der">pkcs8v2_dsa_des1_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_cbc.pem">pkcs8v2_dsa_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_cfb.der">pkcs8v2_dsa_des1_cfb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_cfb.pem">pkcs8v2_dsa_des1_cfb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_ecb.der">pkcs8v2_dsa_des1_ecb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_ecb.pem">pkcs8v2_dsa_des1_ecb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_ofb.der">pkcs8v2_dsa_des1_ofb.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des1_ofb.pem">pkcs8v2_dsa_des1_ofb.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.der">pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.pem">pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des3_cbc.der">pkcs8v2_dsa_des3_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_des3_cbc.pem">pkcs8v2_dsa_des3_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_rc2_128_cbc.der">pkcs8v2_dsa_rc2_128_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_rc2_128_cbc.pem">pkcs8v2_dsa_rc2_128_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_rc2_40_cbc.der">pkcs8v2_dsa_rc2_40_cbc.der</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_rc2_40_cbc.pem">pkcs8v2_dsa_rc2_40_cbc.pem</a>
+   |   |   |-- <a href="./samples/dsa/pkcs8v2_dsa_rc2_64_cbc.der">pkcs8v2_dsa_rc2_64_cbc.der</a>
+   |   |   `-- <a href="./samples/dsa/pkcs8v2_dsa_rc2_64_cbc.pem">pkcs8v2_dsa_rc2_64_cbc.pem</a>
+   |   |-- <a href="./samples/dsa.html">dsa.html</a>
+   |   |-- <a href="./samples/dsa_result.html">dsa_result.html</a>
+   |   |-- <a href="./samples/keystores/">keystores</a>
+   |   |   |-- <a href="./samples/keystores/BC.BKS.ks">BC.BKS.ks</a>
+   |   |   |-- <a href="./samples/keystores/BC.PKCS12-3DES-3DES.ks">BC.PKCS12-3DES-3DES.ks</a>
+   |   |   |-- <a href="./samples/keystores/BC.PKCS12-DEF-3DES-3DES.ks">BC.PKCS12-DEF-3DES-3DES.ks</a>
+   |   |   |-- <a href="./samples/keystores/BC.PKCS12-DEF.ks">BC.PKCS12-DEF.ks</a>
+   |   |   |-- <a href="./samples/keystores/BC.PKCS12.ks">BC.PKCS12.ks</a>
+   |   |   |-- <a href="./samples/keystores/BC.UBER.ks">BC.UBER.ks</a>
+   |   |   |-- <a href="./samples/keystores/README.txt">README.txt</a>
+   |   |   |-- <a href="./samples/keystores/Sun.2pass.jks.ks">Sun.2pass.jks.ks</a>
+   |   |   |-- <a href="./samples/keystores/Sun.jks.ks">Sun.jks.ks</a>
+   |   |   |-- <a href="./samples/keystores/SunJCE.jceks.ks">SunJCE.jceks.ks</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_dsa_rsa.ks">chain-rsa_dsa_rsa.ks</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_dsa_rsa.pem">chain-rsa_dsa_rsa.pem</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_dsa_rsa.pkcs12.der">chain-rsa_dsa_rsa.pkcs12.der</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_dsa_rsa.pkcs12.pem">chain-rsa_dsa_rsa.pkcs12.pem</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_rsa_rsa.ks">chain-rsa_rsa_rsa.ks</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_rsa_rsa.pem">chain-rsa_rsa_rsa.pem</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_rsa_rsa.pkcs12.der">chain-rsa_rsa_rsa.pkcs12.der</a>
+   |   |   |-- <a href="./samples/keystores/chain-rsa_rsa_rsa.pkcs12.pem">chain-rsa_rsa_rsa.pkcs12.pem</a>
+   |   |   |-- <a href="./samples/keystores/generate.sh">generate.sh</a>
+   |   |   `-- <a href="./samples/keystores/rsa.key">rsa.key</a>
+   |   |-- <a href="./samples/pbe/">pbe</a>
+   |   |   |-- <a href="./samples/pbe/README.txt">README.txt</a>
+   |   |   |-- <a href="./samples/pbe/java/">java</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-cbc.base64">aes-128-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-cbc.raw">aes-128-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-cfb.base64">aes-128-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-cfb.raw">aes-128-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-cfb8.base64">aes-128-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-cfb8.raw">aes-128-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-ecb.base64">aes-128-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-ecb.raw">aes-128-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-ofb.base64">aes-128-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128-ofb.raw">aes-128-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128.base64">aes-128.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-128.raw">aes-128.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-cbc.base64">aes-192-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-cbc.raw">aes-192-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-cfb.base64">aes-192-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-cfb.raw">aes-192-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-cfb8.base64">aes-192-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-cfb8.raw">aes-192-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-ecb.base64">aes-192-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-ecb.raw">aes-192-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-ofb.base64">aes-192-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192-ofb.raw">aes-192-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192.base64">aes-192.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-192.raw">aes-192.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-cbc.base64">aes-256-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-cbc.raw">aes-256-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-cfb.base64">aes-256-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-cfb.raw">aes-256-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-cfb8.base64">aes-256-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-cfb8.raw">aes-256-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-ecb.base64">aes-256-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-ecb.raw">aes-256-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-ofb.base64">aes-256-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256-ofb.raw">aes-256-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256.base64">aes-256.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes-256.raw">aes-256.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-cbc.base64">aes128-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-cbc.raw">aes128-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-cfb.base64">aes128-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-cfb.raw">aes128-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-cfb8.base64">aes128-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-cfb8.raw">aes128-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-ecb.base64">aes128-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-ecb.raw">aes128-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-ofb.base64">aes128-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128-ofb.raw">aes128-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128.base64">aes128.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes128.raw">aes128.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-cbc.base64">aes192-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-cbc.raw">aes192-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-cfb.base64">aes192-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-cfb.raw">aes192-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-cfb8.base64">aes192-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-cfb8.raw">aes192-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-ecb.base64">aes192-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-ecb.raw">aes192-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-ofb.base64">aes192-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192-ofb.raw">aes192-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192.base64">aes192.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes192.raw">aes192.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-cbc.base64">aes256-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-cbc.raw">aes256-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-cfb.base64">aes256-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-cfb.raw">aes256-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-cfb8.base64">aes256-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-cfb8.raw">aes256-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-ecb.base64">aes256-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-ecb.raw">aes256-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-ofb.base64">aes256-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256-ofb.raw">aes256-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256.base64">aes256.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/aes256.raw">aes256.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-cbc.base64">bf-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-cbc.raw">bf-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-cfb.base64">bf-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-cfb.raw">bf-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-cfb8.base64">bf-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-cfb8.raw">bf-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-ecb.base64">bf-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-ecb.raw">bf-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-ofb.base64">bf-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf-ofb.raw">bf-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf.base64">bf.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/bf.raw">bf.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-cbc.base64">blowfish-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-cbc.raw">blowfish-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-cfb.base64">blowfish-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-cfb.raw">blowfish-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-cfb8.base64">blowfish-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-cfb8.raw">blowfish-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-ecb.base64">blowfish-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-ecb.raw">blowfish-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-ofb.base64">blowfish-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish-ofb.raw">blowfish-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish.base64">blowfish.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/blowfish.raw">blowfish.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-cbc.base64">camellia-128-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-cbc.raw">camellia-128-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-cfb.base64">camellia-128-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-cfb.raw">camellia-128-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-cfb8.base64">camellia-128-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-cfb8.raw">camellia-128-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-ecb.base64">camellia-128-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-ecb.raw">camellia-128-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-ofb.base64">camellia-128-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128-ofb.raw">camellia-128-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128.base64">camellia-128.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-128.raw">camellia-128.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-cbc.base64">camellia-192-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-cbc.raw">camellia-192-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-cfb.base64">camellia-192-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-cfb.raw">camellia-192-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-cfb8.base64">camellia-192-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-cfb8.raw">camellia-192-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-ecb.base64">camellia-192-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-ecb.raw">camellia-192-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-ofb.base64">camellia-192-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192-ofb.raw">camellia-192-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192.base64">camellia-192.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-192.raw">camellia-192.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-cbc.base64">camellia-256-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-cbc.raw">camellia-256-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-cfb.base64">camellia-256-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-cfb.raw">camellia-256-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-cfb8.base64">camellia-256-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-cfb8.raw">camellia-256-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-ecb.base64">camellia-256-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-ecb.raw">camellia-256-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-ofb.base64">camellia-256-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256-ofb.raw">camellia-256-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256.base64">camellia-256.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia-256.raw">camellia-256.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-cbc.base64">camellia128-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-cbc.raw">camellia128-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-cfb.base64">camellia128-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-cfb.raw">camellia128-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-cfb8.base64">camellia128-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-cfb8.raw">camellia128-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-ecb.base64">camellia128-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-ecb.raw">camellia128-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-ofb.base64">camellia128-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128-ofb.raw">camellia128-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128.base64">camellia128.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia128.raw">camellia128.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-cbc.base64">camellia192-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-cbc.raw">camellia192-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-cfb.base64">camellia192-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-cfb.raw">camellia192-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-cfb8.base64">camellia192-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-cfb8.raw">camellia192-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-ecb.base64">camellia192-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-ecb.raw">camellia192-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-ofb.base64">camellia192-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192-ofb.raw">camellia192-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192.base64">camellia192.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia192.raw">camellia192.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-cbc.base64">camellia256-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-cbc.raw">camellia256-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-cfb.base64">camellia256-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-cfb.raw">camellia256-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-cfb8.base64">camellia256-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-cfb8.raw">camellia256-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-ecb.base64">camellia256-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-ecb.raw">camellia256-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-ofb.base64">camellia256-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256-ofb.raw">camellia256-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256.base64">camellia256.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/camellia256.raw">camellia256.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-cbc.base64">cast5-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-cbc.raw">cast5-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-cfb.base64">cast5-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-cfb.raw">cast5-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-cfb8.base64">cast5-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-cfb8.raw">cast5-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-ecb.base64">cast5-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-ecb.raw">cast5-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-ofb.base64">cast5-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5-ofb.raw">cast5-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5.base64">cast5.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast5.raw">cast5.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-cbc.base64">cast6-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-cbc.raw">cast6-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-cfb.base64">cast6-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-cfb.raw">cast6-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-cfb8.base64">cast6-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-cfb8.raw">cast6-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-ecb.base64">cast6-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-ecb.raw">cast6-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-ofb.base64">cast6-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6-ofb.raw">cast6-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6.base64">cast6.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/cast6.raw">cast6.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-cbc.base64">des-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-cbc.raw">des-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-cfb.base64">des-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-cfb.raw">des-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-cfb8.base64">des-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-cfb8.raw">des-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ecb.base64">des-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ecb.raw">des-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-cbc.base64">des-ede-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-cbc.raw">des-ede-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-cfb.base64">des-ede-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-cfb.raw">des-ede-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-cfb8.base64">des-ede-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-cfb8.raw">des-ede-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-ecb.base64">des-ede-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-ecb.raw">des-ede-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-ofb.base64">des-ede-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede-ofb.raw">des-ede-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede.base64">des-ede.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede.raw">des-ede.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-cbc.base64">des-ede3-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-cbc.raw">des-ede3-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-cfb.base64">des-ede3-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-cfb.raw">des-ede3-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-cfb8.base64">des-ede3-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-cfb8.raw">des-ede3-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-ecb.base64">des-ede3-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-ecb.raw">des-ede3-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-ofb.base64">des-ede3-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3-ofb.raw">des-ede3-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3.base64">des-ede3.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ede3.raw">des-ede3.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ofb.base64">des-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des-ofb.raw">des-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des.base64">des.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des.raw">des.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-cbc.base64">des2-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-cbc.raw">des2-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-cfb.base64">des2-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-cfb.raw">des2-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-cfb8.base64">des2-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-cfb8.raw">des2-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-ecb.base64">des2-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-ecb.raw">des2-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-ofb.base64">des2-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2-ofb.raw">des2-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2.base64">des2.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des2.raw">des2.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-cbc.base64">des3-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-cbc.raw">des3-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-cfb.base64">des3-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-cfb.raw">des3-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-cfb8.base64">des3-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-cfb8.raw">des3-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-ecb.base64">des3-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-ecb.raw">des3-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-ofb.base64">des3-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3-ofb.raw">des3-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3.base64">des3.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/des3.raw">des3.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-cbc.base64">gost-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-cbc.raw">gost-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-cfb.base64">gost-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-cfb.raw">gost-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-cfb8.base64">gost-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-cfb8.raw">gost-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-ecb.base64">gost-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-ecb.raw">gost-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-ofb.base64">gost-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost-ofb.raw">gost-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost.base64">gost.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost.raw">gost.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-cbc.base64">gost28147-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-cbc.raw">gost28147-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-cfb.base64">gost28147-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-cfb.raw">gost28147-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-cfb8.base64">gost28147-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-cfb8.raw">gost28147-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-ecb.base64">gost28147-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-ecb.raw">gost28147-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-ofb.base64">gost28147-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147-ofb.raw">gost28147-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147.base64">gost28147.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/gost28147.raw">gost28147.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-cbc.base64">idea-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-cbc.raw">idea-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-cfb.base64">idea-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-cfb.raw">idea-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-cfb8.base64">idea-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-cfb8.raw">idea-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-ecb.base64">idea-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-ecb.raw">idea-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-ofb.base64">idea-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea-ofb.raw">idea-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea.base64">idea.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/idea.raw">idea.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-cbc.base64">rc2-40-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-cbc.raw">rc2-40-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-cfb.base64">rc2-40-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-cfb.raw">rc2-40-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-cfb8.base64">rc2-40-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-cfb8.raw">rc2-40-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-ecb.base64">rc2-40-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-ecb.raw">rc2-40-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-ofb.base64">rc2-40-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40-ofb.raw">rc2-40-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40.base64">rc2-40.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-40.raw">rc2-40.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-cbc.base64">rc2-64-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-cbc.raw">rc2-64-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-cfb.base64">rc2-64-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-cfb.raw">rc2-64-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-cfb8.base64">rc2-64-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-cfb8.raw">rc2-64-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-ecb.base64">rc2-64-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-ecb.raw">rc2-64-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-ofb.base64">rc2-64-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64-ofb.raw">rc2-64-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64.base64">rc2-64.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-64.raw">rc2-64.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-cbc.base64">rc2-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-cbc.raw">rc2-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-cfb.base64">rc2-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-cfb.raw">rc2-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-cfb8.base64">rc2-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-cfb8.raw">rc2-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-ecb.base64">rc2-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-ecb.raw">rc2-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-ofb.base64">rc2-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2-ofb.raw">rc2-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2.base64">rc2.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc2.raw">rc2.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cbc.base64">rc4-40-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cbc.raw">rc4-40-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cfb.base64">rc4-40-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cfb.raw">rc4-40-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cfb1.base64">rc4-40-cfb1.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cfb1.raw">rc4-40-cfb1.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cfb8.base64">rc4-40-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-cfb8.raw">rc4-40-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-ecb.base64">rc4-40-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-ecb.raw">rc4-40-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-ofb.base64">rc4-40-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40-ofb.raw">rc4-40-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40.base64">rc4-40.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-40.raw">rc4-40.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cbc.base64">rc4-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cbc.raw">rc4-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cfb.base64">rc4-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cfb.raw">rc4-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cfb1.base64">rc4-cfb1.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cfb1.raw">rc4-cfb1.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cfb8.base64">rc4-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-cfb8.raw">rc4-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-ecb.base64">rc4-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-ecb.raw">rc4-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-ofb.base64">rc4-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4-ofb.raw">rc4-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4.base64">rc4.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc4.raw">rc4.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-cbc.base64">rc5-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-cbc.raw">rc5-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-cfb.base64">rc5-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-cfb.raw">rc5-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-cfb8.base64">rc5-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-cfb8.raw">rc5-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-ecb.base64">rc5-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-ecb.raw">rc5-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-ofb.base64">rc5-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5-ofb.raw">rc5-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5.base64">rc5.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc5.raw">rc5.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-cbc.base64">rc6-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-cbc.raw">rc6-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-cfb.base64">rc6-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-cfb.raw">rc6-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-cfb8.base64">rc6-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-cfb8.raw">rc6-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-ecb.base64">rc6-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-ecb.raw">rc6-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-ofb.base64">rc6-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6-ofb.raw">rc6-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6.base64">rc6.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rc6.raw">rc6.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-cbc.base64">rijndael-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-cbc.raw">rijndael-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-cfb.base64">rijndael-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-cfb.raw">rijndael-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-cfb8.base64">rijndael-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-cfb8.raw">rijndael-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-ecb.base64">rijndael-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-ecb.raw">rijndael-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-ofb.base64">rijndael-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael-ofb.raw">rijndael-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael.base64">rijndael.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/rijndael.raw">rijndael.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-cbc.base64">seed-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-cbc.raw">seed-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-cfb.base64">seed-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-cfb.raw">seed-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-cfb8.base64">seed-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-cfb8.raw">seed-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-ecb.base64">seed-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-ecb.raw">seed-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-ofb.base64">seed-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed-ofb.raw">seed-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed.base64">seed.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/seed.raw">seed.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-cbc.base64">serpent-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-cbc.raw">serpent-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-cfb.base64">serpent-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-cfb.raw">serpent-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-cfb8.base64">serpent-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-cfb8.raw">serpent-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-ecb.base64">serpent-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-ecb.raw">serpent-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-ofb.base64">serpent-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent-ofb.raw">serpent-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent.base64">serpent.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/serpent.raw">serpent.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-cbc.base64">skipjack-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-cbc.raw">skipjack-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-cfb.base64">skipjack-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-cfb.raw">skipjack-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-cfb8.base64">skipjack-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-cfb8.raw">skipjack-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-ecb.base64">skipjack-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-ecb.raw">skipjack-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-ofb.base64">skipjack-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack-ofb.raw">skipjack-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack.base64">skipjack.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/skipjack.raw">skipjack.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-cbc.base64">tea-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-cbc.raw">tea-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-cfb.base64">tea-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-cfb.raw">tea-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-cfb8.base64">tea-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-cfb8.raw">tea-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-ecb.base64">tea-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-ecb.raw">tea-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-ofb.base64">tea-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea-ofb.raw">tea-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea.base64">tea.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/tea.raw">tea.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-cbc.base64">twofish-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-cbc.raw">twofish-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-cfb.base64">twofish-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-cfb.raw">twofish-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-cfb8.base64">twofish-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-cfb8.raw">twofish-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-ecb.base64">twofish-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-ecb.raw">twofish-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-ofb.base64">twofish-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish-ofb.raw">twofish-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish.base64">twofish.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/twofish.raw">twofish.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-cbc.base64">xtea-cbc.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-cbc.raw">xtea-cbc.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-cfb.base64">xtea-cfb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-cfb.raw">xtea-cfb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-cfb8.base64">xtea-cfb8.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-cfb8.raw">xtea-cfb8.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-ecb.base64">xtea-ecb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-ecb.raw">xtea-ecb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-ofb.base64">xtea-ofb.base64</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea-ofb.raw">xtea-ofb.raw</a>
+   |   |   |   |-- <a href="./samples/pbe/java/xtea.base64">xtea.base64</a>
+   |   |   |   `-- <a href="./samples/pbe/java/xtea.raw">xtea.raw</a>
+   |   |   `-- <a href="./samples/pbe/openssl/">openssl</a>
+   |   |       |-- <a href="./samples/pbe/openssl/README.txt">README.txt</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cbc.base64">aes-128-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cbc.raw">aes-128-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cfb.base64">aes-128-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cfb.raw">aes-128-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cfb1.base64">aes-128-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cfb1.raw">aes-128-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cfb8.base64">aes-128-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-cfb8.raw">aes-128-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-ecb.base64">aes-128-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-ecb.raw">aes-128-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-ofb.base64">aes-128-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-128-ofb.raw">aes-128-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cbc.base64">aes-192-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cbc.raw">aes-192-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cfb.base64">aes-192-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cfb.raw">aes-192-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cfb1.base64">aes-192-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cfb1.raw">aes-192-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cfb8.base64">aes-192-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-cfb8.raw">aes-192-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-ecb.base64">aes-192-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-ecb.raw">aes-192-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-ofb.base64">aes-192-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-192-ofb.raw">aes-192-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cbc.base64">aes-256-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cbc.raw">aes-256-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cfb.base64">aes-256-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cfb.raw">aes-256-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cfb1.base64">aes-256-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cfb1.raw">aes-256-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cfb8.base64">aes-256-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-cfb8.raw">aes-256-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-ecb.base64">aes-256-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-ecb.raw">aes-256-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-ofb.base64">aes-256-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes-256-ofb.raw">aes-256-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes128.base64">aes128.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes128.raw">aes128.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes192.base64">aes192.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes192.raw">aes192.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes256.base64">aes256.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/aes256.raw">aes256.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-cbc.base64">bf-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-cbc.raw">bf-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-cfb.base64">bf-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-cfb.raw">bf-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-ecb.base64">bf-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-ecb.raw">bf-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-ofb.base64">bf-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf-ofb.raw">bf-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf.base64">bf.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/bf.raw">bf.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/blowfish.base64">blowfish.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/blowfish.raw">blowfish.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cbc.base64">camellia-128-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cbc.raw">camellia-128-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cfb.base64">camellia-128-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cfb.raw">camellia-128-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cfb1.base64">camellia-128-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cfb1.raw">camellia-128-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cfb8.base64">camellia-128-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-cfb8.raw">camellia-128-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-ecb.base64">camellia-128-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-ecb.raw">camellia-128-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-ofb.base64">camellia-128-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-128-ofb.raw">camellia-128-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cbc.base64">camellia-192-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cbc.raw">camellia-192-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cfb.base64">camellia-192-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cfb.raw">camellia-192-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cfb1.base64">camellia-192-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cfb1.raw">camellia-192-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cfb8.base64">camellia-192-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-cfb8.raw">camellia-192-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-ecb.base64">camellia-192-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-ecb.raw">camellia-192-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-ofb.base64">camellia-192-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-192-ofb.raw">camellia-192-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cbc.base64">camellia-256-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cbc.raw">camellia-256-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cfb.base64">camellia-256-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cfb.raw">camellia-256-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cfb1.base64">camellia-256-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cfb1.raw">camellia-256-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cfb8.base64">camellia-256-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-cfb8.raw">camellia-256-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-ecb.base64">camellia-256-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-ecb.raw">camellia-256-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-ofb.base64">camellia-256-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia-256-ofb.raw">camellia-256-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia128.base64">camellia128.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia128.raw">camellia128.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia192.base64">camellia192.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia192.raw">camellia192.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia256.base64">camellia256.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/camellia256.raw">camellia256.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast-cbc.base64">cast-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast-cbc.raw">cast-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast.base64">cast.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast.raw">cast.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-cbc.base64">cast5-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-cbc.raw">cast5-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-cfb.base64">cast5-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-cfb.raw">cast5-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-ecb.base64">cast5-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-ecb.raw">cast5-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-ofb.base64">cast5-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/cast5-ofb.raw">cast5-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cbc.base64">des-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cbc.raw">des-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cfb.base64">des-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cfb.raw">des-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cfb1.base64">des-cfb1.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cfb1.raw">des-cfb1.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cfb8.base64">des-cfb8.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-cfb8.raw">des-cfb8.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ecb.base64">des-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ecb.raw">des-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede-cbc.base64">des-ede-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede-cbc.raw">des-ede-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede-cfb.base64">des-ede-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede-cfb.raw">des-ede-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede-ofb.base64">des-ede-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede-ofb.raw">des-ede-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede.base64">des-ede.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede.raw">des-ede.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3-cbc.base64">des-ede3-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3-cbc.raw">des-ede3-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3-cfb.base64">des-ede3-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3-cfb.raw">des-ede3-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3-ofb.base64">des-ede3-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3-ofb.raw">des-ede3-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3.base64">des-ede3.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ede3.raw">des-ede3.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ofb.base64">des-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des-ofb.raw">des-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des.base64">des.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des.raw">des.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des3.base64">des3.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/des3.raw">des3.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-cbc.base64">idea-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-cbc.raw">idea-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-cfb.base64">idea-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-cfb.raw">idea-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-ecb.base64">idea-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-ecb.raw">idea-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-ofb.base64">idea-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea-ofb.raw">idea-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea.base64">idea.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/idea.raw">idea.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-40-cbc.base64">rc2-40-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-40-cbc.raw">rc2-40-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-64-cbc.base64">rc2-64-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-64-cbc.raw">rc2-64-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-cbc.base64">rc2-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-cbc.raw">rc2-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-cfb.base64">rc2-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-cfb.raw">rc2-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-ecb.base64">rc2-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-ecb.raw">rc2-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-ofb.base64">rc2-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2-ofb.raw">rc2-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2.base64">rc2.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc2.raw">rc2.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc4-40.base64">rc4-40.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc4-40.raw">rc4-40.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc4.base64">rc4.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc4.raw">rc4.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-cbc.base64">rc5-cbc.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-cbc.raw">rc5-cbc.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-cfb.base64">rc5-cfb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-cfb.raw">rc5-cfb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-ecb.base64">rc5-ecb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-ecb.raw">rc5-ecb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-ofb.base64">rc5-ofb.base64</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5-ofb.raw">rc5-ofb.raw</a>
+   |   |       |-- <a href="./samples/pbe/openssl/rc5.base64">rc5.base64</a>
+   |   |       `-- <a href="./samples/pbe/openssl/rc5.raw">rc5.raw</a>
+   |   |-- <a href="./samples/pbe.tests">pbe.tests</a>
+   |   |-- <a href="./samples/pkcs12/">pkcs12</a>
+   |   |   |-- <a href="./samples/pkcs12/pkcs12_client_cert.p12">pkcs12_client_cert.p12</a>
+   |   |   `-- <a href="./samples/pkcs12/pkcs12_client_cert.pem">pkcs12_client_cert.pem</a>
+   |   |-- <a href="./samples/rsa/">rsa</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes128_cbc.pem">openssl_rsa_aes128_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes128_cfb.pem">openssl_rsa_aes128_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes128_ecb.pem">openssl_rsa_aes128_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes128_ofb.pem">openssl_rsa_aes128_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes192_cbc.pem">openssl_rsa_aes192_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes192_cfb.pem">openssl_rsa_aes192_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes192_ecb.pem">openssl_rsa_aes192_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes192_ofb.pem">openssl_rsa_aes192_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes256_cbc.pem">openssl_rsa_aes256_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes256_cfb.pem">openssl_rsa_aes256_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes256_ecb.pem">openssl_rsa_aes256_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_aes256_ofb.pem">openssl_rsa_aes256_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_blowfish_cbc.pem">openssl_rsa_blowfish_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_blowfish_cfb.pem">openssl_rsa_blowfish_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_blowfish_ecb.pem">openssl_rsa_blowfish_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_blowfish_ofb.pem">openssl_rsa_blowfish_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des1_cbc.pem">openssl_rsa_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des1_cfb.pem">openssl_rsa_des1_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des1_ecb.pem">openssl_rsa_des1_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des1_ofb.pem">openssl_rsa_des1_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des2_cbc.pem">openssl_rsa_des2_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des2_cfb.pem">openssl_rsa_des2_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des2_ecb.pem">openssl_rsa_des2_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des2_ofb.pem">openssl_rsa_des2_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des3_cbc.pem">openssl_rsa_des3_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des3_cfb.pem">openssl_rsa_des3_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des3_ecb.pem">openssl_rsa_des3_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_des3_ofb.pem">openssl_rsa_des3_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_rc2_128_cbc.pem">openssl_rsa_rc2_128_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_rc2_128_cfb.pem">openssl_rsa_rc2_128_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_rc2_128_ecb.pem">openssl_rsa_rc2_128_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_rc2_128_ofb.pem">openssl_rsa_rc2_128_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_rc2_40.pem">openssl_rsa_rc2_40.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_rc2_64.pem">openssl_rsa_rc2_64.pem</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_unencrypted.der">openssl_rsa_unencrypted.der</a>
+   |   |   |-- <a href="./samples/rsa/openssl_rsa_unencrypted.pem">openssl_rsa_unencrypted.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8_rsa_unencrypted.der">pkcs8_rsa_unencrypted.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8_rsa_unencrypted.pem">pkcs8_rsa_unencrypted.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md2_des1.der">pkcs8v1_rsa_md2_des1.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md2_des1.pem">pkcs8v1_rsa_md2_des1.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md2_rc2_64.der">pkcs8v1_rsa_md2_rc2_64.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md2_rc2_64.pem">pkcs8v1_rsa_md2_rc2_64.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md5_des1.der">pkcs8v1_rsa_md5_des1.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md5_des1.pem">pkcs8v1_rsa_md5_des1.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md5_rc2_64.der">pkcs8v1_rsa_md5_rc2_64.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_md5_rc2_64.pem">pkcs8v1_rsa_md5_rc2_64.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_des1.der">pkcs8v1_rsa_sha1_des1.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_des1.pem">pkcs8v1_rsa_sha1_des1.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_des2.der">pkcs8v1_rsa_sha1_des2.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_des2.pem">pkcs8v1_rsa_sha1_des2.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_des3.der">pkcs8v1_rsa_sha1_des3.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_des3.pem">pkcs8v1_rsa_sha1_des3.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc2_128.der">pkcs8v1_rsa_sha1_rc2_128.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc2_128.pem">pkcs8v1_rsa_sha1_rc2_128.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc2_40.der">pkcs8v1_rsa_sha1_rc2_40.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc2_40.pem">pkcs8v1_rsa_sha1_rc2_40.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc2_64.der">pkcs8v1_rsa_sha1_rc2_64.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc2_64.pem">pkcs8v1_rsa_sha1_rc2_64.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc4_128.der">pkcs8v1_rsa_sha1_rc4_128.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc4_128.pem">pkcs8v1_rsa_sha1_rc4_128.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc4_40.der">pkcs8v1_rsa_sha1_rc4_40.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v1_rsa_sha1_rc4_40.pem">pkcs8v1_rsa_sha1_rc4_40.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_cbc.der">pkcs8v2_rsa_aes128_cbc.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_cbc.pem">pkcs8v2_rsa_aes128_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_cfb.der">pkcs8v2_rsa_aes128_cfb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_cfb.pem">pkcs8v2_rsa_aes128_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_ecb.der">pkcs8v2_rsa_aes128_ecb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_ecb.pem">pkcs8v2_rsa_aes128_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_ofb.der">pkcs8v2_rsa_aes128_ofb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes128_ofb.pem">pkcs8v2_rsa_aes128_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_cbc.der">pkcs8v2_rsa_aes192_cbc.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_cbc.pem">pkcs8v2_rsa_aes192_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_cfb.der">pkcs8v2_rsa_aes192_cfb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_cfb.pem">pkcs8v2_rsa_aes192_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_ecb.der">pkcs8v2_rsa_aes192_ecb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_ecb.pem">pkcs8v2_rsa_aes192_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_ofb.der">pkcs8v2_rsa_aes192_ofb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes192_ofb.pem">pkcs8v2_rsa_aes192_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_cbc.der">pkcs8v2_rsa_aes256_cbc.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_cbc.pem">pkcs8v2_rsa_aes256_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_cfb.der">pkcs8v2_rsa_aes256_cfb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_cfb.pem">pkcs8v2_rsa_aes256_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_ecb.der">pkcs8v2_rsa_aes256_ecb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_ecb.pem">pkcs8v2_rsa_aes256_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_ofb.der">pkcs8v2_rsa_aes256_ofb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_aes256_ofb.pem">pkcs8v2_rsa_aes256_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_blowfish_cbc.der">pkcs8v2_rsa_blowfish_cbc.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_blowfish_cbc.pem">pkcs8v2_rsa_blowfish_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_cbc.der">pkcs8v2_rsa_des1_cbc.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_cbc.pem">pkcs8v2_rsa_des1_cbc.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_cfb.der">pkcs8v2_rsa_des1_cfb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_cfb.pem">pkcs8v2_rsa_des1_cfb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_ecb.der">pkcs8v2_rsa_des1_ecb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_ecb.pem">pkcs8v2_rsa_des1_ecb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_ofb.der">pkcs8v2_rsa_des1_ofb.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des1_ofb.pem">pkcs8v2_rsa_des1_ofb.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.der">pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.pem">pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des3.der">pkcs8v2_rsa_des3.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_des3.pem">pkcs8v2_rsa_des3.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_rc2_128.der">pkcs8v2_rsa_rc2_128.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_rc2_128.pem">pkcs8v2_rsa_rc2_128.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_rc2_40.der">pkcs8v2_rsa_rc2_40.der</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_rc2_40.pem">pkcs8v2_rsa_rc2_40.pem</a>
+   |   |   |-- <a href="./samples/rsa/pkcs8v2_rsa_rc2_64.der">pkcs8v2_rsa_rc2_64.der</a>
+   |   |   `-- <a href="./samples/rsa/pkcs8v2_rsa_rc2_64.pem">pkcs8v2_rsa_rc2_64.pem</a>
+   |   |-- <a href="./samples/rsa.html">rsa.html</a>
+   |   |-- <a href="./samples/rsa_result.html">rsa_result.html</a>
+   |   `-- <a href="./samples/x509/">x509</a>
+   |       |-- <a href="./samples/x509/certificate.der">certificate.der</a>
+   |       |-- <a href="./samples/x509/certificate.pem">certificate.pem</a>
+   |       |-- <a href="./samples/x509/certificate_chain.pem">certificate_chain.pem</a>
+   |       |-- <a href="./samples/x509/certificate_root_ca.der">certificate_root_ca.der</a>
+   |       |-- <a href="./samples/x509/certificate_root_ca.pem">certificate_root_ca.pem</a>
+   |       |-- <a href="./samples/x509/oscp.pem">oscp.pem</a>
+   |       |-- <a href="./samples/x509/two-crls.pem">two-crls.pem</a>
+   |       |-- <a href="./samples/x509/x509_foo.pem">x509_foo.pem</a>
+   |       |-- <a href="./samples/x509/x509_foo_bar.pem">x509_foo_bar.pem</a>
+   |       |-- <a href="./samples/x509/x509_foo_bar_hanako.pem">x509_foo_bar_hanako.pem</a>
+   |       |-- <a href="./samples/x509/x509_hanako.pem">x509_hanako.pem</a>
+   |       |-- <a href="./samples/x509/x509_no_cns_foo.pem">x509_no_cns_foo.pem</a>
+   |       |-- <a href="./samples/x509/x509_three_cns_foo_bar_hanako.pem">x509_three_cns_foo_bar_hanako.pem</a>
+   |       |-- <a href="./samples/x509/x509_wild_co_jp.pem">x509_wild_co_jp.pem</a>
+   |       |-- <a href="./samples/x509/x509_wild_foo.pem">x509_wild_foo.pem</a>
+   |       `-- <a href="./samples/x509/x509_wild_foo_bar_hanako.pem">x509_wild_foo_bar_hanako.pem</a>
+   |-- <a href="./source.html">source.html</a>
+   |-- <a href="./src/">src</a>
+   |   |-- <a href="./src/java/">java</a>
+   |   |   `-- <a href="./src/java/org/">org</a>
+   |   |       `-- <a href="./src/java/org/apache/">apache</a>
+   |   |           `-- <a href="./src/java/org/apache/commons/">commons</a>
+   |   |               |-- <a href="./src/java/org/apache/commons/httpclient/">httpclient</a>
+   |   |               |   `-- <a href="./src/java/org/apache/commons/httpclient/contrib/">contrib</a>
+   |   |               |       `-- <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/">ssl</a>
+   |   |               |           |-- <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java">AuthSSLProtocolSocketFactory.java</a>
+   |   |               |           |-- <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java">EasySSLProtocolSocketFactory.java</a>
+   |   |               |           |-- <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/StrictSSLProtocolSocketFactory.java">StrictSSLProtocolSocketFactory.java</a>
+   |   |               |           `-- <a href="./src/java/org/apache/commons/httpclient/contrib/ssl/TrustSSLProtocolSocketFactory.java">TrustSSLProtocolSocketFactory.java</a>
+   |   |               `-- <a href="./src/java/org/apache/commons/ssl/">ssl</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/ASN1Structure.java">ASN1Structure.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/ASN1Util.java">ASN1Util.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Base64.java">Base64.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Base64InputStream.java">Base64InputStream.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Base64OutputStream.java">Base64OutputStream.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/CRLSocket.java">CRLSocket.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/CRLUtil.java">CRLUtil.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Certificates.java">Certificates.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/ComboInputStream.java">ComboInputStream.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/DerivedKey.java">DerivedKey.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/HostPort.java">HostPort.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/HostnameVerifier.java">HostnameVerifier.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/HttpSecureProtocol.java">HttpSecureProtocol.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Java13.java">Java13.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java">Java13KeyManagerWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java">Java13TrustManagerWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Java14.java">Java14.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java">Java14KeyManagerWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java">Java14TrustManagerWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/JavaImpl.java">JavaImpl.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/KeyMaterial.java">KeyMaterial.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/KeyStoreBuilder.java">KeyStoreBuilder.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/LDAPSocket.java">LDAPSocket.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/LogHelper.java">LogHelper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/LogWrapper.java">LogWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/OpenSSL.java">OpenSSL.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/PBETestCreate.java">PBETestCreate.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/PEMItem.java">PEMItem.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/PEMUtil.java">PEMUtil.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/PKCS8Key.java">PKCS8Key.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Ping.java">Ping.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java">ProbablyBadPasswordException.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java">ProbablyNotPKCS8Exception.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java">RMISocketFactoryImpl.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSL.java">SSL.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLClient.java">SSLClient.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLEchoServer.java">SSLEchoServer.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLProxyServer.java">SSLProxyServer.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLServer.java">SSLServer.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java">SSLServerSocketWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLSocketWrapper.java">SSLSocketWrapper.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/SSLWrapperFactory.java">SSLWrapperFactory.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/TomcatServerXML.java">TomcatServerXML.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/TrustChain.java">TrustChain.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/TrustMaterial.java">TrustMaterial.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Util.java">Util.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/Version.java">Version.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java">X509CertificateChainBuilder.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/asn1/">asn1</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Choice.java">ASN1Choice.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Encodable.java">ASN1Encodable.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1EncodableVector.java">ASN1EncodableVector.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Generator.java">ASN1Generator.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1InputStream.java">ASN1InputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Null.java">ASN1Null.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Object.java">ASN1Object.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1ObjectParser.java">ASN1ObjectParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1OctetString.java">ASN1OctetString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1OctetStringParser.java">ASN1OctetStringParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1OutputStream.java">ASN1OutputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Sequence.java">ASN1Sequence.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1SequenceParser.java">ASN1SequenceParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1Set.java">ASN1Set.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1SetParser.java">ASN1SetParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1StreamParser.java">ASN1StreamParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1TaggedObject.java">ASN1TaggedObject.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ASN1TaggedObjectParser.java">ASN1TaggedObjectParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERConstructedOctetString.java">BERConstructedOctetString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERConstructedSequence.java">BERConstructedSequence.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERGenerator.java">BERGenerator.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERInputStream.java">BERInputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERNull.java">BERNull.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BEROctetStringGenerator.java">BEROctetStringGenerator.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BEROctetStringParser.java">BEROctetStringParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BEROutputStream.java">BEROutputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERSequence.java">BERSequence.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERSequenceGenerator.java">BERSequenceGenerator.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERSequenceParser.java">BERSequenceParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERSet.java">BERSet.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERSetParser.java">BERSetParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERTaggedObject.java">BERTaggedObject.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/BERTaggedObjectParser.java">BERTaggedObjectParser.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/ConstructedOctetStream.java">ConstructedOctetStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERApplicationSpecific.java">DERApplicationSpecific.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERBMPString.java">DERBMPString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERBitString.java">DERBitString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERBoolean.java">DERBoolean.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERConstructedSequence.java">DERConstructedSequence.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERConstructedSet.java">DERConstructedSet.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DEREncodable.java">DEREncodable.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DEREncodableVector.java">DEREncodableVector.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DEREnumerated.java">DEREnumerated.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERGeneralString.java">DERGeneralString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERGeneralizedTime.java">DERGeneralizedTime.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERGenerator.java">DERGenerator.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERIA5String.java">DERIA5String.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERInputStream.java">DERInputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERInteger.java">DERInteger.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERNull.java">DERNull.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERNumericString.java">DERNumericString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERObject.java">DERObject.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERObjectIdentifier.java">DERObjectIdentifier.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DEROctetString.java">DEROctetString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DEROutputStream.java">DEROutputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERPrintableString.java">DERPrintableString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERSequence.java">DERSequence.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERSequenceGenerator.java">DERSequenceGenerator.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERSet.java">DERSet.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERString.java">DERString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERT61String.java">DERT61String.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERTaggedObject.java">DERTaggedObject.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERTags.java">DERTags.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERUTCTime.java">DERUTCTime.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERUTF8String.java">DERUTF8String.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERUniversalString.java">DERUniversalString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERUnknownTag.java">DERUnknownTag.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DERVisibleString.java">DERVisibleString.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/DefiniteLengthInputStream.java">DefiniteLengthInputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/IndefiniteLengthInputStream.java">IndefiniteLengthInputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/LimitedInputStream.java">LimitedInputStream.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/asn1/OIDTokenizer.java">OIDTokenizer.java</a>
+   |   |                   |   `-- <a href="./src/java/org/apache/commons/ssl/asn1/Strings.java">Strings.java</a>
+   |   |                   |-- <a href="./src/java/org/apache/commons/ssl/rmi/">rmi</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/rmi/DateRMI.java">DateRMI.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/rmi/IntegerRMI.java">IntegerRMI.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/rmi/RemoteDate.java">RemoteDate.java</a>
+   |   |                   |   |-- <a href="./src/java/org/apache/commons/ssl/rmi/RemoteInteger.java">RemoteInteger.java</a>
+   |   |                   |   `-- <a href="./src/java/org/apache/commons/ssl/rmi/Test.java">Test.java</a>
+   |   |                   `-- <a href="./src/java/org/apache/commons/ssl/util/">util</a>
+   |   |                       |-- <a href="./src/java/org/apache/commons/ssl/util/ByteArrayReadLine.java">ByteArrayReadLine.java</a>
+   |   |                       |-- <a href="./src/java/org/apache/commons/ssl/util/Hex.java">Hex.java</a>
+   |   |                       |-- <a href="./src/java/org/apache/commons/ssl/util/PublicKeyDeriver.java">PublicKeyDeriver.java</a>
+   |   |                       |-- <a href="./src/java/org/apache/commons/ssl/util/ReadLine.java">ReadLine.java</a>
+   |   |                       `-- <a href="./src/java/org/apache/commons/ssl/util/UTF8.java">UTF8.java</a>
+   |   `-- <a href="./src/test/">test</a>
+   |       `-- <a href="./src/test/org/">org</a>
+   |           `-- <a href="./src/test/org/apache/">apache</a>
+   |               `-- <a href="./src/test/org/apache/commons/">commons</a>
+   |                   `-- <a href="./src/test/org/apache/commons/ssl/">ssl</a>
+   |                       |-- <a href="./src/test/org/apache/commons/ssl/TestBase64.java">TestBase64.java</a>
+   |                       |-- <a href="./src/test/org/apache/commons/ssl/TestKeyMaterial.java">TestKeyMaterial.java</a>
+   |                       |-- <a href="./src/test/org/apache/commons/ssl/TestOpenSSL.java">TestOpenSSL.java</a>
+   |                       `-- <a href="./src/test/org/apache/commons/ssl/TestPKCS8Key.java">TestPKCS8Key.java</a>
+   `-- <a href="./version.txt">version.txt</a>
+		</pre>
+		<p>
 
-	 tree v1.5.1 (c) 1996 - 2007 by Steve Baker and Thomas Moore 
-	 HTML output hacked and copyleft (c) 1998 by Francesc Rocher 
-	 Charsets / OS/2 support (c) 2001 by Kyosuke Tokoro
-</pre>
+40 directories, 1082 files
+		<br><br>
+		</p>
+		<hr>
+		<p class="VERSION">
+ tree v1.5.2.2 (c) 1996 - 2009 by Steve Baker and Thomas Moore <br>
+ HTML output hacked and copyleft (c) 1998 by Francesc Rocher <br>
+ Charsets / OS/2 support (c) 2001 by Kyosuke Tokoro
+		</p>
diff --git a/docs/utilities.html b/docs/utilities.html
index d4e3134..76ec47c 100644
--- a/docs/utilities.html
+++ b/docs/utilities.html
@@ -42,8 +42,8 @@ certificate even if your client certificate is bad (so even though the SSL
 handshake fails).  And unlike "openssl s_client", this utility can bind
 against any IP address available.
 
-Usage:  java -jar not-yet-commons-ssl-0.3.9.jar [options]
-Version 0.3.9      compiled=[PST:2007-11-14/14:42:18.000]
+Usage:  java -jar not-yet-commons-ssl-0.3.13.jar [options]
+Version 0.3.13      compiled=[PST:2014-05-08/14:42:18.000]
 Options:   (*=required)
 *  -t  --target           [hostname[:port]]              default port=443
    -b  --bind             [hostname[:port]]              default port=0 "ANY"
@@ -69,7 +69,7 @@ available, instead of requiring the password to be specified as a command-line a
 <p>org.apache.commons.ssl.KeyStoreBuilder is able to convert OpenSSL style public/private keys into
 Java KeyStore files.  It can also convert Java Keystore files into the PEM format that Apache likes.</p>
 
-<p><code>java -cp not-yet-commons-ssl-0.3.9.jar org.apache.commons.ssl.KeyStoreBuilder</code></p>
+<p><code>java -cp not-yet-commons-ssl-0.3.13.jar org.apache.commons.ssl.KeyStoreBuilder</code></p>
 
 <pre style="border: 1px solid red; padding: 10px; float: left;"><u><b>KeyStoreBuilder converts PKCS12 and PKCS8 to Java "Keystore"</b></u>
 
diff --git a/samples/ca/CA.sh b/samples/ca/CA.sh
new file mode 100755
index 0000000..22e9df6
--- /dev/null
+++ b/samples/ca/CA.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+
+echo
+echo "WARNING:  This script creates fake test SSL certificates that expire after 2038."
+echo "          Because of date/time issues on 32 bit unix with dates after 2038, this"
+echo "          script can only be run on 64 bit unix machines."
+echo
+
+export DAYS=14610 # 40 years
+export ROOT_SUBJ="/1.2.840.113549.1.9.1=juliusdavies at gmail.com/CN=root/OU=not-yet-commons-ssl/O=juliusdavies.ca/L=Victoria/ST=BC/C=CA";
+export  RSA_SUBJ="/1.2.840.113549.1.9.1=juliusdavies at gmail.com/CN=rsa-intermediate/OU=not-yet-commons-ssl/O=juliusdavies.ca/L=Victoria/ST=BC/C=CA";
+export  DSA_SUBJ="/1.2.840.113549.1.9.1=juliusdavies at gmail.com/CN=dsa-intermediate/OU=not-yet-commons-ssl/O=juliusdavies.ca/L=Victoria/ST=BC/C=CA";
+export TEST_SUBJ="/1.2.840.113549.1.9.1=juliusdavies at gmail.com/CN=test/OU=not-yet-commons-ssl/O=juliusdavies.ca/L=Victoria/ST=BC/C=CA";
+
+export CA=root
+sed s/demoCA/$CA/ openssl.cnf > $CA.cnf
+export PRIV=$CA/private
+export ROOT_PRIV=$PRIV
+mkdir -p       $PRIV
+mkdir -p       $CA/newcerts
+touch          $CA/index.txt
+if [ ! -f "$CA/serial" ]; then
+  date +%Y%m%d > $CA/serial
+fi
+echo
+echo "Attempting to make $CA/cacert.pem"
+openssl req -newkey rsa:2048 -days $DAYS -nodes -subj $ROOT_SUBJ -keyout $PRIV/cakey.pem -out $CA/careq.pem
+openssl ca -config $CA.cnf -create_serial -out $CA/cacert.pem -days $DAYS -batch -keyfile $PRIV/cakey.pem -selfsign -extensions v3_ca -infiles $CA/careq.pem
+
+
+export CA=rsa-intermediate
+sed s/demoCA/$CA/ openssl.cnf > $CA.cnf
+export PRIV=$CA/private
+mkdir -p       $PRIV
+mkdir -p       $CA/newcerts
+touch          $CA/index.txt
+if [ ! -f "$CA/serial" ]; then
+  date +%Y%m%d > $CA/serial
+fi
+echo
+echo "Attempting to make $CA/cacert.pem"
+openssl req -newkey rsa:2048 -days $DAYS -nodes -subj $RSA_SUBJ -keyout $PRIV/cakey.pem -out $CA/careq.pem
+openssl ca -config root.cnf -create_serial -out $CA/cacert.pem -days $DAYS -batch -keyfile $ROOT_PRIV/cakey.pem -extensions v3_ca -infiles $CA/careq.pem
+
+
+export CA=dsa-intermediate
+sed s/demoCA/$CA/ openssl.cnf > $CA.cnf
+export PRIV=$CA/private
+mkdir -p       $PRIV
+mkdir -p       $CA/newcerts
+touch          $CA/index.txt
+if [ ! -f "$CA/serial" ]; then
+  date +%Y%m%d > $CA/serial
+fi
+echo
+echo "Attempting to make $CA/cacert.pem"
+openssl dsaparam -genkey 2048 -out $CA/dsa.params
+openssl req -newkey dsa:$CA/dsa.params -days $DAYS -nodes -subj $DSA_SUBJ -keyout $PRIV/cakey.pem -out $CA/careq.pem
+openssl ca -config root.cnf -create_serial -out $CA/cacert.pem -days $DAYS -batch -keyfile $ROOT_PRIV/cakey.pem -extensions v3_ca -infiles $CA/careq.pem
+
+
+export CA=dsa-intermediate
+export PRIV=$CA/private
+echo
+echo "Attempting to make test-dsa-cert.pem"
+openssl req -new -key rsa.key -days $DAYS -subj $TEST_SUBJ -out testreq.pem
+openssl ca -config dsa-intermediate.cnf -create_serial -out test-dsa-cert.pem -days $DAYS -batch -keyfile $PRIV/cakey.pem -infiles testreq.pem
+
+export CA=rsa-intermediate
+export PRIV=$CA/private
+echo
+echo "Attempting to make test-rsa-cert.pem"
+openssl ca -config rsa-intermediate.cnf -create_serial -out test-rsa-cert.pem -days $DAYS -batch -keyfile $PRIV/cakey.pem -infiles testreq.pem
+
+cat test-rsa-cert.pem rsa-intermediate/cacert.pem root/cacert.pem > test-rsa-chain.pem
+cat test-dsa-cert.pem dsa-intermediate/cacert.pem root/cacert.pem > test-dsa-chain.pem
diff --git a/samples/ca/clean.sh b/samples/ca/clean.sh
new file mode 100755
index 0000000..e190163
--- /dev/null
+++ b/samples/ca/clean.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+find -iname \*.pem  -exec rm {} \;
+find -iname \*.txt\*  -exec rm {} \;
+find -iname \*serial\*  -exec rm {} \;
+rm -f root.cnf rsa-intermediate.cnf dsa-intermediate.cnf dsa-intermediate/dsa.params
diff --git a/samples/ca/dsa-intermediate/cacert.pem b/samples/ca/dsa-intermediate/cacert.pem
new file mode 100644
index 0000000..5431c90
--- /dev/null
+++ b/samples/ca/dsa-intermediate/cacert.pem
@@ -0,0 +1,137 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462055 (0x20090527)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=dsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    7a:a9:65:fb:76:ba:be:f3:fa:94:59:52:ed:4e:fc:
+                    e4:70:5e:8f:7c:14:e7:73:d6:d2:36:6b:62:d2:56:
+                    c9:6e:7a:91:63:72:4e:a9:ce:2e:eb:38:5e:c4:72:
+                    f6:2c:52:aa:51:f4:ce:3b:28:55:39:c3:ad:5d:52:
+                    fa:ac:0c:32:48:fc:00:9f:c3:d9:75:09:8d:82:e0:
+                    cb:07:65:29:25:7a:34:2e:bb:a0:2d:30:91:59:0e:
+                    ce:82:fb:2d:ad:a5:b2:b9:2b:ec:6b:b1:04:07:0c:
+                    52:16:7d:6c:0c:b2:64:c7:c6:cb:ab:18:ab:a6:fa:
+                    3e:31:f3:8f:49:75:33:69:d3:2a:2a:e7:2c:38:b5:
+                    d6:7d:33:94:ba:a6:3e:2f:e5:3b:cc:4a:27:d1:59:
+                    f3:9c:71:b1:46:64:3f:28:f1:33:d1:bc:c2:8b:47:
+                    92:2d:c6:1f:fb:23:34:56:f1:6e:18:8e:7c:0b:75:
+                    42:8a:bb:92:44:04:58:41:d1:9b:6e:d6:14:98:94:
+                    3d:77:8d:93:d3:1f:e9:7b:a7:71:94:10:ee:e9:d3:
+                    5a:4a:b8:91:61:35:4c:00:76:f2:b2:3a:bd:9f:42:
+                    f9:f0:8e:da:bd:8c:60:fd:7d:65:85:98:c5:7d:42:
+                    b9:27:de:09:0a:1c:85:a7:63:e5:71:3c:ab:78:de:
+                    cf
+                P:   
+                    00:8f:5a:80:34:53:e1:52:68:8c:cf:9b:d5:7a:01:
+                    60:57:63:f9:f8:01:55:9e:55:17:7f:f4:cc:cd:d7:
+                    fb:f7:1e:36:00:1c:ae:5c:70:e8:1b:33:ef:b8:8d:
+                    aa:69:2a:66:f0:48:fd:bb:25:82:eb:56:be:ac:ca:
+                    49:6e:7f:17:fd:3b:61:57:a7:14:c1:eb:99:5d:6b:
+                    82:03:db:1c:18:2a:25:05:19:ec:34:b8:c3:1b:2c:
+                    69:89:37:7b:85:9b:c0:a9:39:84:43:f1:60:0b:91:
+                    50:e0:b5:93:3c:ad:1c:b8:33:4e:9b:00:ed:cd:60:
+                    59:9b:57:04:7b:c0:fb:2d:49:45:e3:ce:c0:8a:aa:
+                    4d:07:3a:43:a3:3d:06:70:66:fc:9f:b2:8f:d6:c5:
+                    1f:a5:7b:00:36:a9:42:5e:50:db:38:34:8c:4a:c6:
+                    f6:3a:58:9a:a6:57:93:f7:4e:55:8b:46:f0:b0:1b:
+                    9c:a0:cb:fc:57:91:be:6d:47:56:a9:d1:46:cd:43:
+                    7b:ff:24:96:0a:dd:d7:d8:b7:58:8e:6a:a1:eb:2a:
+                    ba:40:0a:f6:d1:53:7c:84:06:fc:14:1c:d5:33:79:
+                    88:bb:4f:fa:b5:87:35:61:0d:b0:7b:07:bb:74:7c:
+                    30:a7:a3:60:7d:76:a6:d1:46:2b:84:a2:9a:28:61:
+                    f2:89
+                Q:   
+                    00:bf:87:b6:dd:a6:62:0f:88:a2:44:a5:99:ac:b9:
+                    12:82:05:7b:2e:af
+                G:   
+                    00:86:37:bd:1d:60:12:25:f5:01:7f:7e:e0:e7:de:
+                    26:f4:3d:d4:75:fe:91:41:41:b3:c6:70:7f:71:c6:
+                    5e:4e:c1:0f:3e:cc:be:9c:0b:df:b4:8f:6e:2a:0f:
+                    90:5b:20:14:75:c7:31:13:e2:d8:73:73:76:b6:c4:
+                    f5:5f:ac:b4:2a:26:4e:8c:af:87:2e:f5:1d:78:69:
+                    15:b5:b4:b7:d3:52:ec:f4:c8:6e:c5:65:bd:88:e5:
+                    c4:da:0c:48:ac:d3:2d:a2:da:b0:72:75:09:1d:aa:
+                    d9:64:80:b7:18:31:54:07:d6:7a:8b:f3:be:b7:22:
+                    87:1c:3a:c7:2f:a9:4b:8d:79:06:a1:ff:1c:db:f3:
+                    17:9b:32:a0:61:20:6e:37:92:eb:27:a1:6f:b8:22:
+                    0e:26:4d:71:9a:b3:a0:9a:fb:fb:91:68:5b:52:3b:
+                    20:75:d5:36:a6:aa:c3:dc:52:01:87:06:58:68:62:
+                    20:b8:aa:bd:2b:c9:58:60:b7:02:2e:c4:4f:bf:ec:
+                    b7:43:13:3f:90:51:65:65:a9:ba:48:74:9e:3c:ad:
+                    93:b6:00:3f:93:11:e7:cd:ea:5f:11:44:b2:4f:d1:
+                    e3:fd:19:a8:bc:4a:c6:ae:4c:ec:83:85:fa:98:ed:
+                    0b:a3:8f:a0:35:38:d4:9f:96:fd:f3:b2:b5:80:d5:
+                    1e:a4
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                94:A7:CC:B9:AB:D7:48:81:B3:3A:71:6E:2B:F4:24:FE:2A:A4:C0:39
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        30:75:fb:1e:e2:d0:ff:18:3a:de:7d:49:8a:20:33:bc:0e:0c:
+        ad:7a:68:f8:57:91:3a:bd:2b:07:a7:25:a6:c6:d0:f7:30:57:
+        73:a3:34:af:ee:d3:5d:06:9f:80:f5:41:b7:7f:e8:0e:e2:28:
+        6c:a5:d7:82:9b:81:89:85:9f:47:5d:af:17:ab:f6:e1:02:4c:
+        01:2b:07:7c:2b:e1:77:1c:a4:e9:a6:89:97:50:49:87:73:04:
+        6e:32:50:f5:b7:be:f2:60:b3:9c:5f:b4:2a:d2:2f:c0:0b:82:
+        47:71:70:62:cc:98:ad:47:20:58:61:d6:c0:c5:30:65:3f:97:
+        43:47:50:cb:90:4c:c3:7c:50:c4:28:27:b7:2d:c8:2a:61:40:
+        18:7e:fa:ce:03:39:20:f9:96:a2:da:1c:fe:5e:c7:9f:f1:bc:
+        98:18:c1:63:e6:f6:35:35:d8:5d:18:2e:ef:87:7d:af:00:a3:
+        bc:12:18:c3:11:1e:8a:6d:bf:5d:10:87:6f:79:f3:8f:11:9d:
+        cb:0d:fe:f6:fe:4f:d0:2b:de:8e:3a:da:f3:46:11:ca:12:bb:
+        ca:22:67:05:45:e6:fd:9f:71:09:98:0b:1e:cf:51:73:b2:ad:
+        48:f9:06:2a:b5:5c:9f:f3:97:e0:8e:a3:df:57:1c:a7:94:ca:
+        f2:97:8e:56
+-----BEGIN CERTIFICATE-----
+MIIGoTCCBYmgAwIBAgIEIAkFJzANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDMxWhcN
+NDkwNTI1MjE0NDMxWjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEGRzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggM7MIICLgYHKoZIzjgEATCCAiECggEBAI9a
+gDRT4VJojM+b1XoBYFdj+fgBVZ5VF3/0zM3X+/ceNgAcrlxw6Bsz77iNqmkqZvBI
+/bslgutWvqzKSW5/F/07YVenFMHrmV1rggPbHBgqJQUZ7DS4wxssaYk3e4WbwKk5
+hEPxYAuRUOC1kzytHLgzTpsA7c1gWZtXBHvA+y1JRePOwIqqTQc6Q6M9BnBm/J+y
+j9bFH6V7ADapQl5Q2zg0jErG9jpYmqZXk/dOVYtG8LAbnKDL/FeRvm1HVqnRRs1D
+e/8klgrd19i3WI5qoesqukAK9tFTfIQG/BQc1TN5iLtP+rWHNWENsHsHu3R8MKej
+YH12ptFGK4Simihh8okCFQC/h7bdpmIPiKJEpZmsuRKCBXsurwKCAQEAhje9HWAS
+JfUBf37g594m9D3Udf6RQUGzxnB/ccZeTsEPPsy+nAvftI9uKg+QWyAUdccxE+LY
+c3N2tsT1X6y0KiZOjK+HLvUdeGkVtbS301Ls9MhuxWW9iOXE2gxIrNMtotqwcnUJ
+HarZZIC3GDFUB9Z6i/O+tyKHHDrHL6lLjXkGof8c2/MXmzKgYSBuN5LrJ6FvuCIO
+Jk1xmrOgmvv7kWhbUjsgddU2pqrD3FIBhwZYaGIguKq9K8lYYLcCLsRPv+y3QxM/
+kFFlZam6SHSePK2TtgA/kxHnzepfEUSyT9Hj/RmovErGrkzsg4X6mO0Lo4+gNTjU
+n5b987K1gNUepAOCAQUAAoIBAHqpZft2ur7z+pRZUu1O/ORwXo98FOdz1tI2a2LS
+VsluepFjck6pzi7rOF7EcvYsUqpR9M47KFU5w61dUvqsDDJI/ACfw9l1CY2C4MsH
+ZSklejQuu6AtMJFZDs6C+y2tpbK5K+xrsQQHDFIWfWwMsmTHxsurGKum+j4x849J
+dTNp0yoq5yw4tdZ9M5S6pj4v5TvMSifRWfOccbFGZD8o8TPRvMKLR5Itxh/7IzRW
+8W4YjnwLdUKKu5JEBFhB0Ztu1hSYlD13jZPTH+l7p3GUEO7p01pKuJFhNUwAdvKy
+Or2fQvnwjtq9jGD9fWWFmMV9Qrkn3gkKHIWnY+VxPKt43s+jgeswgegwHQYDVR0O
+BBYEFJSnzLmr10iBszpxbiv0JP4qpMA5MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2u
+wgcwLgCsWGObIH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMx
+GDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21t
+b25zLXNzbDENMAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2
+aWVzQGdtYWlsLmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
+A4IBAQAwdfse4tD/GDrefUmKIDO8Dgytemj4V5E6vSsHpyWmxtD3MFdzozSv7tNd
+Bp+A9UG3f+gO4ihspdeCm4GJhZ9HXa8Xq/bhAkwBKwd8K+F3HKTppomXUEmHcwRu
+MlD1t77yYLOcX7Qq0i/AC4JHcXBizJitRyBYYdbAxTBlP5dDR1DLkEzDfFDEKCe3
+LcgqYUAYfvrOAzkg+Zai2hz+Xsef8byYGMFj5vY1NdhdGC7vh32vAKO8EhjDER6K
+bb9dEIdvefOPEZ3LDf72/k/QK96OOtrzRhHKErvKImcFReb9n3EJmAsez1Fzsq1I
++QYqtVyf85fgjqPfVxynlMryl45W
+-----END CERTIFICATE-----
diff --git a/samples/ca/dsa-intermediate/dsa.params b/samples/ca/dsa-intermediate/dsa.params
new file mode 100644
index 0000000..5b4d97f
--- /dev/null
+++ b/samples/ca/dsa-intermediate/dsa.params
@@ -0,0 +1,34 @@
+-----BEGIN DSA PARAMETERS-----
+MIICIQKCAQEAj1qANFPhUmiMz5vVegFgV2P5+AFVnlUXf/TMzdf79x42AByuXHDo
+GzPvuI2qaSpm8Ej9uyWC61a+rMpJbn8X/TthV6cUweuZXWuCA9scGColBRnsNLjD
+GyxpiTd7hZvAqTmEQ/FgC5FQ4LWTPK0cuDNOmwDtzWBZm1cEe8D7LUlF487AiqpN
+BzpDoz0GcGb8n7KP1sUfpXsANqlCXlDbODSMSsb2OliapleT905Vi0bwsBucoMv8
+V5G+bUdWqdFGzUN7/ySWCt3X2LdYjmqh6yq6QAr20VN8hAb8FBzVM3mIu0/6tYc1
+YQ2wewe7dHwwp6NgfXam0UYrhKKaKGHyiQIVAL+Htt2mYg+IokSlmay5EoIFey6v
+AoIBAQCGN70dYBIl9QF/fuDn3ib0PdR1/pFBQbPGcH9xxl5OwQ8+zL6cC9+0j24q
+D5BbIBR1xzET4thzc3a2xPVfrLQqJk6Mr4cu9R14aRW1tLfTUuz0yG7FZb2I5cTa
+DEis0y2i2rBydQkdqtlkgLcYMVQH1nqL8763IoccOscvqUuNeQah/xzb8xebMqBh
+IG43kusnoW+4Ig4mTXGas6Ca+/uRaFtSOyB11TamqsPcUgGHBlhoYiC4qr0ryVhg
+twIuxE+/7LdDEz+QUWVlqbpIdJ48rZO2AD+TEefN6l8RRLJP0eP9Gai8SsauTOyD
+hfqY7Qujj6A1ONSflv3zsrWA1R6k
+-----END DSA PARAMETERS-----
+-----BEGIN DSA PRIVATE KEY-----
+MIIDPwIBAAKCAQEAj1qANFPhUmiMz5vVegFgV2P5+AFVnlUXf/TMzdf79x42AByu
+XHDoGzPvuI2qaSpm8Ej9uyWC61a+rMpJbn8X/TthV6cUweuZXWuCA9scGColBRns
+NLjDGyxpiTd7hZvAqTmEQ/FgC5FQ4LWTPK0cuDNOmwDtzWBZm1cEe8D7LUlF487A
+iqpNBzpDoz0GcGb8n7KP1sUfpXsANqlCXlDbODSMSsb2OliapleT905Vi0bwsBuc
+oMv8V5G+bUdWqdFGzUN7/ySWCt3X2LdYjmqh6yq6QAr20VN8hAb8FBzVM3mIu0/6
+tYc1YQ2wewe7dHwwp6NgfXam0UYrhKKaKGHyiQIVAL+Htt2mYg+IokSlmay5EoIF
+ey6vAoIBAQCGN70dYBIl9QF/fuDn3ib0PdR1/pFBQbPGcH9xxl5OwQ8+zL6cC9+0
+j24qD5BbIBR1xzET4thzc3a2xPVfrLQqJk6Mr4cu9R14aRW1tLfTUuz0yG7FZb2I
+5cTaDEis0y2i2rBydQkdqtlkgLcYMVQH1nqL8763IoccOscvqUuNeQah/xzb8xeb
+MqBhIG43kusnoW+4Ig4mTXGas6Ca+/uRaFtSOyB11TamqsPcUgGHBlhoYiC4qr0r
+yVhgtwIuxE+/7LdDEz+QUWVlqbpIdJ48rZO2AD+TEefN6l8RRLJP0eP9Gai8Ssau
+TOyDhfqY7Qujj6A1ONSflv3zsrWA1R6kAoIBAEv2b206JjZOeRVQ6R4gmCGhxCL6
+v8K/geGdHOzveYLGc+eaSfEP2X9F64rq4lf7kZSfjlwbCa7wPFiudQwTqIvtz6AO
+7tYfDk5BKsSqxfHChYHbTK5bUIvPapMH+aATdX0haXRRvNGY/V7lAPoBSwpWpPzG
+17rz29tysLZWvaDJK05Vwg+UmJB3AG4zyJGD/Zw2Ub/Eik1rL2N7p6ewa7EsTG4H
+pZAYwCJvAhidpaLfpoFxmF7VsMU+e/SwV++sbElb/a9szjbRc80jTyDHdxTO+hCS
+6MJjQkev4Bzy4+DO/PrCESoZymg4skRkVVc0knpSuGUviPZejvkdVo26mlsCFQCW
+c8bFDKclUXmeh6vxr7RGih+SKg==
+-----END DSA PRIVATE KEY-----
diff --git a/samples/ca/dsa-intermediate/private/cakey.pem b/samples/ca/dsa-intermediate/private/cakey.pem
new file mode 100644
index 0000000..adc6d0b
--- /dev/null
+++ b/samples/ca/dsa-intermediate/private/cakey.pem
@@ -0,0 +1,20 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIDPgIBAAKCAQEAj1qANFPhUmiMz5vVegFgV2P5+AFVnlUXf/TMzdf79x42AByu
+XHDoGzPvuI2qaSpm8Ej9uyWC61a+rMpJbn8X/TthV6cUweuZXWuCA9scGColBRns
+NLjDGyxpiTd7hZvAqTmEQ/FgC5FQ4LWTPK0cuDNOmwDtzWBZm1cEe8D7LUlF487A
+iqpNBzpDoz0GcGb8n7KP1sUfpXsANqlCXlDbODSMSsb2OliapleT905Vi0bwsBuc
+oMv8V5G+bUdWqdFGzUN7/ySWCt3X2LdYjmqh6yq6QAr20VN8hAb8FBzVM3mIu0/6
+tYc1YQ2wewe7dHwwp6NgfXam0UYrhKKaKGHyiQIVAL+Htt2mYg+IokSlmay5EoIF
+ey6vAoIBAQCGN70dYBIl9QF/fuDn3ib0PdR1/pFBQbPGcH9xxl5OwQ8+zL6cC9+0
+j24qD5BbIBR1xzET4thzc3a2xPVfrLQqJk6Mr4cu9R14aRW1tLfTUuz0yG7FZb2I
+5cTaDEis0y2i2rBydQkdqtlkgLcYMVQH1nqL8763IoccOscvqUuNeQah/xzb8xeb
+MqBhIG43kusnoW+4Ig4mTXGas6Ca+/uRaFtSOyB11TamqsPcUgGHBlhoYiC4qr0r
+yVhgtwIuxE+/7LdDEz+QUWVlqbpIdJ48rZO2AD+TEefN6l8RRLJP0eP9Gai8Ssau
+TOyDhfqY7Qujj6A1ONSflv3zsrWA1R6kAoIBAHqpZft2ur7z+pRZUu1O/ORwXo98
+FOdz1tI2a2LSVsluepFjck6pzi7rOF7EcvYsUqpR9M47KFU5w61dUvqsDDJI/ACf
+w9l1CY2C4MsHZSklejQuu6AtMJFZDs6C+y2tpbK5K+xrsQQHDFIWfWwMsmTHxsur
+GKum+j4x849JdTNp0yoq5yw4tdZ9M5S6pj4v5TvMSifRWfOccbFGZD8o8TPRvMKL
+R5Itxh/7IzRW8W4YjnwLdUKKu5JEBFhB0Ztu1hSYlD13jZPTH+l7p3GUEO7p01pK
+uJFhNUwAdvKyOr2fQvnwjtq9jGD9fWWFmMV9Qrkn3gkKHIWnY+VxPKt43s8CFDIz
+Am1wgwvcQt/K9JADNgPY9gyS
+-----END DSA PRIVATE KEY-----
diff --git a/samples/ca/openssl.cnf b/samples/ca/openssl.cnf
new file mode 100644
index 0000000..9e59020
--- /dev/null
+++ b/samples/ca/openssl.cnf
@@ -0,0 +1,313 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+crl		= $dir/crl.pem 		# The current CRL
+private_key	= $dir/private/cakey.pem# The private key
+RANDFILE	= $dir/private/.rand	# private random number file
+
+x509_extensions	= usr_cert		# The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+default_bits		= 1024
+default_keyfile 	= privkey.pem
+distinguished_name	= req_distinguished_name
+attributes		= req_attributes
+x509_extensions	= v3_ca	# The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= AU
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+
+localityName			= Locality Name (eg, city)
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+#organizationalUnitName_default	=
+
+commonName			= Common Name (eg, YOUR name)
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
diff --git a/samples/ca/root/cacert.pem b/samples/ca/root/cacert.pem
new file mode 100644
index 0000000..bb8bf4b
--- /dev/null
+++ b/samples/ca/root/cacert.pem
@@ -0,0 +1,85 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:28 2009 GMT
+            Not After : May 25 21:44:28 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:b9:db:04:16:8c:41:eb:91:c4:b8:d1:1a:73:28:
+                    59:09:b8:7a:b5:05:40:db:4f:2b:63:7b:bf:01:70:
+                    e1:0d:4c:09:3a:3b:63:9e:22:13:fa:55:d1:bc:e8:
+                    dd:31:71:df:0d:a6:0b:29:29:cc:da:bd:69:5c:cb:
+                    29:7e:6c:8c:93:82:c7:8b:00:ea:0b:8c:35:5c:fe:
+                    28:12:cf:ba:11:24:48:bc:0a:ee:37:54:a3:f2:9b:
+                    f2:76:94:7d:56:c0:52:35:f0:ff:c8:8c:08:7e:b0:
+                    49:c5:2f:fd:41:92:06:e8:c2:71:0d:f6:70:e5:93:
+                    89:80:a2:13:43:ac:53:56:ba:1a:44:44:98:cd:ba:
+                    f9:3a:93:20:71:34:93:0f:3f:34:34:2e:53:b2:d7:
+                    4a:22:3e:89:0a:c3:6e:12:40:ba:f3:22:6d:38:63:
+                    3b:f0:ef:42:2b:2d:f4:d2:f8:a9:76:ce:13:37:ce:
+                    1a:a4:bd:42:a0:7b:71:df:0e:3f:93:10:9d:22:0a:
+                    8b:61:92:c6:4c:fe:e7:bf:56:f4:5c:d3:85:98:92:
+                    a2:dc:d1:3d:f8:6e:3e:ac:e1:87:2f:e1:fb:30:d5:
+                    3d:24:fc:d9:d1:ac:b9:ca:9c:41:ff:60:aa:e4:57:
+                    7e:b1:93:ac:4f:64:b5:0a:d3:57:4e:12:68:5b:18:
+                    d2:15
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        9a:29:28:5e:4f:4f:59:f8:6b:b0:96:bf:ef:69:02:36:d1:72:
+        af:a2:f3:c0:7d:c1:50:5a:b8:63:61:18:1a:d4:4d:8f:a4:b2:
+        18:5d:1b:75:1d:b6:ce:e6:aa:b3:c1:16:ab:dd:64:ac:be:62:
+        7f:77:1d:d4:6a:eb:5d:f7:19:eb:6a:6a:60:6d:ca:d6:2a:4d:
+        ee:c9:5b:1e:05:eb:bb:3f:5f:a4:76:ae:fd:32:ac:1e:63:e7:
+        35:d3:95:1d:c9:bc:7a:2f:e7:0e:04:95:59:4d:30:51:ac:67:
+        65:41:74:b3:62:f6:4d:85:4b:88:26:15:c2:2d:03:69:16:f7:
+        6a:8a:5c:ca:ca:7b:ba:41:f9:7b:f4:ae:f8:29:56:48:9d:86:
+        2e:0a:06:7a:21:97:01:b3:d4:45:5a:14:05:d3:b1:3a:da:0a:
+        67:6d:d5:45:db:ba:88:09:4b:53:b3:69:1a:52:de:57:03:89:
+        fa:99:82:1d:79:fb:ae:55:d7:13:fd:5e:99:25:cb:75:a1:62:
+        b4:27:f0:54:4b:78:42:8b:54:63:62:f4:a3:0b:e2:26:a4:0c:
+        29:ae:49:b4:1a:34:e6:a4:07:8a:64:cb:63:46:ae:fa:ec:d0:
+        f4:e1:e2:25:11:57:27:61:e8:d1:48:ad:60:13:2d:b9:38:a3:
+        52:03:0f:ad
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
diff --git a/samples/ca/root/private/cakey.pem b/samples/ca/root/private/cakey.pem
new file mode 100644
index 0000000..d4bb17a
--- /dev/null
+++ b/samples/ca/root/private/cakey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAudsEFoxB65HEuNEacyhZCbh6tQVA208rY3u/AXDhDUwJOjtj
+niIT+lXRvOjdMXHfDaYLKSnM2r1pXMspfmyMk4LHiwDqC4w1XP4oEs+6ESRIvAru
+N1Sj8pvydpR9VsBSNfD/yIwIfrBJxS/9QZIG6MJxDfZw5ZOJgKITQ6xTVroaRESY
+zbr5OpMgcTSTDz80NC5TstdKIj6JCsNuEkC68yJtOGM78O9CKy300vipds4TN84a
+pL1CoHtx3w4/kxCdIgqLYZLGTP7nv1b0XNOFmJKi3NE9+G4+rOGHL+H7MNU9JPzZ
+0ay5ypxB/2Cq5Fd+sZOsT2S1CtNXThJoWxjSFQIDAQABAoIBAH6oCRMspkfZYQzq
+Q3IzDuqW89ilKdvLCjCTxkk/Gb+sD6XFj0/WvXKeRX7N2t+1UGLGw1hcCiUPa9w2
+/6IOa4ajW0UZbGZOOJeVBM49DfpclczATjMa1VeiewvgicIy8lOcV1PeSnO7w6pD
+1/11fIvm5pCzX6C0eMJWsXYu2+R/abc1VJPsm+lJ4dTErAM0MQNjbpSB7rth5AAh
+V4e1W6SU0IqMZbTfFYwwgwUHSW8Q3wk30yY0tiMoblNaDfYomoGK1ekfCpdE9eve
+okGGs5Nv3q4h1gJsUPF9oSWcCuMW3zTKH6DUtuuE08Q9x1Z/g1YralWV4WnApSSS
+iZy3k4kCgYEA4G5lOblwaZ3rmV4h76lwwOderqwdLs0T4p7TUalgg+fiy2ifC37d
+VXyk/ZEw9nqWH1C9QIUpM6VH0l/cYxCAt94ioYkZZYQmGZVGzBOdIA4LEdP1juN4
+fCOuesxSaRu2DEVf3J7U1XsOsLPT9cUb/UtgmUqVrcprSiYDmYWU+cMCgYEA0/+J
+qytZi5PFZWa+rBxm6zb1WXrIzs3AavVWG2ryGjZuLjO0ADLDDPTvNI6WGo807PpX
+2ISq7VAFCWm1kukgUFNc7a+uIAMHV4USW5MRnTtc91C71iBabYs2uYJnP9KZKjnz
+1kji6+jz4wbHyIddkMwKVCmMmdHHlhXpj4vUb0cCgYAdUE4IbCAyq13KenEUTJ1d
+lNrZFcH6Cu89+mC/mc/xaqhEyTV82uUt9UnXlM9AYmKZVIJjmwD2re/jmoG+rrkh
+SvJbBv06NTiEvuqwXR94wFzRx02bjDqAfGidwXJCKExu7eDHgDdsatZQXiyhPU2a
+l+3WF9fVC0tYM/7kXn5G4QKBgF1AnrIok28ORVphY6YZqDv3JN2DYSl24BksagAN
+fwmAv96a56berWXZqA8aWXS9Ya6MQHABi55wAIcvdKt22Lv8r3fuO03hhy08X+Lg
+QnNDVZWEcduyx5RAFIZtkjVE0hL9AwFTdl4HTqCirubKhKHY3wI+dJaE7KJcaSy3
+eW6pAoGAayYZFNrDqHJJl8urrX2k6K+m+VE0xU94h9Vx4MpRa/f9bZ0U8YVNdTkZ
+BR6kUHOpOFO166jcBZJX3V305IbQB5TeysIyYqBaMATDc6tAEB+Celoz3+hw/Je2
+bIiQgdtctH4MarQkGlokUGjEz2aMg0l7vecgxQE88l/svAF3vmA=
+-----END RSA PRIVATE KEY-----
diff --git a/samples/ca/rsa-intermediate/cacert.pem b/samples/ca/rsa-intermediate/cacert.pem
new file mode 100644
index 0000000..ac2c117
--- /dev/null
+++ b/samples/ca/rsa-intermediate/cacert.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462054 (0x20090526)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:29 2009 GMT
+            Not After : May 25 21:44:29 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=rsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:ce:1b:db:73:49:85:a4:3c:42:14:84:6a:7d:47:
+                    78:d2:e1:58:27:ed:e4:78:5e:5d:2b:ee:c3:29:c5:
+                    a2:d2:6f:f3:0e:0a:d6:d6:7f:5a:f7:30:6f:c9:8f:
+                    ad:fe:53:22:46:aa:5e:0b:f6:e8:21:f3:dc:5f:75:
+                    9b:55:c5:07:ab:75:54:fd:9b:2e:31:da:12:45:3c:
+                    7b:1e:27:f6:a1:5b:5d:ac:0a:b4:e8:dd:d3:ba:ff:
+                    af:f1:43:31:4c:5b:5e:73:d4:a8:ce:93:b9:f1:9d:
+                    8b:17:1f:16:74:4f:9a:07:80:7c:1a:41:a6:49:21:
+                    2a:a8:83:75:18:3d:ed:17:8b:8b:b4:f8:46:d3:28:
+                    25:35:e1:17:df:e6:b4:f7:87:a7:71:0f:a0:b5:22:
+                    4d:48:35:2c:a3:dc:fc:58:33:76:fb:07:cf:fb:64:
+                    e9:fa:05:a8:be:63:eb:32:48:01:10:fd:44:a2:79:
+                    72:5d:33:62:1b:ad:f4:60:3f:7d:59:9c:07:cf:9c:
+                    b1:b5:e7:18:84:5e:ec:e0:78:6c:53:f0:cf:67:8d:
+                    91:95:73:72:de:70:c7:ca:ea:27:6f:d2:61:c8:7d:
+                    a5:28:28:61:c8:c9:e9:6b:7e:ae:07:9d:36:87:04:
+                    a4:97:1c:1d:f5:39:cb:b2:8a:32:8d:25:68:05:2d:
+                    86:65
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                2E:F4:CD:A1:B4:AD:03:85:D8:AF:69:97:D5:2D:95:40:D6:BF:12:BF
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        03:b6:83:af:6c:ff:2b:21:12:b9:8a:cd:8e:2f:d9:1a:28:88:
+        0c:9f:f1:6b:73:fb:76:3f:70:d8:cd:ce:5a:f6:0f:08:6a:0a:
+        a3:f7:ad:b2:72:19:eb:0e:9c:36:bb:a4:fb:3f:90:78:ba:45:
+        ee:da:c9:8e:a0:ef:b3:ac:05:4c:f4:b4:37:18:0d:bb:20:5d:
+        f4:e7:b3:77:ea:56:0c:ad:81:42:80:04:92:ca:3b:73:ed:35:
+        d5:35:f6:9f:95:a2:2d:81:4d:e6:3a:3c:13:64:f1:0f:36:7e:
+        90:c2:a0:37:c6:19:9e:13:47:92:a3:e8:18:3d:f4:d8:a0:83:
+        80:0f:7b:a7:57:9c:60:6c:6a:3e:d4:1d:cc:5e:8c:13:7f:1c:
+        d7:f6:df:ad:ae:0a:95:12:f1:71:c2:70:98:d1:2f:6c:f0:24:
+        43:b4:7e:a4:e4:31:d4:bc:50:90:03:4b:34:ba:a3:d0:fd:f5:
+        01:17:eb:11:83:44:86:65:17:bf:89:00:c7:93:d6:70:7e:0b:
+        4b:93:dc:f9:92:50:4c:3e:11:23:c5:50:1c:49:bd:8c:0c:2c:
+        60:1c:d8:e6:5f:a4:fa:21:db:8c:62:bf:74:a3:83:1c:8d:cc:
+        8e:34:8c:16:1c:c6:71:63:89:c2:c4:45:0c:90:71:98:68:2f:
+        9d:a7:87:f7
+-----BEGIN CERTIFICATE-----
+MIIEiDCCA3CgAwIBAgIEIAkFJjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI5WhcN
+NDkwNTI1MjE0NDI5WjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDOG9tzSYWkPEIUhGp9R3jS4Vgn7eR4Xl0r7sMpxaLSb/MOCtbWf1r3MG/J
+j63+UyJGql4L9ugh89xfdZtVxQerdVT9my4x2hJFPHseJ/ahW12sCrTo3dO6/6/x
+QzFMW15z1KjOk7nxnYsXHxZ0T5oHgHwaQaZJISqog3UYPe0Xi4u0+EbTKCU14Rff
+5rT3h6dxD6C1Ik1INSyj3PxYM3b7B8/7ZOn6Bai+Y+sySAEQ/USieXJdM2IbrfRg
+P31ZnAfPnLG15xiEXuzgeGxT8M9njZGVc3LecMfK6idv0mHIfaUoKGHIyelrfq4H
+nTaHBKSXHB31OcuyijKNJWgFLYZlAgMBAAGjgeswgegwHQYDVR0OBBYEFC70zaG0
+rQOF2K9pl9UtlUDWvxK/MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGOb
+IH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoT
+D2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDEN
+MAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWls
+LmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQADtoOv
+bP8rIRK5is2OL9kaKIgMn/Frc/t2P3DYzc5a9g8Iagqj962ychnrDpw2u6T7P5B4
+ukXu2smOoO+zrAVM9LQ3GA27IF3057N36lYMrYFCgASSyjtz7TXVNfaflaItgU3m
+OjwTZPEPNn6QwqA3xhmeE0eSo+gYPfTYoIOAD3unV5xgbGo+1B3MXowTfxzX9t+t
+rgqVEvFxwnCY0S9s8CRDtH6k5DHUvFCQA0s0uqPQ/fUBF+sRg0SGZRe/iQDHk9Zw
+fgtLk9z5klBMPhEjxVAcSb2MDCxgHNjmX6T6IduMYr90o4McjcyONIwWHMZxY4nC
+xEUMkHGYaC+dp4f3
+-----END CERTIFICATE-----
diff --git a/samples/ca/rsa-intermediate/private/cakey.pem b/samples/ca/rsa-intermediate/private/cakey.pem
new file mode 100644
index 0000000..466f54a
--- /dev/null
+++ b/samples/ca/rsa-intermediate/private/cakey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAzhvbc0mFpDxCFIRqfUd40uFYJ+3keF5dK+7DKcWi0m/zDgrW
+1n9a9zBvyY+t/lMiRqpeC/boIfPcX3WbVcUHq3VU/ZsuMdoSRTx7Hif2oVtdrAq0
+6N3Tuv+v8UMxTFtec9SozpO58Z2LFx8WdE+aB4B8GkGmSSEqqIN1GD3tF4uLtPhG
+0yglNeEX3+a094encQ+gtSJNSDUso9z8WDN2+wfP+2Tp+gWovmPrMkgBEP1Eonly
+XTNiG630YD99WZwHz5yxtecYhF7s4HhsU/DPZ42RlXNy3nDHyuonb9JhyH2lKChh
+yMnpa36uB502hwSklxwd9TnLsooyjSVoBS2GZQIDAQABAoIBADajAdic69Vut+Gy
+fHw7Xxcf73ueP4t9EFveDlRbdN8uGBNn4i24UwfmCiw3b1tU9GghL48iY8TkXU3c
+4lGpSnA0SVR1N5i1g1RhRQ3ocCO0Ea/SosR8UW1n7F8bfc0NB4vTGvCwDoGzTrTR
+Y+VvWJiWgc+ACbGnHiTPvFGx0NEFjizCrBTWDCSMbHdujEkw/gZt1PhKgJg0DbUj
+M4zLG0YCIR/RSnNHYKgMEl2PXCKHLsMwyH52BMi/lmh47N2H0cC/5YSoCX6s1Y8I
+ZWojgMJVCN4SQInm630hiF8X0r3yQFvig1OYyebpJpqHSJUZ6GGQl5M6p8MFlgam
+BNFakH0CgYEA7F1+SJMOeWB+TnP7ilvYaXzE+aLvJ0/Wl5whyxJCCkMJsz+120Ui
+4ooKbohQF0h1IXJGeFS4hD/DK+3S/mjjBC8TQBtuvWzhk2+C7+Gigke4XjrdJXbB
+b87nDf1EPY9d1lGhVRmVh2APgPxgmw7mb3WgMN3lnh0xknhEoHPYbdMCgYEA3zrv
+pNAnGHg8ALJTHWiyEWrXRIhuOYOJa2oQB4cQeK6ou5UsfzQsd6w2UmwzghOTNtrM
+fvGeHECsTVh8AeNY9sT0GG5BY+DcOlYn3Dgs7UW0w8otZ/D/lmc9+Z/R4hBo/qcY
+h7WkcG5S0TeIiam9bq5EfTUAs5fFvbYRsdAGv+cCgYAuvrq33aVyKbwxBc0Mauec
+zRkjia6kZqy45R7ly2GWJ/XmJkZv6/dfOA+iFoFIaYMIr1HygEbRmM6fhHRC7jlf
+XXQALKy097CQ+O+7QzNhco+qyxdrTlYpJ5EYeishxZW4SgKPEvU4ha3rQ35TjBnU
+lz2sDGZZ48om/nQMC30VEwKBgQDKl5xiQZ8ZsBUUtMKF0Dy7XfGcew0+GUigOZPu
+oP+r5yevhoTptRoeSibKyvQ8OzPB9vTcyL+r+G3njESPGhvlaX32pimmUa7NKt/m
+Fv1/IWIaxuRKjwgHIg+2+vrqZeZEJrY2g/2HJDj5M6Mw/OG1D2eNEotecoG92P1a
+GOfnRQKBgQCe/zEs+IZxrnqMq+B5QIiSBTliZeGApOG7P+TS1MyvIijeIM5d1LNc
+oUtzPUSOz0CwQT669F8C4gOllnXImyHUkivBxgfwLJcOt6NqxfiTIcDqrf7jaNyp
+R8l/GuwFPz/DtBsFizfYmY9cXV5/Ihz9/gmnw0oFgVX2MLVv0CRKZA==
+-----END RSA PRIVATE KEY-----
diff --git a/samples/ca/rsa.key b/samples/ca/rsa.key
new file mode 100644
index 0000000..f540dcc
--- /dev/null
+++ b/samples/ca/rsa.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyGOvloI+jKnRHWKuhYB+cTIEwZhagKJ0f3rIY8WNgujB7Plp
+gpjUg4pNjYGViGjg7zhfbjhCtlNGXyRBti3GcaHiBIIP5nyCNn+Ay8tSWGo5v5Zc
+8BQcwHf0ZHLN6sD9m2uVSp/6UqjS5ZyhzF5FzvvUo3xw8fecdnStXQfHhkBnLpTj
+HE5t7iu1JVjTuE0pcBvah2dWqDNxiIOQtXyKW8Sag1YxaunxQGqRNykSFiEJindx
+OSAnAxK6q/wGqcZ3zvFBTcVVkji1u2QH4rOMP3PPxAIMkB8ONkdHTco1DmbE6BfD
+HArDqUYxqJUlPGlMqrKb3fCFiT3eXehwR7nlzQIDAQABAoIBAFd6vTKVVT0O/U04
+wTtiptA/p7fkDM5PHVBxh32Wxno5pj8PerIaiduKyuRVh7PvJRMJpw903BrAK95o
+847WWOVOaF7TcKGMBURJUS6maiJS7TboK1ZbUVnsg/I99ArhiVUKGDhlsl/Xd4np
+YPDYztzXLzLXpm7bS6CiuvP762x9dfVu8K+afP8cjH8pfXLq55ghZOUKidRQaYz1
+mNOTQyAQlCQdLRgKlYgqcRHlj0pb28XBJaln3W7Z7GFMWFPojkxx6LaCp8+Jyx2C
+tv54zIZQhMjF37tQyTnfK4Ocl3sCRb+jYV4FkrUnsQE9W2dey0Tms1XB31gfUJlx
+dRZu7zkCgYEA/nWcTwzot2OIAhXoJ2fnqTcpdmj05LHhGcayKjyix7BsVH2I0KpF
+9kXX066tr3+LxZTergl4UpWSl3yx/4kPBQM6np4VVRytn7+cQdEhOczZnBw6x7IZ
+fv81DSNruQDBRAlTtklW4KBY74JKLhaJSvF1F3x32+H+99i1MmCNJRMCgYEAyZpF
+h4c3pM9z+YlmgLdUh/G2abdoamugcQOFbzHbZowsRAxEzdEW9wj2McN6mt8Rn1tc
+tY/+PcYuIK+vcmk9k23GuzxRlJlkaDicHwlAebgVIulFcrStfTlSkXjpuOuusfD9
+2DuHMcUiPx3qElNB0dZJF/axpq7BjTIFENefhZ8CgYACn+vw1M1BtwEcJGW0olm9
+YRhIZGTCRyNvRKFp1h5HuQYlCPZ0UI1QMQA86rxX5xTmANcbLHXVRD2y2lJrtFo3
+TwU3xaGqsxUHZM6TzzhshDRqa9AfZzLkIHXHoOnnip5zuTTn2HHQ91ZzggCJ4Smh
+YEQ47cu+tOIQZGfaESzjiQKBgQCCfnZlDJRq/NFwA40y4fg4arANa+eNgw7+OC5F
+1HrUvQTmIx7iLmZ0Dvv1KDgTSTLJ+MRgzczexYoUJEQnhZGS/Wq2xYt06XlBsOr1
+d/KhFxOvXllSrzrhJJqaiS6YQQ36JijZr2aKQ7UwL7fUlsmy/safWVKStumX8Hmw
+9jFOtwKBgQDmtirdNQ8aKolokD/3bDHPcDsNcybEpiCu8BIltxZAs/LsN1IIxfcp
+mGP2AFt3mbblKbsRM8hDW/X9taeG9s2KGe5wlKOE5lV8YAo4hFoJYN2/0d8Y0K9X
+QAAYU3iPG1zL+a/7TFLJ0u/biqsBg9hnNbMnN/tOeSuKnH2Rx9F1rg==
+-----END RSA PRIVATE KEY-----
diff --git a/samples/ca/test-dsa-cert.pem b/samples/ca/test-dsa-cert.pem
new file mode 100644
index 0000000..d96dc66
--- /dev/null
+++ b/samples/ca/test-dsa-cert.pem
@@ -0,0 +1,67 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: dsaWithSHA1
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=dsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=test/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:c8:63:af:96:82:3e:8c:a9:d1:1d:62:ae:85:80:
+                    7e:71:32:04:c1:98:5a:80:a2:74:7f:7a:c8:63:c5:
+                    8d:82:e8:c1:ec:f9:69:82:98:d4:83:8a:4d:8d:81:
+                    95:88:68:e0:ef:38:5f:6e:38:42:b6:53:46:5f:24:
+                    41:b6:2d:c6:71:a1:e2:04:82:0f:e6:7c:82:36:7f:
+                    80:cb:cb:52:58:6a:39:bf:96:5c:f0:14:1c:c0:77:
+                    f4:64:72:cd:ea:c0:fd:9b:6b:95:4a:9f:fa:52:a8:
+                    d2:e5:9c:a1:cc:5e:45:ce:fb:d4:a3:7c:70:f1:f7:
+                    9c:76:74:ad:5d:07:c7:86:40:67:2e:94:e3:1c:4e:
+                    6d:ee:2b:b5:25:58:d3:b8:4d:29:70:1b:da:87:67:
+                    56:a8:33:71:88:83:90:b5:7c:8a:5b:c4:9a:83:56:
+                    31:6a:e9:f1:40:6a:91:37:29:12:16:21:09:8a:77:
+                    71:39:20:27:03:12:ba:ab:fc:06:a9:c6:77:ce:f1:
+                    41:4d:c5:55:92:38:b5:bb:64:07:e2:b3:8c:3f:73:
+                    cf:c4:02:0c:90:1f:0e:36:47:47:4d:ca:35:0e:66:
+                    c4:e8:17:c3:1c:0a:c3:a9:46:31:a8:95:25:3c:69:
+                    4c:aa:b2:9b:dd:f0:85:89:3d:de:5d:e8:70:47:b9:
+                    e5:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                9F:14:77:BF:3F:3A:B6:CA:38:82:42:48:16:2C:DA:D0:CB:5E:87:D8
+            X509v3 Authority Key Identifier: 
+                keyid:94:A7:CC:B9:AB:D7:48:81:B3:3A:71:6E:2B:F4:24:FE:2A:A4:C0:39
+
+    Signature Algorithm: dsaWithSHA1
+        30:2d:02:15:00:86:ec:d5:ef:f1:75:60:a2:09:36:40:ff:ca:
+        83:67:6a:08:5d:d4:1e:02:14:51:6c:df:41:80:43:74:2a:1c:
+        48:c2:08:85:5b:9b:7d:07:46:6b:84
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAvugAwIBAgIEIAkFJTAJBgcqhkjOOAQDMIGUMQswCQYDVQQGEwJDQTEL
+MAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMT
+bm90LXlldC1jb21tb25zLXNzbDEZMBcGA1UEAxMQZHNhLWludGVybWVkaWF0ZTEl
+MCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbTAeFw0wOTA1MjUy
+MTQ0MzFaFw00OTA1MjUyMTQ0MzFaMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMC
+QkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1j
+b21tb25zLXNzbDENMAsGA1UEAxMEdGVzdDElMCMGCSqGSIb3DQEJARYWanVsaXVz
+ZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2BlYho
+4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRyzerA
+/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY07hN
+KXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8BqnG
+d87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiVJTxp
+TKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
+AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJ8U
+d78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFJSnzLmr10iBszpxbiv0JP4q
+pMA5MAkGByqGSM44BAMDMAAwLQIVAIbs1e/xdWCiCTZA/8qDZ2oIXdQeAhRRbN9B
+gEN0KhxIwgiFW5t9B0ZrhA==
+-----END CERTIFICATE-----
diff --git a/samples/ca/test-dsa-chain.pem b/samples/ca/test-dsa-chain.pem
new file mode 100644
index 0000000..7418215
--- /dev/null
+++ b/samples/ca/test-dsa-chain.pem
@@ -0,0 +1,289 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: dsaWithSHA1
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=dsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=test/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:c8:63:af:96:82:3e:8c:a9:d1:1d:62:ae:85:80:
+                    7e:71:32:04:c1:98:5a:80:a2:74:7f:7a:c8:63:c5:
+                    8d:82:e8:c1:ec:f9:69:82:98:d4:83:8a:4d:8d:81:
+                    95:88:68:e0:ef:38:5f:6e:38:42:b6:53:46:5f:24:
+                    41:b6:2d:c6:71:a1:e2:04:82:0f:e6:7c:82:36:7f:
+                    80:cb:cb:52:58:6a:39:bf:96:5c:f0:14:1c:c0:77:
+                    f4:64:72:cd:ea:c0:fd:9b:6b:95:4a:9f:fa:52:a8:
+                    d2:e5:9c:a1:cc:5e:45:ce:fb:d4:a3:7c:70:f1:f7:
+                    9c:76:74:ad:5d:07:c7:86:40:67:2e:94:e3:1c:4e:
+                    6d:ee:2b:b5:25:58:d3:b8:4d:29:70:1b:da:87:67:
+                    56:a8:33:71:88:83:90:b5:7c:8a:5b:c4:9a:83:56:
+                    31:6a:e9:f1:40:6a:91:37:29:12:16:21:09:8a:77:
+                    71:39:20:27:03:12:ba:ab:fc:06:a9:c6:77:ce:f1:
+                    41:4d:c5:55:92:38:b5:bb:64:07:e2:b3:8c:3f:73:
+                    cf:c4:02:0c:90:1f:0e:36:47:47:4d:ca:35:0e:66:
+                    c4:e8:17:c3:1c:0a:c3:a9:46:31:a8:95:25:3c:69:
+                    4c:aa:b2:9b:dd:f0:85:89:3d:de:5d:e8:70:47:b9:
+                    e5:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                9F:14:77:BF:3F:3A:B6:CA:38:82:42:48:16:2C:DA:D0:CB:5E:87:D8
+            X509v3 Authority Key Identifier: 
+                keyid:94:A7:CC:B9:AB:D7:48:81:B3:3A:71:6E:2B:F4:24:FE:2A:A4:C0:39
+
+    Signature Algorithm: dsaWithSHA1
+        30:2d:02:15:00:86:ec:d5:ef:f1:75:60:a2:09:36:40:ff:ca:
+        83:67:6a:08:5d:d4:1e:02:14:51:6c:df:41:80:43:74:2a:1c:
+        48:c2:08:85:5b:9b:7d:07:46:6b:84
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAvugAwIBAgIEIAkFJTAJBgcqhkjOOAQDMIGUMQswCQYDVQQGEwJDQTEL
+MAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMT
+bm90LXlldC1jb21tb25zLXNzbDEZMBcGA1UEAxMQZHNhLWludGVybWVkaWF0ZTEl
+MCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbTAeFw0wOTA1MjUy
+MTQ0MzFaFw00OTA1MjUyMTQ0MzFaMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMC
+QkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1j
+b21tb25zLXNzbDENMAsGA1UEAxMEdGVzdDElMCMGCSqGSIb3DQEJARYWanVsaXVz
+ZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2BlYho
+4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRyzerA
+/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY07hN
+KXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8BqnG
+d87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiVJTxp
+TKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
+AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJ8U
+d78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFJSnzLmr10iBszpxbiv0JP4q
+pMA5MAkGByqGSM44BAMDMAAwLQIVAIbs1e/xdWCiCTZA/8qDZ2oIXdQeAhRRbN9B
+gEN0KhxIwgiFW5t9B0ZrhA==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462055 (0x20090527)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=dsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    7a:a9:65:fb:76:ba:be:f3:fa:94:59:52:ed:4e:fc:
+                    e4:70:5e:8f:7c:14:e7:73:d6:d2:36:6b:62:d2:56:
+                    c9:6e:7a:91:63:72:4e:a9:ce:2e:eb:38:5e:c4:72:
+                    f6:2c:52:aa:51:f4:ce:3b:28:55:39:c3:ad:5d:52:
+                    fa:ac:0c:32:48:fc:00:9f:c3:d9:75:09:8d:82:e0:
+                    cb:07:65:29:25:7a:34:2e:bb:a0:2d:30:91:59:0e:
+                    ce:82:fb:2d:ad:a5:b2:b9:2b:ec:6b:b1:04:07:0c:
+                    52:16:7d:6c:0c:b2:64:c7:c6:cb:ab:18:ab:a6:fa:
+                    3e:31:f3:8f:49:75:33:69:d3:2a:2a:e7:2c:38:b5:
+                    d6:7d:33:94:ba:a6:3e:2f:e5:3b:cc:4a:27:d1:59:
+                    f3:9c:71:b1:46:64:3f:28:f1:33:d1:bc:c2:8b:47:
+                    92:2d:c6:1f:fb:23:34:56:f1:6e:18:8e:7c:0b:75:
+                    42:8a:bb:92:44:04:58:41:d1:9b:6e:d6:14:98:94:
+                    3d:77:8d:93:d3:1f:e9:7b:a7:71:94:10:ee:e9:d3:
+                    5a:4a:b8:91:61:35:4c:00:76:f2:b2:3a:bd:9f:42:
+                    f9:f0:8e:da:bd:8c:60:fd:7d:65:85:98:c5:7d:42:
+                    b9:27:de:09:0a:1c:85:a7:63:e5:71:3c:ab:78:de:
+                    cf
+                P:   
+                    00:8f:5a:80:34:53:e1:52:68:8c:cf:9b:d5:7a:01:
+                    60:57:63:f9:f8:01:55:9e:55:17:7f:f4:cc:cd:d7:
+                    fb:f7:1e:36:00:1c:ae:5c:70:e8:1b:33:ef:b8:8d:
+                    aa:69:2a:66:f0:48:fd:bb:25:82:eb:56:be:ac:ca:
+                    49:6e:7f:17:fd:3b:61:57:a7:14:c1:eb:99:5d:6b:
+                    82:03:db:1c:18:2a:25:05:19:ec:34:b8:c3:1b:2c:
+                    69:89:37:7b:85:9b:c0:a9:39:84:43:f1:60:0b:91:
+                    50:e0:b5:93:3c:ad:1c:b8:33:4e:9b:00:ed:cd:60:
+                    59:9b:57:04:7b:c0:fb:2d:49:45:e3:ce:c0:8a:aa:
+                    4d:07:3a:43:a3:3d:06:70:66:fc:9f:b2:8f:d6:c5:
+                    1f:a5:7b:00:36:a9:42:5e:50:db:38:34:8c:4a:c6:
+                    f6:3a:58:9a:a6:57:93:f7:4e:55:8b:46:f0:b0:1b:
+                    9c:a0:cb:fc:57:91:be:6d:47:56:a9:d1:46:cd:43:
+                    7b:ff:24:96:0a:dd:d7:d8:b7:58:8e:6a:a1:eb:2a:
+                    ba:40:0a:f6:d1:53:7c:84:06:fc:14:1c:d5:33:79:
+                    88:bb:4f:fa:b5:87:35:61:0d:b0:7b:07:bb:74:7c:
+                    30:a7:a3:60:7d:76:a6:d1:46:2b:84:a2:9a:28:61:
+                    f2:89
+                Q:   
+                    00:bf:87:b6:dd:a6:62:0f:88:a2:44:a5:99:ac:b9:
+                    12:82:05:7b:2e:af
+                G:   
+                    00:86:37:bd:1d:60:12:25:f5:01:7f:7e:e0:e7:de:
+                    26:f4:3d:d4:75:fe:91:41:41:b3:c6:70:7f:71:c6:
+                    5e:4e:c1:0f:3e:cc:be:9c:0b:df:b4:8f:6e:2a:0f:
+                    90:5b:20:14:75:c7:31:13:e2:d8:73:73:76:b6:c4:
+                    f5:5f:ac:b4:2a:26:4e:8c:af:87:2e:f5:1d:78:69:
+                    15:b5:b4:b7:d3:52:ec:f4:c8:6e:c5:65:bd:88:e5:
+                    c4:da:0c:48:ac:d3:2d:a2:da:b0:72:75:09:1d:aa:
+                    d9:64:80:b7:18:31:54:07:d6:7a:8b:f3:be:b7:22:
+                    87:1c:3a:c7:2f:a9:4b:8d:79:06:a1:ff:1c:db:f3:
+                    17:9b:32:a0:61:20:6e:37:92:eb:27:a1:6f:b8:22:
+                    0e:26:4d:71:9a:b3:a0:9a:fb:fb:91:68:5b:52:3b:
+                    20:75:d5:36:a6:aa:c3:dc:52:01:87:06:58:68:62:
+                    20:b8:aa:bd:2b:c9:58:60:b7:02:2e:c4:4f:bf:ec:
+                    b7:43:13:3f:90:51:65:65:a9:ba:48:74:9e:3c:ad:
+                    93:b6:00:3f:93:11:e7:cd:ea:5f:11:44:b2:4f:d1:
+                    e3:fd:19:a8:bc:4a:c6:ae:4c:ec:83:85:fa:98:ed:
+                    0b:a3:8f:a0:35:38:d4:9f:96:fd:f3:b2:b5:80:d5:
+                    1e:a4
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                94:A7:CC:B9:AB:D7:48:81:B3:3A:71:6E:2B:F4:24:FE:2A:A4:C0:39
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        30:75:fb:1e:e2:d0:ff:18:3a:de:7d:49:8a:20:33:bc:0e:0c:
+        ad:7a:68:f8:57:91:3a:bd:2b:07:a7:25:a6:c6:d0:f7:30:57:
+        73:a3:34:af:ee:d3:5d:06:9f:80:f5:41:b7:7f:e8:0e:e2:28:
+        6c:a5:d7:82:9b:81:89:85:9f:47:5d:af:17:ab:f6:e1:02:4c:
+        01:2b:07:7c:2b:e1:77:1c:a4:e9:a6:89:97:50:49:87:73:04:
+        6e:32:50:f5:b7:be:f2:60:b3:9c:5f:b4:2a:d2:2f:c0:0b:82:
+        47:71:70:62:cc:98:ad:47:20:58:61:d6:c0:c5:30:65:3f:97:
+        43:47:50:cb:90:4c:c3:7c:50:c4:28:27:b7:2d:c8:2a:61:40:
+        18:7e:fa:ce:03:39:20:f9:96:a2:da:1c:fe:5e:c7:9f:f1:bc:
+        98:18:c1:63:e6:f6:35:35:d8:5d:18:2e:ef:87:7d:af:00:a3:
+        bc:12:18:c3:11:1e:8a:6d:bf:5d:10:87:6f:79:f3:8f:11:9d:
+        cb:0d:fe:f6:fe:4f:d0:2b:de:8e:3a:da:f3:46:11:ca:12:bb:
+        ca:22:67:05:45:e6:fd:9f:71:09:98:0b:1e:cf:51:73:b2:ad:
+        48:f9:06:2a:b5:5c:9f:f3:97:e0:8e:a3:df:57:1c:a7:94:ca:
+        f2:97:8e:56
+-----BEGIN CERTIFICATE-----
+MIIGoTCCBYmgAwIBAgIEIAkFJzANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDMxWhcN
+NDkwNTI1MjE0NDMxWjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEGRzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggM7MIICLgYHKoZIzjgEATCCAiECggEBAI9a
+gDRT4VJojM+b1XoBYFdj+fgBVZ5VF3/0zM3X+/ceNgAcrlxw6Bsz77iNqmkqZvBI
+/bslgutWvqzKSW5/F/07YVenFMHrmV1rggPbHBgqJQUZ7DS4wxssaYk3e4WbwKk5
+hEPxYAuRUOC1kzytHLgzTpsA7c1gWZtXBHvA+y1JRePOwIqqTQc6Q6M9BnBm/J+y
+j9bFH6V7ADapQl5Q2zg0jErG9jpYmqZXk/dOVYtG8LAbnKDL/FeRvm1HVqnRRs1D
+e/8klgrd19i3WI5qoesqukAK9tFTfIQG/BQc1TN5iLtP+rWHNWENsHsHu3R8MKej
+YH12ptFGK4Simihh8okCFQC/h7bdpmIPiKJEpZmsuRKCBXsurwKCAQEAhje9HWAS
+JfUBf37g594m9D3Udf6RQUGzxnB/ccZeTsEPPsy+nAvftI9uKg+QWyAUdccxE+LY
+c3N2tsT1X6y0KiZOjK+HLvUdeGkVtbS301Ls9MhuxWW9iOXE2gxIrNMtotqwcnUJ
+HarZZIC3GDFUB9Z6i/O+tyKHHDrHL6lLjXkGof8c2/MXmzKgYSBuN5LrJ6FvuCIO
+Jk1xmrOgmvv7kWhbUjsgddU2pqrD3FIBhwZYaGIguKq9K8lYYLcCLsRPv+y3QxM/
+kFFlZam6SHSePK2TtgA/kxHnzepfEUSyT9Hj/RmovErGrkzsg4X6mO0Lo4+gNTjU
+n5b987K1gNUepAOCAQUAAoIBAHqpZft2ur7z+pRZUu1O/ORwXo98FOdz1tI2a2LS
+VsluepFjck6pzi7rOF7EcvYsUqpR9M47KFU5w61dUvqsDDJI/ACfw9l1CY2C4MsH
+ZSklejQuu6AtMJFZDs6C+y2tpbK5K+xrsQQHDFIWfWwMsmTHxsurGKum+j4x849J
+dTNp0yoq5yw4tdZ9M5S6pj4v5TvMSifRWfOccbFGZD8o8TPRvMKLR5Itxh/7IzRW
+8W4YjnwLdUKKu5JEBFhB0Ztu1hSYlD13jZPTH+l7p3GUEO7p01pKuJFhNUwAdvKy
+Or2fQvnwjtq9jGD9fWWFmMV9Qrkn3gkKHIWnY+VxPKt43s+jgeswgegwHQYDVR0O
+BBYEFJSnzLmr10iBszpxbiv0JP4qpMA5MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2u
+wgcwLgCsWGObIH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMx
+GDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21t
+b25zLXNzbDENMAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2
+aWVzQGdtYWlsLmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
+A4IBAQAwdfse4tD/GDrefUmKIDO8Dgytemj4V5E6vSsHpyWmxtD3MFdzozSv7tNd
+Bp+A9UG3f+gO4ihspdeCm4GJhZ9HXa8Xq/bhAkwBKwd8K+F3HKTppomXUEmHcwRu
+MlD1t77yYLOcX7Qq0i/AC4JHcXBizJitRyBYYdbAxTBlP5dDR1DLkEzDfFDEKCe3
+LcgqYUAYfvrOAzkg+Zai2hz+Xsef8byYGMFj5vY1NdhdGC7vh32vAKO8EhjDER6K
+bb9dEIdvefOPEZ3LDf72/k/QK96OOtrzRhHKErvKImcFReb9n3EJmAsez1Fzsq1I
++QYqtVyf85fgjqPfVxynlMryl45W
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:28 2009 GMT
+            Not After : May 25 21:44:28 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:b9:db:04:16:8c:41:eb:91:c4:b8:d1:1a:73:28:
+                    59:09:b8:7a:b5:05:40:db:4f:2b:63:7b:bf:01:70:
+                    e1:0d:4c:09:3a:3b:63:9e:22:13:fa:55:d1:bc:e8:
+                    dd:31:71:df:0d:a6:0b:29:29:cc:da:bd:69:5c:cb:
+                    29:7e:6c:8c:93:82:c7:8b:00:ea:0b:8c:35:5c:fe:
+                    28:12:cf:ba:11:24:48:bc:0a:ee:37:54:a3:f2:9b:
+                    f2:76:94:7d:56:c0:52:35:f0:ff:c8:8c:08:7e:b0:
+                    49:c5:2f:fd:41:92:06:e8:c2:71:0d:f6:70:e5:93:
+                    89:80:a2:13:43:ac:53:56:ba:1a:44:44:98:cd:ba:
+                    f9:3a:93:20:71:34:93:0f:3f:34:34:2e:53:b2:d7:
+                    4a:22:3e:89:0a:c3:6e:12:40:ba:f3:22:6d:38:63:
+                    3b:f0:ef:42:2b:2d:f4:d2:f8:a9:76:ce:13:37:ce:
+                    1a:a4:bd:42:a0:7b:71:df:0e:3f:93:10:9d:22:0a:
+                    8b:61:92:c6:4c:fe:e7:bf:56:f4:5c:d3:85:98:92:
+                    a2:dc:d1:3d:f8:6e:3e:ac:e1:87:2f:e1:fb:30:d5:
+                    3d:24:fc:d9:d1:ac:b9:ca:9c:41:ff:60:aa:e4:57:
+                    7e:b1:93:ac:4f:64:b5:0a:d3:57:4e:12:68:5b:18:
+                    d2:15
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        9a:29:28:5e:4f:4f:59:f8:6b:b0:96:bf:ef:69:02:36:d1:72:
+        af:a2:f3:c0:7d:c1:50:5a:b8:63:61:18:1a:d4:4d:8f:a4:b2:
+        18:5d:1b:75:1d:b6:ce:e6:aa:b3:c1:16:ab:dd:64:ac:be:62:
+        7f:77:1d:d4:6a:eb:5d:f7:19:eb:6a:6a:60:6d:ca:d6:2a:4d:
+        ee:c9:5b:1e:05:eb:bb:3f:5f:a4:76:ae:fd:32:ac:1e:63:e7:
+        35:d3:95:1d:c9:bc:7a:2f:e7:0e:04:95:59:4d:30:51:ac:67:
+        65:41:74:b3:62:f6:4d:85:4b:88:26:15:c2:2d:03:69:16:f7:
+        6a:8a:5c:ca:ca:7b:ba:41:f9:7b:f4:ae:f8:29:56:48:9d:86:
+        2e:0a:06:7a:21:97:01:b3:d4:45:5a:14:05:d3:b1:3a:da:0a:
+        67:6d:d5:45:db:ba:88:09:4b:53:b3:69:1a:52:de:57:03:89:
+        fa:99:82:1d:79:fb:ae:55:d7:13:fd:5e:99:25:cb:75:a1:62:
+        b4:27:f0:54:4b:78:42:8b:54:63:62:f4:a3:0b:e2:26:a4:0c:
+        29:ae:49:b4:1a:34:e6:a4:07:8a:64:cb:63:46:ae:fa:ec:d0:
+        f4:e1:e2:25:11:57:27:61:e8:d1:48:ad:60:13:2d:b9:38:a3:
+        52:03:0f:ad
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
diff --git a/samples/ca/test-rsa-cert.pem b/samples/ca/test-rsa-cert.pem
new file mode 100644
index 0000000..e4fa2f0
--- /dev/null
+++ b/samples/ca/test-rsa-cert.pem
@@ -0,0 +1,83 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=rsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=test/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:c8:63:af:96:82:3e:8c:a9:d1:1d:62:ae:85:80:
+                    7e:71:32:04:c1:98:5a:80:a2:74:7f:7a:c8:63:c5:
+                    8d:82:e8:c1:ec:f9:69:82:98:d4:83:8a:4d:8d:81:
+                    95:88:68:e0:ef:38:5f:6e:38:42:b6:53:46:5f:24:
+                    41:b6:2d:c6:71:a1:e2:04:82:0f:e6:7c:82:36:7f:
+                    80:cb:cb:52:58:6a:39:bf:96:5c:f0:14:1c:c0:77:
+                    f4:64:72:cd:ea:c0:fd:9b:6b:95:4a:9f:fa:52:a8:
+                    d2:e5:9c:a1:cc:5e:45:ce:fb:d4:a3:7c:70:f1:f7:
+                    9c:76:74:ad:5d:07:c7:86:40:67:2e:94:e3:1c:4e:
+                    6d:ee:2b:b5:25:58:d3:b8:4d:29:70:1b:da:87:67:
+                    56:a8:33:71:88:83:90:b5:7c:8a:5b:c4:9a:83:56:
+                    31:6a:e9:f1:40:6a:91:37:29:12:16:21:09:8a:77:
+                    71:39:20:27:03:12:ba:ab:fc:06:a9:c6:77:ce:f1:
+                    41:4d:c5:55:92:38:b5:bb:64:07:e2:b3:8c:3f:73:
+                    cf:c4:02:0c:90:1f:0e:36:47:47:4d:ca:35:0e:66:
+                    c4:e8:17:c3:1c:0a:c3:a9:46:31:a8:95:25:3c:69:
+                    4c:aa:b2:9b:dd:f0:85:89:3d:de:5d:e8:70:47:b9:
+                    e5:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                9F:14:77:BF:3F:3A:B6:CA:38:82:42:48:16:2C:DA:D0:CB:5E:87:D8
+            X509v3 Authority Key Identifier: 
+                keyid:2E:F4:CD:A1:B4:AD:03:85:D8:AF:69:97:D5:2D:95:40:D6:BF:12:BF
+
+    Signature Algorithm: sha1WithRSAEncryption
+        02:ea:45:04:9c:7b:79:4b:bc:24:7d:b4:5a:43:fa:cc:06:48:
+        d3:60:3f:a0:04:bc:42:ef:01:cc:0d:75:64:85:0a:86:37:e7:
+        14:09:29:92:f0:e0:c1:d4:e5:c1:6b:82:82:74:74:74:ae:68:
+        ac:0d:08:d3:95:e4:aa:3b:6a:a7:fd:f6:ea:f1:de:7b:4d:7b:
+        70:f8:a4:b1:21:a3:b2:e6:b1:5a:85:ca:c5:47:4b:c3:35:23:
+        3d:cd:f3:f8:fa:07:35:7d:df:a9:7e:a5:11:86:83:8f:06:13:
+        b5:93:73:78:ab:35:90:0d:a1:7d:8a:11:e7:55:d8:15:bd:bd:
+        54:e0:ae:6a:77:1a:13:ea:4c:23:11:64:d2:2f:2c:e1:04:2c:
+        05:b4:c7:25:73:6d:3b:69:be:94:16:6d:28:00:bc:67:48:f8:
+        1e:dd:1d:63:4c:6b:9f:85:e4:bb:10:ff:bf:b6:f2:2c:c8:53:
+        3c:23:b6:55:85:fd:68:95:27:93:ff:34:d7:29:7b:18:19:4b:
+        77:88:e8:75:a5:ba:2c:d6:64:f7:25:2e:fa:af:14:63:95:1b:
+        d1:77:3c:bc:0c:13:5f:37:5a:06:b7:92:22:ed:a0:d1:6c:b1:
+        e7:3f:af:95:c1:8a:7f:47:46:a0:74:ad:35:d0:52:59:31:b5:
+        2b:3c:fe:3d
+-----BEGIN CERTIFICATE-----
+MIIEFzCCAv+gAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlh
+dGUxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkw
+NTI1MjE0NDMxWhcNNDkwNTI1MjE0NDMxWjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNV
+BAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15
+ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHRlc3QxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDIY6+Wgj6MqdEdYq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2N
+gZWIaODvOF9uOEK2U0ZfJEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rk
+cs3qwP2ba5VKn/pSqNLlnKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7Ul
+WNO4TSlwG9qHZ1aoM3GIg5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr
+/AapxnfO8UFNxVWSOLW7ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGo
+lSU8aUyqspvd8IWJPd5d6HBHueXNAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSfFHe/Pzq2yjiCQkgWLNrQy16H2DAfBgNVHSMEGDAWgBQu9M2htK0DhdivaZfV
+LZVA1r8SvzANBgkqhkiG9w0BAQUFAAOCAQEAAupFBJx7eUu8JH20WkP6zAZI02A/
+oAS8Qu8BzA11ZIUKhjfnFAkpkvDgwdTlwWuCgnR0dK5orA0I05Xkqjtqp/326vHe
+e017cPiksSGjsuaxWoXKxUdLwzUjPc3z+PoHNX3fqX6lEYaDjwYTtZNzeKs1kA2h
+fYoR51XYFb29VOCuancaE+pMIxFk0i8s4QQsBbTHJXNtO2m+lBZtKAC8Z0j4Ht0d
+Y0xrn4XkuxD/v7byLMhTPCO2VYX9aJUnk/801yl7GBlLd4jodaW6LNZk9yUu+q8U
+Y5Ub0Xc8vAwTXzdaBreSIu2g0Wyx5z+vlcGKf0dGoHStNdBSWTG1Kzz+PQ==
+-----END CERTIFICATE-----
diff --git a/samples/ca/test-rsa-chain.pem b/samples/ca/test-rsa-chain.pem
new file mode 100644
index 0000000..2326bcf
--- /dev/null
+++ b/samples/ca/test-rsa-chain.pem
@@ -0,0 +1,254 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=rsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=test/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:c8:63:af:96:82:3e:8c:a9:d1:1d:62:ae:85:80:
+                    7e:71:32:04:c1:98:5a:80:a2:74:7f:7a:c8:63:c5:
+                    8d:82:e8:c1:ec:f9:69:82:98:d4:83:8a:4d:8d:81:
+                    95:88:68:e0:ef:38:5f:6e:38:42:b6:53:46:5f:24:
+                    41:b6:2d:c6:71:a1:e2:04:82:0f:e6:7c:82:36:7f:
+                    80:cb:cb:52:58:6a:39:bf:96:5c:f0:14:1c:c0:77:
+                    f4:64:72:cd:ea:c0:fd:9b:6b:95:4a:9f:fa:52:a8:
+                    d2:e5:9c:a1:cc:5e:45:ce:fb:d4:a3:7c:70:f1:f7:
+                    9c:76:74:ad:5d:07:c7:86:40:67:2e:94:e3:1c:4e:
+                    6d:ee:2b:b5:25:58:d3:b8:4d:29:70:1b:da:87:67:
+                    56:a8:33:71:88:83:90:b5:7c:8a:5b:c4:9a:83:56:
+                    31:6a:e9:f1:40:6a:91:37:29:12:16:21:09:8a:77:
+                    71:39:20:27:03:12:ba:ab:fc:06:a9:c6:77:ce:f1:
+                    41:4d:c5:55:92:38:b5:bb:64:07:e2:b3:8c:3f:73:
+                    cf:c4:02:0c:90:1f:0e:36:47:47:4d:ca:35:0e:66:
+                    c4:e8:17:c3:1c:0a:c3:a9:46:31:a8:95:25:3c:69:
+                    4c:aa:b2:9b:dd:f0:85:89:3d:de:5d:e8:70:47:b9:
+                    e5:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                9F:14:77:BF:3F:3A:B6:CA:38:82:42:48:16:2C:DA:D0:CB:5E:87:D8
+            X509v3 Authority Key Identifier: 
+                keyid:2E:F4:CD:A1:B4:AD:03:85:D8:AF:69:97:D5:2D:95:40:D6:BF:12:BF
+
+    Signature Algorithm: sha1WithRSAEncryption
+        02:ea:45:04:9c:7b:79:4b:bc:24:7d:b4:5a:43:fa:cc:06:48:
+        d3:60:3f:a0:04:bc:42:ef:01:cc:0d:75:64:85:0a:86:37:e7:
+        14:09:29:92:f0:e0:c1:d4:e5:c1:6b:82:82:74:74:74:ae:68:
+        ac:0d:08:d3:95:e4:aa:3b:6a:a7:fd:f6:ea:f1:de:7b:4d:7b:
+        70:f8:a4:b1:21:a3:b2:e6:b1:5a:85:ca:c5:47:4b:c3:35:23:
+        3d:cd:f3:f8:fa:07:35:7d:df:a9:7e:a5:11:86:83:8f:06:13:
+        b5:93:73:78:ab:35:90:0d:a1:7d:8a:11:e7:55:d8:15:bd:bd:
+        54:e0:ae:6a:77:1a:13:ea:4c:23:11:64:d2:2f:2c:e1:04:2c:
+        05:b4:c7:25:73:6d:3b:69:be:94:16:6d:28:00:bc:67:48:f8:
+        1e:dd:1d:63:4c:6b:9f:85:e4:bb:10:ff:bf:b6:f2:2c:c8:53:
+        3c:23:b6:55:85:fd:68:95:27:93:ff:34:d7:29:7b:18:19:4b:
+        77:88:e8:75:a5:ba:2c:d6:64:f7:25:2e:fa:af:14:63:95:1b:
+        d1:77:3c:bc:0c:13:5f:37:5a:06:b7:92:22:ed:a0:d1:6c:b1:
+        e7:3f:af:95:c1:8a:7f:47:46:a0:74:ad:35:d0:52:59:31:b5:
+        2b:3c:fe:3d
+-----BEGIN CERTIFICATE-----
+MIIEFzCCAv+gAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlh
+dGUxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkw
+NTI1MjE0NDMxWhcNNDkwNTI1MjE0NDMxWjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNV
+BAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15
+ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHRlc3QxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDIY6+Wgj6MqdEdYq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2N
+gZWIaODvOF9uOEK2U0ZfJEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rk
+cs3qwP2ba5VKn/pSqNLlnKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7Ul
+WNO4TSlwG9qHZ1aoM3GIg5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr
+/AapxnfO8UFNxVWSOLW7ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGo
+lSU8aUyqspvd8IWJPd5d6HBHueXNAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSfFHe/Pzq2yjiCQkgWLNrQy16H2DAfBgNVHSMEGDAWgBQu9M2htK0DhdivaZfV
+LZVA1r8SvzANBgkqhkiG9w0BAQUFAAOCAQEAAupFBJx7eUu8JH20WkP6zAZI02A/
+oAS8Qu8BzA11ZIUKhjfnFAkpkvDgwdTlwWuCgnR0dK5orA0I05Xkqjtqp/326vHe
+e017cPiksSGjsuaxWoXKxUdLwzUjPc3z+PoHNX3fqX6lEYaDjwYTtZNzeKs1kA2h
+fYoR51XYFb29VOCuancaE+pMIxFk0i8s4QQsBbTHJXNtO2m+lBZtKAC8Z0j4Ht0d
+Y0xrn4XkuxD/v7byLMhTPCO2VYX9aJUnk/801yl7GBlLd4jodaW6LNZk9yUu+q8U
+Y5Ub0Xc8vAwTXzdaBreSIu2g0Wyx5z+vlcGKf0dGoHStNdBSWTG1Kzz+PQ==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462054 (0x20090526)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:29 2009 GMT
+            Not After : May 25 21:44:29 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=rsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:ce:1b:db:73:49:85:a4:3c:42:14:84:6a:7d:47:
+                    78:d2:e1:58:27:ed:e4:78:5e:5d:2b:ee:c3:29:c5:
+                    a2:d2:6f:f3:0e:0a:d6:d6:7f:5a:f7:30:6f:c9:8f:
+                    ad:fe:53:22:46:aa:5e:0b:f6:e8:21:f3:dc:5f:75:
+                    9b:55:c5:07:ab:75:54:fd:9b:2e:31:da:12:45:3c:
+                    7b:1e:27:f6:a1:5b:5d:ac:0a:b4:e8:dd:d3:ba:ff:
+                    af:f1:43:31:4c:5b:5e:73:d4:a8:ce:93:b9:f1:9d:
+                    8b:17:1f:16:74:4f:9a:07:80:7c:1a:41:a6:49:21:
+                    2a:a8:83:75:18:3d:ed:17:8b:8b:b4:f8:46:d3:28:
+                    25:35:e1:17:df:e6:b4:f7:87:a7:71:0f:a0:b5:22:
+                    4d:48:35:2c:a3:dc:fc:58:33:76:fb:07:cf:fb:64:
+                    e9:fa:05:a8:be:63:eb:32:48:01:10:fd:44:a2:79:
+                    72:5d:33:62:1b:ad:f4:60:3f:7d:59:9c:07:cf:9c:
+                    b1:b5:e7:18:84:5e:ec:e0:78:6c:53:f0:cf:67:8d:
+                    91:95:73:72:de:70:c7:ca:ea:27:6f:d2:61:c8:7d:
+                    a5:28:28:61:c8:c9:e9:6b:7e:ae:07:9d:36:87:04:
+                    a4:97:1c:1d:f5:39:cb:b2:8a:32:8d:25:68:05:2d:
+                    86:65
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                2E:F4:CD:A1:B4:AD:03:85:D8:AF:69:97:D5:2D:95:40:D6:BF:12:BF
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        03:b6:83:af:6c:ff:2b:21:12:b9:8a:cd:8e:2f:d9:1a:28:88:
+        0c:9f:f1:6b:73:fb:76:3f:70:d8:cd:ce:5a:f6:0f:08:6a:0a:
+        a3:f7:ad:b2:72:19:eb:0e:9c:36:bb:a4:fb:3f:90:78:ba:45:
+        ee:da:c9:8e:a0:ef:b3:ac:05:4c:f4:b4:37:18:0d:bb:20:5d:
+        f4:e7:b3:77:ea:56:0c:ad:81:42:80:04:92:ca:3b:73:ed:35:
+        d5:35:f6:9f:95:a2:2d:81:4d:e6:3a:3c:13:64:f1:0f:36:7e:
+        90:c2:a0:37:c6:19:9e:13:47:92:a3:e8:18:3d:f4:d8:a0:83:
+        80:0f:7b:a7:57:9c:60:6c:6a:3e:d4:1d:cc:5e:8c:13:7f:1c:
+        d7:f6:df:ad:ae:0a:95:12:f1:71:c2:70:98:d1:2f:6c:f0:24:
+        43:b4:7e:a4:e4:31:d4:bc:50:90:03:4b:34:ba:a3:d0:fd:f5:
+        01:17:eb:11:83:44:86:65:17:bf:89:00:c7:93:d6:70:7e:0b:
+        4b:93:dc:f9:92:50:4c:3e:11:23:c5:50:1c:49:bd:8c:0c:2c:
+        60:1c:d8:e6:5f:a4:fa:21:db:8c:62:bf:74:a3:83:1c:8d:cc:
+        8e:34:8c:16:1c:c6:71:63:89:c2:c4:45:0c:90:71:98:68:2f:
+        9d:a7:87:f7
+-----BEGIN CERTIFICATE-----
+MIIEiDCCA3CgAwIBAgIEIAkFJjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI5WhcN
+NDkwNTI1MjE0NDI5WjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDOG9tzSYWkPEIUhGp9R3jS4Vgn7eR4Xl0r7sMpxaLSb/MOCtbWf1r3MG/J
+j63+UyJGql4L9ugh89xfdZtVxQerdVT9my4x2hJFPHseJ/ahW12sCrTo3dO6/6/x
+QzFMW15z1KjOk7nxnYsXHxZ0T5oHgHwaQaZJISqog3UYPe0Xi4u0+EbTKCU14Rff
+5rT3h6dxD6C1Ik1INSyj3PxYM3b7B8/7ZOn6Bai+Y+sySAEQ/USieXJdM2IbrfRg
+P31ZnAfPnLG15xiEXuzgeGxT8M9njZGVc3LecMfK6idv0mHIfaUoKGHIyelrfq4H
+nTaHBKSXHB31OcuyijKNJWgFLYZlAgMBAAGjgeswgegwHQYDVR0OBBYEFC70zaG0
+rQOF2K9pl9UtlUDWvxK/MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGOb
+IH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoT
+D2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDEN
+MAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWls
+LmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQADtoOv
+bP8rIRK5is2OL9kaKIgMn/Frc/t2P3DYzc5a9g8Iagqj962ychnrDpw2u6T7P5B4
+ukXu2smOoO+zrAVM9LQ3GA27IF3057N36lYMrYFCgASSyjtz7TXVNfaflaItgU3m
+OjwTZPEPNn6QwqA3xhmeE0eSo+gYPfTYoIOAD3unV5xgbGo+1B3MXowTfxzX9t+t
+rgqVEvFxwnCY0S9s8CRDtH6k5DHUvFCQA0s0uqPQ/fUBF+sRg0SGZRe/iQDHk9Zw
+fgtLk9z5klBMPhEjxVAcSb2MDCxgHNjmX6T6IduMYr90o4McjcyONIwWHMZxY4nC
+xEUMkHGYaC+dp4f3
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:28 2009 GMT
+            Not After : May 25 21:44:28 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:b9:db:04:16:8c:41:eb:91:c4:b8:d1:1a:73:28:
+                    59:09:b8:7a:b5:05:40:db:4f:2b:63:7b:bf:01:70:
+                    e1:0d:4c:09:3a:3b:63:9e:22:13:fa:55:d1:bc:e8:
+                    dd:31:71:df:0d:a6:0b:29:29:cc:da:bd:69:5c:cb:
+                    29:7e:6c:8c:93:82:c7:8b:00:ea:0b:8c:35:5c:fe:
+                    28:12:cf:ba:11:24:48:bc:0a:ee:37:54:a3:f2:9b:
+                    f2:76:94:7d:56:c0:52:35:f0:ff:c8:8c:08:7e:b0:
+                    49:c5:2f:fd:41:92:06:e8:c2:71:0d:f6:70:e5:93:
+                    89:80:a2:13:43:ac:53:56:ba:1a:44:44:98:cd:ba:
+                    f9:3a:93:20:71:34:93:0f:3f:34:34:2e:53:b2:d7:
+                    4a:22:3e:89:0a:c3:6e:12:40:ba:f3:22:6d:38:63:
+                    3b:f0:ef:42:2b:2d:f4:d2:f8:a9:76:ce:13:37:ce:
+                    1a:a4:bd:42:a0:7b:71:df:0e:3f:93:10:9d:22:0a:
+                    8b:61:92:c6:4c:fe:e7:bf:56:f4:5c:d3:85:98:92:
+                    a2:dc:d1:3d:f8:6e:3e:ac:e1:87:2f:e1:fb:30:d5:
+                    3d:24:fc:d9:d1:ac:b9:ca:9c:41:ff:60:aa:e4:57:
+                    7e:b1:93:ac:4f:64:b5:0a:d3:57:4e:12:68:5b:18:
+                    d2:15
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        9a:29:28:5e:4f:4f:59:f8:6b:b0:96:bf:ef:69:02:36:d1:72:
+        af:a2:f3:c0:7d:c1:50:5a:b8:63:61:18:1a:d4:4d:8f:a4:b2:
+        18:5d:1b:75:1d:b6:ce:e6:aa:b3:c1:16:ab:dd:64:ac:be:62:
+        7f:77:1d:d4:6a:eb:5d:f7:19:eb:6a:6a:60:6d:ca:d6:2a:4d:
+        ee:c9:5b:1e:05:eb:bb:3f:5f:a4:76:ae:fd:32:ac:1e:63:e7:
+        35:d3:95:1d:c9:bc:7a:2f:e7:0e:04:95:59:4d:30:51:ac:67:
+        65:41:74:b3:62:f6:4d:85:4b:88:26:15:c2:2d:03:69:16:f7:
+        6a:8a:5c:ca:ca:7b:ba:41:f9:7b:f4:ae:f8:29:56:48:9d:86:
+        2e:0a:06:7a:21:97:01:b3:d4:45:5a:14:05:d3:b1:3a:da:0a:
+        67:6d:d5:45:db:ba:88:09:4b:53:b3:69:1a:52:de:57:03:89:
+        fa:99:82:1d:79:fb:ae:55:d7:13:fd:5e:99:25:cb:75:a1:62:
+        b4:27:f0:54:4b:78:42:8b:54:63:62:f4:a3:0b:e2:26:a4:0c:
+        29:ae:49:b4:1a:34:e6:a4:07:8a:64:cb:63:46:ae:fa:ec:d0:
+        f4:e1:e2:25:11:57:27:61:e8:d1:48:ad:60:13:2d:b9:38:a3:
+        52:03:0f:ad
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
diff --git a/samples/cacerts-with-78-entries-and-one-private-key.jks b/samples/cacerts-with-78-entries-and-one-private-key.jks
new file mode 100644
index 0000000..d0648ec
Binary files /dev/null and b/samples/cacerts-with-78-entries-and-one-private-key.jks differ
diff --git a/samples/cacerts-with-78-entries.jks b/samples/cacerts-with-78-entries.jks
new file mode 100644
index 0000000..4492a7d
Binary files /dev/null and b/samples/cacerts-with-78-entries.jks differ
diff --git a/samples/dsa.html b/samples/dsa.html
index 6851348..1719aa3 100644
--- a/samples/dsa.html
+++ b/samples/dsa.html
@@ -1,114 +1,115 @@
 <pre>
-java -showversion -cp <a href="../download.html">build/not-yet-commons-ssl-0.3.7.jar</a>  org.apache.commons.ssl.PKCS8Key <a href="dsa/">samples/dsa/*.*</a>
+java -showversion -cp build/not-yet-commons-ssl-0.3.13.jar  org.apache.commons.ssl.PKCS8Key samples/dsa/*.*
 
-java version "1.6.0"
-Java(TM) SE Runtime Environment (build 1.6.0-b105)
-Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
+java version "1.6.0_45"
+Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
+Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
 
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	128	<a href="dsa/openssl_dsa_aes128_cbc.pem">samples/dsa/openssl_dsa_aes128_cbc.pem</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	128	<a href="dsa/openssl_dsa_aes128_cfb.pem">samples/dsa/openssl_dsa_aes128_cfb.pem</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	128	<a href="dsa/openssl_dsa_aes128_ecb.pem">samples/dsa/openssl_dsa_aes128_ecb.pem</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	128	<a href="dsa/openssl_dsa_aes128_ofb.pem">samples/dsa/openssl_dsa_aes128_ofb.pem</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	192	<a href="dsa/openssl_dsa_aes192_cbc.pem">samples/dsa/openssl_dsa_aes192_cbc.pem</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	192	<a href="dsa/openssl_dsa_aes192_cfb.pem">samples/dsa/openssl_dsa_aes192_cfb.pem</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	192	<a href="dsa/openssl_dsa_aes192_ecb.pem">samples/dsa/openssl_dsa_aes192_ecb.pem</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	192	<a href="dsa/openssl_dsa_aes192_ofb.pem">samples/dsa/openssl_dsa_aes192_ofb.pem</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	256	<a href="dsa/openssl_dsa_aes256_cbc.pem">samples/dsa/openssl_dsa_aes256_cbc.pem</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	256	<a href="dsa/openssl_dsa_aes256_cfb.pem">samples/dsa/openssl_dsa_aes256_cfb.pem</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	256	<a href="dsa/openssl_dsa_aes256_ecb.pem">samples/dsa/openssl_dsa_aes256_ecb.pem</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	256	<a href="dsa/openssl_dsa_aes256_ofb.pem">samples/dsa/openssl_dsa_aes256_ofb.pem</a>
-   SUCCESS    	DSA	Blowfish/CBC/PKCS5Padding	128	<a href="dsa/openssl_dsa_blowfish_cbc.pem">samples/dsa/openssl_dsa_blowfish_cbc.pem</a>
-   SUCCESS    	DSA	Blowfish/CFB/NoPadding   	128	<a href="dsa/openssl_dsa_blowfish_cfb.pem">samples/dsa/openssl_dsa_blowfish_cfb.pem</a>
-   SUCCESS    	DSA	Blowfish/ECB/PKCS5Padding	128	<a href="dsa/openssl_dsa_blowfish_ecb.pem">samples/dsa/openssl_dsa_blowfish_ecb.pem</a>
-   SUCCESS    	DSA	Blowfish/OFB/NoPadding   	128	<a href="dsa/openssl_dsa_blowfish_ofb.pem">samples/dsa/openssl_dsa_blowfish_ofb.pem</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/openssl_dsa_des1_cbc.pem">samples/dsa/openssl_dsa_des1_cbc.pem</a>
-   SUCCESS    	DSA	DES/CFB/NoPadding        	 64	<a href="dsa/openssl_dsa_des1_cfb.pem">samples/dsa/openssl_dsa_des1_cfb.pem</a>
-   SUCCESS    	DSA	DES/ECB/PKCS5Padding     	 64	<a href="dsa/openssl_dsa_des1_ecb.pem">samples/dsa/openssl_dsa_des1_ecb.pem</a>
-   SUCCESS    	DSA	DES/OFB/NoPadding        	 64	<a href="dsa/openssl_dsa_des1_ofb.pem">samples/dsa/openssl_dsa_des1_ofb.pem</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/openssl_dsa_des2_cbc.pem">samples/dsa/openssl_dsa_des2_cbc.pem</a>
-   SUCCESS    	DSA	DESede/CFB/NoPadding     	192	<a href="dsa/openssl_dsa_des2_cfb.pem">samples/dsa/openssl_dsa_des2_cfb.pem</a>
-   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	<a href="dsa/openssl_dsa_des2_ecb.pem">samples/dsa/openssl_dsa_des2_ecb.pem</a>
-   SUCCESS    	DSA	DESede/OFB/NoPadding     	192	<a href="dsa/openssl_dsa_des2_ofb.pem">samples/dsa/openssl_dsa_des2_ofb.pem</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/openssl_dsa_des3_cbc.pem">samples/dsa/openssl_dsa_des3_cbc.pem</a>
-   SUCCESS    	DSA	DESede/CFB/NoPadding     	192	<a href="dsa/openssl_dsa_des3_cfb.pem">samples/dsa/openssl_dsa_des3_cfb.pem</a>
-   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	<a href="dsa/openssl_dsa_des3_ecb.pem">samples/dsa/openssl_dsa_des3_ecb.pem</a>
-   SUCCESS    	DSA	DESede/OFB/NoPadding     	192	<a href="dsa/openssl_dsa_des3_ofb.pem">samples/dsa/openssl_dsa_des3_ofb.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	<a href="dsa/openssl_dsa_rc2_128_cbc.pem">samples/dsa/openssl_dsa_rc2_128_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CFB/NoPadding        	128	<a href="dsa/openssl_dsa_rc2_128_cfb.pem">samples/dsa/openssl_dsa_rc2_128_cfb.pem</a>
-   SUCCESS    	DSA	RC2/ECB/PKCS5Padding     	128	<a href="dsa/openssl_dsa_rc2_128_ecb.pem">samples/dsa/openssl_dsa_rc2_128_ecb.pem</a>
-   SUCCESS    	DSA	RC2/OFB/NoPadding        	128	<a href="dsa/openssl_dsa_rc2_128_ofb.pem">samples/dsa/openssl_dsa_rc2_128_ofb.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	<a href="dsa/openssl_dsa_rc2_40_cbc.pem">samples/dsa/openssl_dsa_rc2_40_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/openssl_dsa_rc2_64_cbc.pem">samples/dsa/openssl_dsa_rc2_64_cbc.pem</a>
-   SUCCESS    	DSA	UNENCRYPTED              	  0	<a href="dsa/openssl_dsa_unencrypted.der">samples/dsa/openssl_dsa_unencrypted.der</a>
-   SUCCESS    	DSA	UNENCRYPTED              	  0	<a href="dsa/openssl_dsa_unencrypted.pem">samples/dsa/openssl_dsa_unencrypted.pem</a>
-   SUCCESS    	DSA	UNENCRYPTED              	  0	<a href="dsa/pkcs8_dsa_unencrypted.der">samples/dsa/pkcs8_dsa_unencrypted.der</a>
-   SUCCESS    	DSA	UNENCRYPTED              	  0	<a href="dsa/pkcs8_dsa_unencrypted.pem">samples/dsa/pkcs8_dsa_unencrypted.pem</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md2_des1_cbc.der">samples/dsa/pkcs8v1_dsa_md2_des1_cbc.der</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md2_des1_cbc.pem">samples/dsa/pkcs8v1_dsa_md2_des1_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md2_rc2_64_cbc.der">samples/dsa/pkcs8v1_dsa_md2_rc2_64_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md2_rc2_64_cbc.pem">samples/dsa/pkcs8v1_dsa_md2_rc2_64_cbc.pem</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md5_des1_cbc.der">samples/dsa/pkcs8v1_dsa_md5_des1_cbc.der</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md5_des1_cbc.pem">samples/dsa/pkcs8v1_dsa_md5_des1_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md5_rc2_64_cbc.der">samples/dsa/pkcs8v1_dsa_md5_rc2_64_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_md5_rc2_64_cbc.pem">samples/dsa/pkcs8v1_dsa_md5_rc2_64_cbc.pem</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_sha1_des1_cbc.der">samples/dsa/pkcs8v1_dsa_sha1_des1_cbc.der</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_sha1_des1_cbc.pem">samples/dsa/pkcs8v1_dsa_sha1_des1_cbc.pem</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/pkcs8v1_dsa_sha1_des2_cbc.der">samples/dsa/pkcs8v1_dsa_sha1_des2_cbc.der</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/pkcs8v1_dsa_sha1_des2_cbc.pem">samples/dsa/pkcs8v1_dsa_sha1_des2_cbc.pem</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/pkcs8v1_dsa_sha1_des3_cbc.der">samples/dsa/pkcs8v1_dsa_sha1_des3_cbc.der</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/pkcs8v1_dsa_sha1_des3_cbc.pem">samples/dsa/pkcs8v1_dsa_sha1_des3_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	<a href="dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.der">samples/dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	<a href="dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.pem">samples/dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	<a href="dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.der">samples/dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	<a href="dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.pem">samples/dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.der">samples/dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.pem">samples/dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.pem</a>
-   SUCCESS    	DSA	RC4                      	128	<a href="dsa/pkcs8v1_dsa_sha1_rc4_128.der">samples/dsa/pkcs8v1_dsa_sha1_rc4_128.der</a>
-   SUCCESS    	DSA	RC4                      	128	<a href="dsa/pkcs8v1_dsa_sha1_rc4_128.pem">samples/dsa/pkcs8v1_dsa_sha1_rc4_128.pem</a>
-   SUCCESS    	DSA	RC4                      	 40	<a href="dsa/pkcs8v1_dsa_sha1_rc4_40.der">samples/dsa/pkcs8v1_dsa_sha1_rc4_40.der</a>
-   SUCCESS    	DSA	RC4                      	 40	<a href="dsa/pkcs8v1_dsa_sha1_rc4_40.pem">samples/dsa/pkcs8v1_dsa_sha1_rc4_40.pem</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	128	<a href="dsa/pkcs8v2_dsa_aes128_cbc.der">samples/dsa/pkcs8v2_dsa_aes128_cbc.der</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	128	<a href="dsa/pkcs8v2_dsa_aes128_cbc.pem">samples/dsa/pkcs8v2_dsa_aes128_cbc.pem</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	128	<a href="dsa/pkcs8v2_dsa_aes128_cfb.der">samples/dsa/pkcs8v2_dsa_aes128_cfb.der</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	128	<a href="dsa/pkcs8v2_dsa_aes128_cfb.pem">samples/dsa/pkcs8v2_dsa_aes128_cfb.pem</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	128	<a href="dsa/pkcs8v2_dsa_aes128_ecb.der">samples/dsa/pkcs8v2_dsa_aes128_ecb.der</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	128	<a href="dsa/pkcs8v2_dsa_aes128_ecb.pem">samples/dsa/pkcs8v2_dsa_aes128_ecb.pem</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	128	<a href="dsa/pkcs8v2_dsa_aes128_ofb.der">samples/dsa/pkcs8v2_dsa_aes128_ofb.der</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	128	<a href="dsa/pkcs8v2_dsa_aes128_ofb.pem">samples/dsa/pkcs8v2_dsa_aes128_ofb.pem</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	192	<a href="dsa/pkcs8v2_dsa_aes192_cbc.der">samples/dsa/pkcs8v2_dsa_aes192_cbc.der</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	192	<a href="dsa/pkcs8v2_dsa_aes192_cbc.pem">samples/dsa/pkcs8v2_dsa_aes192_cbc.pem</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	192	<a href="dsa/pkcs8v2_dsa_aes192_cfb.der">samples/dsa/pkcs8v2_dsa_aes192_cfb.der</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	192	<a href="dsa/pkcs8v2_dsa_aes192_cfb.pem">samples/dsa/pkcs8v2_dsa_aes192_cfb.pem</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	192	<a href="dsa/pkcs8v2_dsa_aes192_ecb.der">samples/dsa/pkcs8v2_dsa_aes192_ecb.der</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	192	<a href="dsa/pkcs8v2_dsa_aes192_ecb.pem">samples/dsa/pkcs8v2_dsa_aes192_ecb.pem</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	192	<a href="dsa/pkcs8v2_dsa_aes192_ofb.der">samples/dsa/pkcs8v2_dsa_aes192_ofb.der</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	192	<a href="dsa/pkcs8v2_dsa_aes192_ofb.pem">samples/dsa/pkcs8v2_dsa_aes192_ofb.pem</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	256	<a href="dsa/pkcs8v2_dsa_aes256_cbc.der">samples/dsa/pkcs8v2_dsa_aes256_cbc.der</a>
-   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	256	<a href="dsa/pkcs8v2_dsa_aes256_cbc.pem">samples/dsa/pkcs8v2_dsa_aes256_cbc.pem</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	256	<a href="dsa/pkcs8v2_dsa_aes256_cfb.der">samples/dsa/pkcs8v2_dsa_aes256_cfb.der</a>
-   SUCCESS    	DSA	AES/CFB/NoPadding        	256	<a href="dsa/pkcs8v2_dsa_aes256_cfb.pem">samples/dsa/pkcs8v2_dsa_aes256_cfb.pem</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	256	<a href="dsa/pkcs8v2_dsa_aes256_ecb.der">samples/dsa/pkcs8v2_dsa_aes256_ecb.der</a>
-   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	256	<a href="dsa/pkcs8v2_dsa_aes256_ecb.pem">samples/dsa/pkcs8v2_dsa_aes256_ecb.pem</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	256	<a href="dsa/pkcs8v2_dsa_aes256_ofb.der">samples/dsa/pkcs8v2_dsa_aes256_ofb.der</a>
-   SUCCESS    	DSA	AES/OFB/NoPadding        	256	<a href="dsa/pkcs8v2_dsa_aes256_ofb.pem">samples/dsa/pkcs8v2_dsa_aes256_ofb.pem</a>
-   SUCCESS    	DSA	Blowfish/CBC/PKCS5Padding	128	<a href="dsa/pkcs8v2_dsa_blowfish_cbc.der">samples/dsa/pkcs8v2_dsa_blowfish_cbc.der</a>
-   SUCCESS    	DSA	Blowfish/CBC/PKCS5Padding	128	<a href="dsa/pkcs8v2_dsa_blowfish_cbc.pem">samples/dsa/pkcs8v2_dsa_blowfish_cbc.pem</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v2_dsa_des1_cbc.der">samples/dsa/pkcs8v2_dsa_des1_cbc.der</a>
-   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v2_dsa_des1_cbc.pem">samples/dsa/pkcs8v2_dsa_des1_cbc.pem</a>
-   SUCCESS    	DSA	DES/CFB/NoPadding        	 64	<a href="dsa/pkcs8v2_dsa_des1_cfb.der">samples/dsa/pkcs8v2_dsa_des1_cfb.der</a>
-   SUCCESS    	DSA	DES/CFB/NoPadding        	 64	<a href="dsa/pkcs8v2_dsa_des1_cfb.pem">samples/dsa/pkcs8v2_dsa_des1_cfb.pem</a>
-   SUCCESS    	DSA	DES/ECB/PKCS5Padding     	 64	<a href="dsa/pkcs8v2_dsa_des1_ecb.der">samples/dsa/pkcs8v2_dsa_des1_ecb.der</a>
-   SUCCESS    	DSA	DES/ECB/PKCS5Padding     	 64	<a href="dsa/pkcs8v2_dsa_des1_ecb.pem">samples/dsa/pkcs8v2_dsa_des1_ecb.pem</a>
-   SUCCESS    	DSA	DES/OFB/NoPadding        	 64	<a href="dsa/pkcs8v2_dsa_des1_ofb.der">samples/dsa/pkcs8v2_dsa_des1_ofb.der</a>
-   SUCCESS    	DSA	DES/OFB/NoPadding        	 64	<a href="dsa/pkcs8v2_dsa_des1_ofb.pem">samples/dsa/pkcs8v2_dsa_des1_ofb.pem</a>
-   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	<a href="dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.der">samples/dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.der</a>
-   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	<a href="dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.pem">samples/dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.pem</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/pkcs8v2_dsa_des3_cbc.der">samples/dsa/pkcs8v2_dsa_des3_cbc.der</a>
-   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	<a href="dsa/pkcs8v2_dsa_des3_cbc.pem">samples/dsa/pkcs8v2_dsa_des3_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	<a href="dsa/pkcs8v2_dsa_rc2_128_cbc.der">samples/dsa/pkcs8v2_dsa_rc2_128_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	<a href="dsa/pkcs8v2_dsa_rc2_128_cbc.pem">samples/dsa/pkcs8v2_dsa_rc2_128_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	<a href="dsa/pkcs8v2_dsa_rc2_40_cbc.der">samples/dsa/pkcs8v2_dsa_rc2_40_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	<a href="dsa/pkcs8v2_dsa_rc2_40_cbc.pem">samples/dsa/pkcs8v2_dsa_rc2_40_cbc.pem</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v2_dsa_rc2_64_cbc.der">samples/dsa/pkcs8v2_dsa_rc2_64_cbc.der</a>
-   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	<a href="dsa/pkcs8v2_dsa_rc2_64_cbc.pem">samples/dsa/pkcs8v2_dsa_rc2_64_cbc.pem</a>
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	128	samples/dsa/openssl_dsa_aes128_cbc.pem
+   SUCCESS    	DSA	AES/CFB/NoPadding        	128	samples/dsa/openssl_dsa_aes128_cfb.pem
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	128	samples/dsa/openssl_dsa_aes128_ecb.pem
+   SUCCESS    	DSA	AES/OFB/NoPadding        	128	samples/dsa/openssl_dsa_aes128_ofb.pem
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	192	samples/dsa/openssl_dsa_aes192_cbc.pem
+   SUCCESS    	DSA	AES/CFB/NoPadding        	192	samples/dsa/openssl_dsa_aes192_cfb.pem
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	192	samples/dsa/openssl_dsa_aes192_ecb.pem
+   SUCCESS    	DSA	AES/OFB/NoPadding        	192	samples/dsa/openssl_dsa_aes192_ofb.pem
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	256	samples/dsa/openssl_dsa_aes256_cbc.pem
+   SUCCESS    	DSA	AES/CFB/NoPadding        	256	samples/dsa/openssl_dsa_aes256_cfb.pem
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	256	samples/dsa/openssl_dsa_aes256_ecb.pem
+   SUCCESS    	DSA	AES/OFB/NoPadding        	256	samples/dsa/openssl_dsa_aes256_ofb.pem
+   SUCCESS    	DSA	Blowfish/CBC/PKCS5Padding	128	samples/dsa/openssl_dsa_blowfish_cbc.pem
+   SUCCESS    	DSA	Blowfish/CFB/NoPadding   	128	samples/dsa/openssl_dsa_blowfish_cfb.pem
+   SUCCESS    	DSA	Blowfish/ECB/PKCS5Padding	128	samples/dsa/openssl_dsa_blowfish_ecb.pem
+   SUCCESS    	DSA	Blowfish/OFB/NoPadding   	128	samples/dsa/openssl_dsa_blowfish_ofb.pem
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/openssl_dsa_des1_cbc.pem
+   SUCCESS    	DSA	DES/CFB/NoPadding        	 64	samples/dsa/openssl_dsa_des1_cfb.pem
+   SUCCESS    	DSA	DES/ECB/PKCS5Padding     	 64	samples/dsa/openssl_dsa_des1_ecb.pem
+   SUCCESS    	DSA	DES/OFB/NoPadding        	 64	samples/dsa/openssl_dsa_des1_ofb.pem
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/openssl_dsa_des2_cbc.pem
+   SUCCESS    	DSA	DESede/CFB/NoPadding     	192	samples/dsa/openssl_dsa_des2_cfb.pem
+   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	samples/dsa/openssl_dsa_des2_ecb.pem
+   SUCCESS    	DSA	DESede/OFB/NoPadding     	192	samples/dsa/openssl_dsa_des2_ofb.pem
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/openssl_dsa_des3_cbc.pem
+   SUCCESS    	DSA	DESede/CFB/NoPadding     	192	samples/dsa/openssl_dsa_des3_cfb.pem
+   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	samples/dsa/openssl_dsa_des3_ecb.pem
+   SUCCESS    	DSA	DESede/OFB/NoPadding     	192	samples/dsa/openssl_dsa_des3_ofb.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	samples/dsa/openssl_dsa_rc2_128_cbc.pem
+   SUCCESS    	DSA	RC2/CFB/NoPadding        	128	samples/dsa/openssl_dsa_rc2_128_cfb.pem
+   SUCCESS    	DSA	RC2/ECB/PKCS5Padding     	128	samples/dsa/openssl_dsa_rc2_128_ecb.pem
+   SUCCESS    	DSA	RC2/OFB/NoPadding        	128	samples/dsa/openssl_dsa_rc2_128_ofb.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	samples/dsa/openssl_dsa_rc2_40_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/openssl_dsa_rc2_64_cbc.pem
+   SUCCESS    	DSA	UNENCRYPTED              	  0	samples/dsa/openssl_dsa_unencrypted.der
+   SUCCESS    	DSA	UNENCRYPTED              	  0	samples/dsa/openssl_dsa_unencrypted.pem
+   SUCCESS    	DSA	UNENCRYPTED              	  0	samples/dsa/pkcs8_dsa_unencrypted.der
+   SUCCESS    	DSA	UNENCRYPTED              	  0	samples/dsa/pkcs8_dsa_unencrypted.pem
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md2_des1_cbc.der
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md2_des1_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md2_rc2_64_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md2_rc2_64_cbc.pem
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md5_des1_cbc.der
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md5_des1_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md5_rc2_64_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_md5_rc2_64_cbc.pem
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_sha1_des1_cbc.der
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_sha1_des1_cbc.pem
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/pkcs8v1_dsa_sha1_des2_cbc.der
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/pkcs8v1_dsa_sha1_des2_cbc.pem
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/pkcs8v1_dsa_sha1_des3_cbc.der
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/pkcs8v1_dsa_sha1_des3_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	samples/dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	samples/dsa/pkcs8v1_dsa_sha1_rc2_128_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	samples/dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	samples/dsa/pkcs8v1_dsa_sha1_rc2_40_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v1_dsa_sha1_rc2_64_cbc.pem
+   SUCCESS    	DSA	RC4                      	128	samples/dsa/pkcs8v1_dsa_sha1_rc4_128.der
+   SUCCESS    	DSA	RC4                      	128	samples/dsa/pkcs8v1_dsa_sha1_rc4_128.pem
+   SUCCESS    	DSA	RC4                      	 40	samples/dsa/pkcs8v1_dsa_sha1_rc4_40.der
+   SUCCESS    	DSA	RC4                      	 40	samples/dsa/pkcs8v1_dsa_sha1_rc4_40.pem
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	128	samples/dsa/pkcs8v2_dsa_aes128_cbc.der
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	128	samples/dsa/pkcs8v2_dsa_aes128_cbc.pem
+   SUCCESS    	DSA	AES/CFB/NoPadding        	128	samples/dsa/pkcs8v2_dsa_aes128_cfb.der
+   SUCCESS    	DSA	AES/CFB/NoPadding        	128	samples/dsa/pkcs8v2_dsa_aes128_cfb.pem
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	128	samples/dsa/pkcs8v2_dsa_aes128_ecb.der
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	128	samples/dsa/pkcs8v2_dsa_aes128_ecb.pem
+   SUCCESS    	DSA	AES/OFB/NoPadding        	128	samples/dsa/pkcs8v2_dsa_aes128_ofb.der
+   SUCCESS    	DSA	AES/OFB/NoPadding        	128	samples/dsa/pkcs8v2_dsa_aes128_ofb.pem
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	192	samples/dsa/pkcs8v2_dsa_aes192_cbc.der
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	192	samples/dsa/pkcs8v2_dsa_aes192_cbc.pem
+   SUCCESS    	DSA	AES/CFB/NoPadding        	192	samples/dsa/pkcs8v2_dsa_aes192_cfb.der
+   SUCCESS    	DSA	AES/CFB/NoPadding        	192	samples/dsa/pkcs8v2_dsa_aes192_cfb.pem
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	192	samples/dsa/pkcs8v2_dsa_aes192_ecb.der
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	192	samples/dsa/pkcs8v2_dsa_aes192_ecb.pem
+   SUCCESS    	DSA	AES/OFB/NoPadding        	192	samples/dsa/pkcs8v2_dsa_aes192_ofb.der
+   SUCCESS    	DSA	AES/OFB/NoPadding        	192	samples/dsa/pkcs8v2_dsa_aes192_ofb.pem
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	256	samples/dsa/pkcs8v2_dsa_aes256_cbc.der
+   SUCCESS    	DSA	AES/CBC/PKCS5Padding     	256	samples/dsa/pkcs8v2_dsa_aes256_cbc.pem
+   SUCCESS    	DSA	AES/CFB/NoPadding        	256	samples/dsa/pkcs8v2_dsa_aes256_cfb.der
+   SUCCESS    	DSA	AES/CFB/NoPadding        	256	samples/dsa/pkcs8v2_dsa_aes256_cfb.pem
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	256	samples/dsa/pkcs8v2_dsa_aes256_ecb.der
+   SUCCESS    	DSA	AES/ECB/PKCS5Padding     	256	samples/dsa/pkcs8v2_dsa_aes256_ecb.pem
+   SUCCESS    	DSA	AES/OFB/NoPadding        	256	samples/dsa/pkcs8v2_dsa_aes256_ofb.der
+   SUCCESS    	DSA	AES/OFB/NoPadding        	256	samples/dsa/pkcs8v2_dsa_aes256_ofb.pem
+   SUCCESS    	DSA	Blowfish/CBC/PKCS5Padding	128	samples/dsa/pkcs8v2_dsa_blowfish_cbc.der
+   SUCCESS    	DSA	Blowfish/CBC/PKCS5Padding	128	samples/dsa/pkcs8v2_dsa_blowfish_cbc.pem
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v2_dsa_des1_cbc.der
+   SUCCESS    	DSA	DES/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v2_dsa_des1_cbc.pem
+   SUCCESS    	DSA	DES/CFB/NoPadding        	 64	samples/dsa/pkcs8v2_dsa_des1_cfb.der
+   SUCCESS    	DSA	DES/CFB/NoPadding        	 64	samples/dsa/pkcs8v2_dsa_des1_cfb.pem
+   SUCCESS    	DSA	DES/ECB/PKCS5Padding     	 64	samples/dsa/pkcs8v2_dsa_des1_ecb.der
+   SUCCESS    	DSA	DES/ECB/PKCS5Padding     	 64	samples/dsa/pkcs8v2_dsa_des1_ecb.pem
+   SUCCESS    	DSA	DES/OFB/NoPadding        	 64	samples/dsa/pkcs8v2_dsa_des1_ofb.der
+   SUCCESS    	DSA	DES/OFB/NoPadding        	 64	samples/dsa/pkcs8v2_dsa_des1_ofb.pem
+   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	samples/dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.der
+   SUCCESS    	DSA	DESede/ECB/PKCS5Padding  	192	samples/dsa/pkcs8v2_dsa_des2_ecb_SEEMS_WRONG.pem
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/pkcs8v2_dsa_des3_cbc.der
+   SUCCESS    	DSA	DESede/CBC/PKCS5Padding  	192	samples/dsa/pkcs8v2_dsa_des3_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	samples/dsa/pkcs8v2_dsa_rc2_128_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	128	samples/dsa/pkcs8v2_dsa_rc2_128_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	samples/dsa/pkcs8v2_dsa_rc2_40_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 40	samples/dsa/pkcs8v2_dsa_rc2_40_cbc.pem
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v2_dsa_rc2_64_cbc.der
+   SUCCESS    	DSA	RC2/CBC/PKCS5Padding     	 64	samples/dsa/pkcs8v2_dsa_rc2_64_cbc.pem
 </pre>
+
diff --git a/samples/keystores/BC.BKS.ks b/samples/keystores/BC.BKS.ks
new file mode 100644
index 0000000..a0ed53b
Binary files /dev/null and b/samples/keystores/BC.BKS.ks differ
diff --git a/samples/keystores/BC.PKCS12-3DES-3DES.ks b/samples/keystores/BC.PKCS12-3DES-3DES.ks
new file mode 100644
index 0000000..7050936
Binary files /dev/null and b/samples/keystores/BC.PKCS12-3DES-3DES.ks differ
diff --git a/samples/keystores/BC.PKCS12-DEF-3DES-3DES.ks b/samples/keystores/BC.PKCS12-DEF-3DES-3DES.ks
new file mode 100644
index 0000000..0b392ec
Binary files /dev/null and b/samples/keystores/BC.PKCS12-DEF-3DES-3DES.ks differ
diff --git a/samples/keystores/BC.PKCS12-DEF.ks b/samples/keystores/BC.PKCS12-DEF.ks
new file mode 100644
index 0000000..5fbaef4
Binary files /dev/null and b/samples/keystores/BC.PKCS12-DEF.ks differ
diff --git a/samples/keystores/BC.PKCS12.ks b/samples/keystores/BC.PKCS12.ks
new file mode 100644
index 0000000..a738611
Binary files /dev/null and b/samples/keystores/BC.PKCS12.ks differ
diff --git a/samples/keystores/BC.UBER.ks b/samples/keystores/BC.UBER.ks
new file mode 100644
index 0000000..28f5378
Binary files /dev/null and b/samples/keystores/BC.UBER.ks differ
diff --git a/samples/keystores/README.txt b/samples/keystores/README.txt
new file mode 100644
index 0000000..bec2157
--- /dev/null
+++ b/samples/keystores/README.txt
@@ -0,0 +1,8 @@
+
+
+Password for single-password JKS is "changeit".
+
+Password to open dual-password JKS is "changeit", and the password to decrypt
+the private key is "itchange".
+
+
diff --git a/samples/keystores/Sun.2pass.jks.ks b/samples/keystores/Sun.2pass.jks.ks
new file mode 100644
index 0000000..e866ac5
Binary files /dev/null and b/samples/keystores/Sun.2pass.jks.ks differ
diff --git a/samples/keystores/Sun.jks.ks b/samples/keystores/Sun.jks.ks
new file mode 100644
index 0000000..fbbe8d9
Binary files /dev/null and b/samples/keystores/Sun.jks.ks differ
diff --git a/samples/keystores/SunJCE.jceks.ks b/samples/keystores/SunJCE.jceks.ks
new file mode 100644
index 0000000..808c792
Binary files /dev/null and b/samples/keystores/SunJCE.jceks.ks differ
diff --git a/samples/keystores/chain-rsa_dsa_rsa.ks b/samples/keystores/chain-rsa_dsa_rsa.ks
new file mode 100644
index 0000000..d2f0867
Binary files /dev/null and b/samples/keystores/chain-rsa_dsa_rsa.ks differ
diff --git a/samples/keystores/chain-rsa_dsa_rsa.pem b/samples/keystores/chain-rsa_dsa_rsa.pem
new file mode 100644
index 0000000..7418215
--- /dev/null
+++ b/samples/keystores/chain-rsa_dsa_rsa.pem
@@ -0,0 +1,289 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: dsaWithSHA1
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=dsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=test/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:c8:63:af:96:82:3e:8c:a9:d1:1d:62:ae:85:80:
+                    7e:71:32:04:c1:98:5a:80:a2:74:7f:7a:c8:63:c5:
+                    8d:82:e8:c1:ec:f9:69:82:98:d4:83:8a:4d:8d:81:
+                    95:88:68:e0:ef:38:5f:6e:38:42:b6:53:46:5f:24:
+                    41:b6:2d:c6:71:a1:e2:04:82:0f:e6:7c:82:36:7f:
+                    80:cb:cb:52:58:6a:39:bf:96:5c:f0:14:1c:c0:77:
+                    f4:64:72:cd:ea:c0:fd:9b:6b:95:4a:9f:fa:52:a8:
+                    d2:e5:9c:a1:cc:5e:45:ce:fb:d4:a3:7c:70:f1:f7:
+                    9c:76:74:ad:5d:07:c7:86:40:67:2e:94:e3:1c:4e:
+                    6d:ee:2b:b5:25:58:d3:b8:4d:29:70:1b:da:87:67:
+                    56:a8:33:71:88:83:90:b5:7c:8a:5b:c4:9a:83:56:
+                    31:6a:e9:f1:40:6a:91:37:29:12:16:21:09:8a:77:
+                    71:39:20:27:03:12:ba:ab:fc:06:a9:c6:77:ce:f1:
+                    41:4d:c5:55:92:38:b5:bb:64:07:e2:b3:8c:3f:73:
+                    cf:c4:02:0c:90:1f:0e:36:47:47:4d:ca:35:0e:66:
+                    c4:e8:17:c3:1c:0a:c3:a9:46:31:a8:95:25:3c:69:
+                    4c:aa:b2:9b:dd:f0:85:89:3d:de:5d:e8:70:47:b9:
+                    e5:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                9F:14:77:BF:3F:3A:B6:CA:38:82:42:48:16:2C:DA:D0:CB:5E:87:D8
+            X509v3 Authority Key Identifier: 
+                keyid:94:A7:CC:B9:AB:D7:48:81:B3:3A:71:6E:2B:F4:24:FE:2A:A4:C0:39
+
+    Signature Algorithm: dsaWithSHA1
+        30:2d:02:15:00:86:ec:d5:ef:f1:75:60:a2:09:36:40:ff:ca:
+        83:67:6a:08:5d:d4:1e:02:14:51:6c:df:41:80:43:74:2a:1c:
+        48:c2:08:85:5b:9b:7d:07:46:6b:84
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAvugAwIBAgIEIAkFJTAJBgcqhkjOOAQDMIGUMQswCQYDVQQGEwJDQTEL
+MAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMT
+bm90LXlldC1jb21tb25zLXNzbDEZMBcGA1UEAxMQZHNhLWludGVybWVkaWF0ZTEl
+MCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbTAeFw0wOTA1MjUy
+MTQ0MzFaFw00OTA1MjUyMTQ0MzFaMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMC
+QkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1j
+b21tb25zLXNzbDENMAsGA1UEAxMEdGVzdDElMCMGCSqGSIb3DQEJARYWanVsaXVz
+ZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2BlYho
+4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRyzerA
+/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY07hN
+KXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8BqnG
+d87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiVJTxp
+TKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
+AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJ8U
+d78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFJSnzLmr10iBszpxbiv0JP4q
+pMA5MAkGByqGSM44BAMDMAAwLQIVAIbs1e/xdWCiCTZA/8qDZ2oIXdQeAhRRbN9B
+gEN0KhxIwgiFW5t9B0ZrhA==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462055 (0x20090527)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=dsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: dsaEncryption
+            DSA Public Key:
+                pub: 
+                    7a:a9:65:fb:76:ba:be:f3:fa:94:59:52:ed:4e:fc:
+                    e4:70:5e:8f:7c:14:e7:73:d6:d2:36:6b:62:d2:56:
+                    c9:6e:7a:91:63:72:4e:a9:ce:2e:eb:38:5e:c4:72:
+                    f6:2c:52:aa:51:f4:ce:3b:28:55:39:c3:ad:5d:52:
+                    fa:ac:0c:32:48:fc:00:9f:c3:d9:75:09:8d:82:e0:
+                    cb:07:65:29:25:7a:34:2e:bb:a0:2d:30:91:59:0e:
+                    ce:82:fb:2d:ad:a5:b2:b9:2b:ec:6b:b1:04:07:0c:
+                    52:16:7d:6c:0c:b2:64:c7:c6:cb:ab:18:ab:a6:fa:
+                    3e:31:f3:8f:49:75:33:69:d3:2a:2a:e7:2c:38:b5:
+                    d6:7d:33:94:ba:a6:3e:2f:e5:3b:cc:4a:27:d1:59:
+                    f3:9c:71:b1:46:64:3f:28:f1:33:d1:bc:c2:8b:47:
+                    92:2d:c6:1f:fb:23:34:56:f1:6e:18:8e:7c:0b:75:
+                    42:8a:bb:92:44:04:58:41:d1:9b:6e:d6:14:98:94:
+                    3d:77:8d:93:d3:1f:e9:7b:a7:71:94:10:ee:e9:d3:
+                    5a:4a:b8:91:61:35:4c:00:76:f2:b2:3a:bd:9f:42:
+                    f9:f0:8e:da:bd:8c:60:fd:7d:65:85:98:c5:7d:42:
+                    b9:27:de:09:0a:1c:85:a7:63:e5:71:3c:ab:78:de:
+                    cf
+                P:   
+                    00:8f:5a:80:34:53:e1:52:68:8c:cf:9b:d5:7a:01:
+                    60:57:63:f9:f8:01:55:9e:55:17:7f:f4:cc:cd:d7:
+                    fb:f7:1e:36:00:1c:ae:5c:70:e8:1b:33:ef:b8:8d:
+                    aa:69:2a:66:f0:48:fd:bb:25:82:eb:56:be:ac:ca:
+                    49:6e:7f:17:fd:3b:61:57:a7:14:c1:eb:99:5d:6b:
+                    82:03:db:1c:18:2a:25:05:19:ec:34:b8:c3:1b:2c:
+                    69:89:37:7b:85:9b:c0:a9:39:84:43:f1:60:0b:91:
+                    50:e0:b5:93:3c:ad:1c:b8:33:4e:9b:00:ed:cd:60:
+                    59:9b:57:04:7b:c0:fb:2d:49:45:e3:ce:c0:8a:aa:
+                    4d:07:3a:43:a3:3d:06:70:66:fc:9f:b2:8f:d6:c5:
+                    1f:a5:7b:00:36:a9:42:5e:50:db:38:34:8c:4a:c6:
+                    f6:3a:58:9a:a6:57:93:f7:4e:55:8b:46:f0:b0:1b:
+                    9c:a0:cb:fc:57:91:be:6d:47:56:a9:d1:46:cd:43:
+                    7b:ff:24:96:0a:dd:d7:d8:b7:58:8e:6a:a1:eb:2a:
+                    ba:40:0a:f6:d1:53:7c:84:06:fc:14:1c:d5:33:79:
+                    88:bb:4f:fa:b5:87:35:61:0d:b0:7b:07:bb:74:7c:
+                    30:a7:a3:60:7d:76:a6:d1:46:2b:84:a2:9a:28:61:
+                    f2:89
+                Q:   
+                    00:bf:87:b6:dd:a6:62:0f:88:a2:44:a5:99:ac:b9:
+                    12:82:05:7b:2e:af
+                G:   
+                    00:86:37:bd:1d:60:12:25:f5:01:7f:7e:e0:e7:de:
+                    26:f4:3d:d4:75:fe:91:41:41:b3:c6:70:7f:71:c6:
+                    5e:4e:c1:0f:3e:cc:be:9c:0b:df:b4:8f:6e:2a:0f:
+                    90:5b:20:14:75:c7:31:13:e2:d8:73:73:76:b6:c4:
+                    f5:5f:ac:b4:2a:26:4e:8c:af:87:2e:f5:1d:78:69:
+                    15:b5:b4:b7:d3:52:ec:f4:c8:6e:c5:65:bd:88:e5:
+                    c4:da:0c:48:ac:d3:2d:a2:da:b0:72:75:09:1d:aa:
+                    d9:64:80:b7:18:31:54:07:d6:7a:8b:f3:be:b7:22:
+                    87:1c:3a:c7:2f:a9:4b:8d:79:06:a1:ff:1c:db:f3:
+                    17:9b:32:a0:61:20:6e:37:92:eb:27:a1:6f:b8:22:
+                    0e:26:4d:71:9a:b3:a0:9a:fb:fb:91:68:5b:52:3b:
+                    20:75:d5:36:a6:aa:c3:dc:52:01:87:06:58:68:62:
+                    20:b8:aa:bd:2b:c9:58:60:b7:02:2e:c4:4f:bf:ec:
+                    b7:43:13:3f:90:51:65:65:a9:ba:48:74:9e:3c:ad:
+                    93:b6:00:3f:93:11:e7:cd:ea:5f:11:44:b2:4f:d1:
+                    e3:fd:19:a8:bc:4a:c6:ae:4c:ec:83:85:fa:98:ed:
+                    0b:a3:8f:a0:35:38:d4:9f:96:fd:f3:b2:b5:80:d5:
+                    1e:a4
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                94:A7:CC:B9:AB:D7:48:81:B3:3A:71:6E:2B:F4:24:FE:2A:A4:C0:39
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        30:75:fb:1e:e2:d0:ff:18:3a:de:7d:49:8a:20:33:bc:0e:0c:
+        ad:7a:68:f8:57:91:3a:bd:2b:07:a7:25:a6:c6:d0:f7:30:57:
+        73:a3:34:af:ee:d3:5d:06:9f:80:f5:41:b7:7f:e8:0e:e2:28:
+        6c:a5:d7:82:9b:81:89:85:9f:47:5d:af:17:ab:f6:e1:02:4c:
+        01:2b:07:7c:2b:e1:77:1c:a4:e9:a6:89:97:50:49:87:73:04:
+        6e:32:50:f5:b7:be:f2:60:b3:9c:5f:b4:2a:d2:2f:c0:0b:82:
+        47:71:70:62:cc:98:ad:47:20:58:61:d6:c0:c5:30:65:3f:97:
+        43:47:50:cb:90:4c:c3:7c:50:c4:28:27:b7:2d:c8:2a:61:40:
+        18:7e:fa:ce:03:39:20:f9:96:a2:da:1c:fe:5e:c7:9f:f1:bc:
+        98:18:c1:63:e6:f6:35:35:d8:5d:18:2e:ef:87:7d:af:00:a3:
+        bc:12:18:c3:11:1e:8a:6d:bf:5d:10:87:6f:79:f3:8f:11:9d:
+        cb:0d:fe:f6:fe:4f:d0:2b:de:8e:3a:da:f3:46:11:ca:12:bb:
+        ca:22:67:05:45:e6:fd:9f:71:09:98:0b:1e:cf:51:73:b2:ad:
+        48:f9:06:2a:b5:5c:9f:f3:97:e0:8e:a3:df:57:1c:a7:94:ca:
+        f2:97:8e:56
+-----BEGIN CERTIFICATE-----
+MIIGoTCCBYmgAwIBAgIEIAkFJzANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDMxWhcN
+NDkwNTI1MjE0NDMxWjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEGRzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggM7MIICLgYHKoZIzjgEATCCAiECggEBAI9a
+gDRT4VJojM+b1XoBYFdj+fgBVZ5VF3/0zM3X+/ceNgAcrlxw6Bsz77iNqmkqZvBI
+/bslgutWvqzKSW5/F/07YVenFMHrmV1rggPbHBgqJQUZ7DS4wxssaYk3e4WbwKk5
+hEPxYAuRUOC1kzytHLgzTpsA7c1gWZtXBHvA+y1JRePOwIqqTQc6Q6M9BnBm/J+y
+j9bFH6V7ADapQl5Q2zg0jErG9jpYmqZXk/dOVYtG8LAbnKDL/FeRvm1HVqnRRs1D
+e/8klgrd19i3WI5qoesqukAK9tFTfIQG/BQc1TN5iLtP+rWHNWENsHsHu3R8MKej
+YH12ptFGK4Simihh8okCFQC/h7bdpmIPiKJEpZmsuRKCBXsurwKCAQEAhje9HWAS
+JfUBf37g594m9D3Udf6RQUGzxnB/ccZeTsEPPsy+nAvftI9uKg+QWyAUdccxE+LY
+c3N2tsT1X6y0KiZOjK+HLvUdeGkVtbS301Ls9MhuxWW9iOXE2gxIrNMtotqwcnUJ
+HarZZIC3GDFUB9Z6i/O+tyKHHDrHL6lLjXkGof8c2/MXmzKgYSBuN5LrJ6FvuCIO
+Jk1xmrOgmvv7kWhbUjsgddU2pqrD3FIBhwZYaGIguKq9K8lYYLcCLsRPv+y3QxM/
+kFFlZam6SHSePK2TtgA/kxHnzepfEUSyT9Hj/RmovErGrkzsg4X6mO0Lo4+gNTjU
+n5b987K1gNUepAOCAQUAAoIBAHqpZft2ur7z+pRZUu1O/ORwXo98FOdz1tI2a2LS
+VsluepFjck6pzi7rOF7EcvYsUqpR9M47KFU5w61dUvqsDDJI/ACfw9l1CY2C4MsH
+ZSklejQuu6AtMJFZDs6C+y2tpbK5K+xrsQQHDFIWfWwMsmTHxsurGKum+j4x849J
+dTNp0yoq5yw4tdZ9M5S6pj4v5TvMSifRWfOccbFGZD8o8TPRvMKLR5Itxh/7IzRW
+8W4YjnwLdUKKu5JEBFhB0Ztu1hSYlD13jZPTH+l7p3GUEO7p01pKuJFhNUwAdvKy
+Or2fQvnwjtq9jGD9fWWFmMV9Qrkn3gkKHIWnY+VxPKt43s+jgeswgegwHQYDVR0O
+BBYEFJSnzLmr10iBszpxbiv0JP4qpMA5MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2u
+wgcwLgCsWGObIH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMx
+GDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21t
+b25zLXNzbDENMAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2
+aWVzQGdtYWlsLmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
+A4IBAQAwdfse4tD/GDrefUmKIDO8Dgytemj4V5E6vSsHpyWmxtD3MFdzozSv7tNd
+Bp+A9UG3f+gO4ihspdeCm4GJhZ9HXa8Xq/bhAkwBKwd8K+F3HKTppomXUEmHcwRu
+MlD1t77yYLOcX7Qq0i/AC4JHcXBizJitRyBYYdbAxTBlP5dDR1DLkEzDfFDEKCe3
+LcgqYUAYfvrOAzkg+Zai2hz+Xsef8byYGMFj5vY1NdhdGC7vh32vAKO8EhjDER6K
+bb9dEIdvefOPEZ3LDf72/k/QK96OOtrzRhHKErvKImcFReb9n3EJmAsez1Fzsq1I
++QYqtVyf85fgjqPfVxynlMryl45W
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:28 2009 GMT
+            Not After : May 25 21:44:28 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:b9:db:04:16:8c:41:eb:91:c4:b8:d1:1a:73:28:
+                    59:09:b8:7a:b5:05:40:db:4f:2b:63:7b:bf:01:70:
+                    e1:0d:4c:09:3a:3b:63:9e:22:13:fa:55:d1:bc:e8:
+                    dd:31:71:df:0d:a6:0b:29:29:cc:da:bd:69:5c:cb:
+                    29:7e:6c:8c:93:82:c7:8b:00:ea:0b:8c:35:5c:fe:
+                    28:12:cf:ba:11:24:48:bc:0a:ee:37:54:a3:f2:9b:
+                    f2:76:94:7d:56:c0:52:35:f0:ff:c8:8c:08:7e:b0:
+                    49:c5:2f:fd:41:92:06:e8:c2:71:0d:f6:70:e5:93:
+                    89:80:a2:13:43:ac:53:56:ba:1a:44:44:98:cd:ba:
+                    f9:3a:93:20:71:34:93:0f:3f:34:34:2e:53:b2:d7:
+                    4a:22:3e:89:0a:c3:6e:12:40:ba:f3:22:6d:38:63:
+                    3b:f0:ef:42:2b:2d:f4:d2:f8:a9:76:ce:13:37:ce:
+                    1a:a4:bd:42:a0:7b:71:df:0e:3f:93:10:9d:22:0a:
+                    8b:61:92:c6:4c:fe:e7:bf:56:f4:5c:d3:85:98:92:
+                    a2:dc:d1:3d:f8:6e:3e:ac:e1:87:2f:e1:fb:30:d5:
+                    3d:24:fc:d9:d1:ac:b9:ca:9c:41:ff:60:aa:e4:57:
+                    7e:b1:93:ac:4f:64:b5:0a:d3:57:4e:12:68:5b:18:
+                    d2:15
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        9a:29:28:5e:4f:4f:59:f8:6b:b0:96:bf:ef:69:02:36:d1:72:
+        af:a2:f3:c0:7d:c1:50:5a:b8:63:61:18:1a:d4:4d:8f:a4:b2:
+        18:5d:1b:75:1d:b6:ce:e6:aa:b3:c1:16:ab:dd:64:ac:be:62:
+        7f:77:1d:d4:6a:eb:5d:f7:19:eb:6a:6a:60:6d:ca:d6:2a:4d:
+        ee:c9:5b:1e:05:eb:bb:3f:5f:a4:76:ae:fd:32:ac:1e:63:e7:
+        35:d3:95:1d:c9:bc:7a:2f:e7:0e:04:95:59:4d:30:51:ac:67:
+        65:41:74:b3:62:f6:4d:85:4b:88:26:15:c2:2d:03:69:16:f7:
+        6a:8a:5c:ca:ca:7b:ba:41:f9:7b:f4:ae:f8:29:56:48:9d:86:
+        2e:0a:06:7a:21:97:01:b3:d4:45:5a:14:05:d3:b1:3a:da:0a:
+        67:6d:d5:45:db:ba:88:09:4b:53:b3:69:1a:52:de:57:03:89:
+        fa:99:82:1d:79:fb:ae:55:d7:13:fd:5e:99:25:cb:75:a1:62:
+        b4:27:f0:54:4b:78:42:8b:54:63:62:f4:a3:0b:e2:26:a4:0c:
+        29:ae:49:b4:1a:34:e6:a4:07:8a:64:cb:63:46:ae:fa:ec:d0:
+        f4:e1:e2:25:11:57:27:61:e8:d1:48:ad:60:13:2d:b9:38:a3:
+        52:03:0f:ad
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
diff --git a/samples/keystores/chain-rsa_dsa_rsa.pkcs12.der b/samples/keystores/chain-rsa_dsa_rsa.pkcs12.der
new file mode 100644
index 0000000..36a0635
Binary files /dev/null and b/samples/keystores/chain-rsa_dsa_rsa.pkcs12.der differ
diff --git a/samples/keystores/chain-rsa_dsa_rsa.pkcs12.pem b/samples/keystores/chain-rsa_dsa_rsa.pkcs12.pem
new file mode 100644
index 0000000..fa2ccb0
--- /dev/null
+++ b/samples/keystores/chain-rsa_dsa_rsa.pkcs12.pem
@@ -0,0 +1,112 @@
+-----BEGIN CERTIFICATE-----
+MIIDPDCCAvugAwIBAgIEIAkFJTAJBgcqhkjOOAQDMIGUMQswCQYDVQQGEwJDQTEL
+MAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMT
+bm90LXlldC1jb21tb25zLXNzbDEZMBcGA1UEAxMQZHNhLWludGVybWVkaWF0ZTEl
+MCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbTAeFw0wOTA1MjUy
+MTQ0MzFaFw00OTA1MjUyMTQ0MzFaMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMC
+QkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1j
+b21tb25zLXNzbDENMAsGA1UEAxMEdGVzdDElMCMGCSqGSIb3DQEJARYWanVsaXVz
+ZGF2aWVzQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AMhjr5aCPoyp0R1iroWAfnEyBMGYWoCidH96yGPFjYLowez5aYKY1IOKTY2BlYho
+4O84X244QrZTRl8kQbYtxnGh4gSCD+Z8gjZ/gMvLUlhqOb+WXPAUHMB39GRyzerA
+/ZtrlUqf+lKo0uWcocxeRc771KN8cPH3nHZ0rV0Hx4ZAZy6U4xxObe4rtSVY07hN
+KXAb2odnVqgzcYiDkLV8ilvEmoNWMWrp8UBqkTcpEhYhCYp3cTkgJwMSuqv8BqnG
+d87xQU3FVZI4tbtkB+KzjD9zz8QCDJAfDjZHR03KNQ5mxOgXwxwKw6lGMaiVJTxp
+TKqym93whYk93l3ocEe55c0CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
+AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJ8U
+d78/OrbKOIJCSBYs2tDLXofYMB8GA1UdIwQYMBaAFJSnzLmr10iBszpxbiv0JP4q
+pMA5MAkGByqGSM44BAMDMAAwLQIVAIbs1e/xdWCiCTZA/8qDZ2oIXdQeAhRRbN9B
+gEN0KhxIwgiFW5t9B0ZrhA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGoTCCBYmgAwIBAgIEIAkFJzANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDMxWhcN
+NDkwNTI1MjE0NDMxWjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEGRzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggM7MIICLgYHKoZIzjgEATCCAiECggEBAI9a
+gDRT4VJojM+b1XoBYFdj+fgBVZ5VF3/0zM3X+/ceNgAcrlxw6Bsz77iNqmkqZvBI
+/bslgutWvqzKSW5/F/07YVenFMHrmV1rggPbHBgqJQUZ7DS4wxssaYk3e4WbwKk5
+hEPxYAuRUOC1kzytHLgzTpsA7c1gWZtXBHvA+y1JRePOwIqqTQc6Q6M9BnBm/J+y
+j9bFH6V7ADapQl5Q2zg0jErG9jpYmqZXk/dOVYtG8LAbnKDL/FeRvm1HVqnRRs1D
+e/8klgrd19i3WI5qoesqukAK9tFTfIQG/BQc1TN5iLtP+rWHNWENsHsHu3R8MKej
+YH12ptFGK4Simihh8okCFQC/h7bdpmIPiKJEpZmsuRKCBXsurwKCAQEAhje9HWAS
+JfUBf37g594m9D3Udf6RQUGzxnB/ccZeTsEPPsy+nAvftI9uKg+QWyAUdccxE+LY
+c3N2tsT1X6y0KiZOjK+HLvUdeGkVtbS301Ls9MhuxWW9iOXE2gxIrNMtotqwcnUJ
+HarZZIC3GDFUB9Z6i/O+tyKHHDrHL6lLjXkGof8c2/MXmzKgYSBuN5LrJ6FvuCIO
+Jk1xmrOgmvv7kWhbUjsgddU2pqrD3FIBhwZYaGIguKq9K8lYYLcCLsRPv+y3QxM/
+kFFlZam6SHSePK2TtgA/kxHnzepfEUSyT9Hj/RmovErGrkzsg4X6mO0Lo4+gNTjU
+n5b987K1gNUepAOCAQUAAoIBAHqpZft2ur7z+pRZUu1O/ORwXo98FOdz1tI2a2LS
+VsluepFjck6pzi7rOF7EcvYsUqpR9M47KFU5w61dUvqsDDJI/ACfw9l1CY2C4MsH
+ZSklejQuu6AtMJFZDs6C+y2tpbK5K+xrsQQHDFIWfWwMsmTHxsurGKum+j4x849J
+dTNp0yoq5yw4tdZ9M5S6pj4v5TvMSifRWfOccbFGZD8o8TPRvMKLR5Itxh/7IzRW
+8W4YjnwLdUKKu5JEBFhB0Ztu1hSYlD13jZPTH+l7p3GUEO7p01pKuJFhNUwAdvKy
+Or2fQvnwjtq9jGD9fWWFmMV9Qrkn3gkKHIWnY+VxPKt43s+jgeswgegwHQYDVR0O
+BBYEFJSnzLmr10iBszpxbiv0JP4qpMA5MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2u
+wgcwLgCsWGObIH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMx
+GDAWBgNVBAoTD2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21t
+b25zLXNzbDENMAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2
+aWVzQGdtYWlsLmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA
+A4IBAQAwdfse4tD/GDrefUmKIDO8Dgytemj4V5E6vSsHpyWmxtD3MFdzozSv7tNd
+Bp+A9UG3f+gO4ihspdeCm4GJhZ9HXa8Xq/bhAkwBKwd8K+F3HKTppomXUEmHcwRu
+MlD1t77yYLOcX7Qq0i/AC4JHcXBizJitRyBYYdbAxTBlP5dDR1DLkEzDfFDEKCe3
+LcgqYUAYfvrOAzkg+Zai2hz+Xsef8byYGMFj5vY1NdhdGC7vh32vAKO8EhjDER6K
+bb9dEIdvefOPEZ3LDf72/k/QK96OOtrzRhHKErvKImcFReb9n3EJmAsez1Fzsq1I
++QYqtVyf85fgjqPfVxynlMryl45W
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIY6+Wgj6MqdEd
+Yq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2NgZWIaODvOF9uOEK2U0Zf
+JEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rkcs3qwP2ba5VKn/pSqNLl
+nKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7UlWNO4TSlwG9qHZ1aoM3GI
+g5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr/AapxnfO8UFNxVWSOLW7
+ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGolSU8aUyqspvd8IWJPd5d
+6HBHueXNAgMBAAECggEAV3q9MpVVPQ79TTjBO2Km0D+nt+QMzk8dUHGHfZbGejmm
+Pw96shqJ24rK5FWHs+8lEwmnD3TcGsAr3mjzjtZY5U5oXtNwoYwFRElRLqZqIlLt
+NugrVltRWeyD8j30CuGJVQoYOGWyX9d3ielg8NjO3NcvMtembttLoKK68/vrbH11
+9W7wr5p8/xyMfyl9curnmCFk5QqJ1FBpjPWY05NDIBCUJB0tGAqViCpxEeWPSlvb
+xcElqWfdbtnsYUxYU+iOTHHotoKnz4nLHYK2/njMhlCEyMXfu1DJOd8rg5yXewJF
+v6NhXgWStSexAT1bZ17LROazVcHfWB9QmXF1Fm7vOQKBgQD+dZxPDOi3Y4gCFegn
+Z+epNyl2aPTkseEZxrIqPKLHsGxUfYjQqkX2RdfTrq2vf4vFlN6uCXhSlZKXfLH/
+iQ8FAzqenhVVHK2fv5xB0SE5zNmcHDrHshl+/zUNI2u5AMFECVO2SVbgoFjvgkou
+FolK8XUXfHfb4f732LUyYI0lEwKBgQDJmkWHhzekz3P5iWaAt1SH8bZpt2hqa6Bx
+A4VvMdtmjCxEDETN0Rb3CPYxw3qa3xGfW1y1j/49xi4gr69yaT2Tbca7PFGUmWRo
+OJwfCUB5uBUi6UVytK19OVKReOm4666x8P3YO4cxxSI/HeoSU0HR1kkX9rGmrsGN
+MgUQ15+FnwKBgAKf6/DUzUG3ARwkZbSiWb1hGEhkZMJHI29EoWnWHke5BiUI9nRQ
+jVAxADzqvFfnFOYA1xssddVEPbLaUmu0WjdPBTfFoaqzFQdkzpPPOGyENGpr0B9n
+MuQgdceg6eeKnnO5NOfYcdD3VnOCAInhKaFgRDjty7604hBkZ9oRLOOJAoGBAIJ+
+dmUMlGr80XADjTLh+DhqsA1r542DDv44LkXUetS9BOYjHuIuZnQO+/UoOBNJMsn4
+xGDNzN7FihQkRCeFkZL9arbFi3TpeUGw6vV38qEXE69eWVKvOuEkmpqJLphBDfom
+KNmvZopDtTAvt9SWybL+xp9ZUpK26ZfwebD2MU63AoGBAOa2Kt01DxoqiWiQP/ds
+Mc9wOw1zJsSmIK7wEiW3FkCz8uw3UgjF9ymYY/YAW3eZtuUpuxEzyENb9f21p4b2
+zYoZ7nCUo4TmVXxgCjiEWglg3b/R3xjQr1dAABhTeI8bXMv5r/tMUsnS79uKqwGD
+2Gc1syc3+055K4qcfZHH0XWu
+-----END PRIVATE KEY-----
diff --git a/samples/keystores/chain-rsa_rsa_rsa.ks b/samples/keystores/chain-rsa_rsa_rsa.ks
new file mode 100644
index 0000000..048ccd5
Binary files /dev/null and b/samples/keystores/chain-rsa_rsa_rsa.ks differ
diff --git a/samples/keystores/chain-rsa_rsa_rsa.pem b/samples/keystores/chain-rsa_rsa_rsa.pem
new file mode 100644
index 0000000..2326bcf
--- /dev/null
+++ b/samples/keystores/chain-rsa_rsa_rsa.pem
@@ -0,0 +1,254 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=rsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:31 2009 GMT
+            Not After : May 25 21:44:31 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=test/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:c8:63:af:96:82:3e:8c:a9:d1:1d:62:ae:85:80:
+                    7e:71:32:04:c1:98:5a:80:a2:74:7f:7a:c8:63:c5:
+                    8d:82:e8:c1:ec:f9:69:82:98:d4:83:8a:4d:8d:81:
+                    95:88:68:e0:ef:38:5f:6e:38:42:b6:53:46:5f:24:
+                    41:b6:2d:c6:71:a1:e2:04:82:0f:e6:7c:82:36:7f:
+                    80:cb:cb:52:58:6a:39:bf:96:5c:f0:14:1c:c0:77:
+                    f4:64:72:cd:ea:c0:fd:9b:6b:95:4a:9f:fa:52:a8:
+                    d2:e5:9c:a1:cc:5e:45:ce:fb:d4:a3:7c:70:f1:f7:
+                    9c:76:74:ad:5d:07:c7:86:40:67:2e:94:e3:1c:4e:
+                    6d:ee:2b:b5:25:58:d3:b8:4d:29:70:1b:da:87:67:
+                    56:a8:33:71:88:83:90:b5:7c:8a:5b:c4:9a:83:56:
+                    31:6a:e9:f1:40:6a:91:37:29:12:16:21:09:8a:77:
+                    71:39:20:27:03:12:ba:ab:fc:06:a9:c6:77:ce:f1:
+                    41:4d:c5:55:92:38:b5:bb:64:07:e2:b3:8c:3f:73:
+                    cf:c4:02:0c:90:1f:0e:36:47:47:4d:ca:35:0e:66:
+                    c4:e8:17:c3:1c:0a:c3:a9:46:31:a8:95:25:3c:69:
+                    4c:aa:b2:9b:dd:f0:85:89:3d:de:5d:e8:70:47:b9:
+                    e5:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                9F:14:77:BF:3F:3A:B6:CA:38:82:42:48:16:2C:DA:D0:CB:5E:87:D8
+            X509v3 Authority Key Identifier: 
+                keyid:2E:F4:CD:A1:B4:AD:03:85:D8:AF:69:97:D5:2D:95:40:D6:BF:12:BF
+
+    Signature Algorithm: sha1WithRSAEncryption
+        02:ea:45:04:9c:7b:79:4b:bc:24:7d:b4:5a:43:fa:cc:06:48:
+        d3:60:3f:a0:04:bc:42:ef:01:cc:0d:75:64:85:0a:86:37:e7:
+        14:09:29:92:f0:e0:c1:d4:e5:c1:6b:82:82:74:74:74:ae:68:
+        ac:0d:08:d3:95:e4:aa:3b:6a:a7:fd:f6:ea:f1:de:7b:4d:7b:
+        70:f8:a4:b1:21:a3:b2:e6:b1:5a:85:ca:c5:47:4b:c3:35:23:
+        3d:cd:f3:f8:fa:07:35:7d:df:a9:7e:a5:11:86:83:8f:06:13:
+        b5:93:73:78:ab:35:90:0d:a1:7d:8a:11:e7:55:d8:15:bd:bd:
+        54:e0:ae:6a:77:1a:13:ea:4c:23:11:64:d2:2f:2c:e1:04:2c:
+        05:b4:c7:25:73:6d:3b:69:be:94:16:6d:28:00:bc:67:48:f8:
+        1e:dd:1d:63:4c:6b:9f:85:e4:bb:10:ff:bf:b6:f2:2c:c8:53:
+        3c:23:b6:55:85:fd:68:95:27:93:ff:34:d7:29:7b:18:19:4b:
+        77:88:e8:75:a5:ba:2c:d6:64:f7:25:2e:fa:af:14:63:95:1b:
+        d1:77:3c:bc:0c:13:5f:37:5a:06:b7:92:22:ed:a0:d1:6c:b1:
+        e7:3f:af:95:c1:8a:7f:47:46:a0:74:ad:35:d0:52:59:31:b5:
+        2b:3c:fe:3d
+-----BEGIN CERTIFICATE-----
+MIIEFzCCAv+gAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlh
+dGUxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkw
+NTI1MjE0NDMxWhcNNDkwNTI1MjE0NDMxWjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNV
+BAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15
+ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHRlc3QxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDIY6+Wgj6MqdEdYq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2N
+gZWIaODvOF9uOEK2U0ZfJEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rk
+cs3qwP2ba5VKn/pSqNLlnKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7Ul
+WNO4TSlwG9qHZ1aoM3GIg5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr
+/AapxnfO8UFNxVWSOLW7ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGo
+lSU8aUyqspvd8IWJPd5d6HBHueXNAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSfFHe/Pzq2yjiCQkgWLNrQy16H2DAfBgNVHSMEGDAWgBQu9M2htK0DhdivaZfV
+LZVA1r8SvzANBgkqhkiG9w0BAQUFAAOCAQEAAupFBJx7eUu8JH20WkP6zAZI02A/
+oAS8Qu8BzA11ZIUKhjfnFAkpkvDgwdTlwWuCgnR0dK5orA0I05Xkqjtqp/326vHe
+e017cPiksSGjsuaxWoXKxUdLwzUjPc3z+PoHNX3fqX6lEYaDjwYTtZNzeKs1kA2h
+fYoR51XYFb29VOCuancaE+pMIxFk0i8s4QQsBbTHJXNtO2m+lBZtKAC8Z0j4Ht0d
+Y0xrn4XkuxD/v7byLMhTPCO2VYX9aJUnk/801yl7GBlLd4jodaW6LNZk9yUu+q8U
+Y5Ub0Xc8vAwTXzdaBreSIu2g0Wyx5z+vlcGKf0dGoHStNdBSWTG1Kzz+PQ==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462054 (0x20090526)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:29 2009 GMT
+            Not After : May 25 21:44:29 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=rsa-intermediate/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:ce:1b:db:73:49:85:a4:3c:42:14:84:6a:7d:47:
+                    78:d2:e1:58:27:ed:e4:78:5e:5d:2b:ee:c3:29:c5:
+                    a2:d2:6f:f3:0e:0a:d6:d6:7f:5a:f7:30:6f:c9:8f:
+                    ad:fe:53:22:46:aa:5e:0b:f6:e8:21:f3:dc:5f:75:
+                    9b:55:c5:07:ab:75:54:fd:9b:2e:31:da:12:45:3c:
+                    7b:1e:27:f6:a1:5b:5d:ac:0a:b4:e8:dd:d3:ba:ff:
+                    af:f1:43:31:4c:5b:5e:73:d4:a8:ce:93:b9:f1:9d:
+                    8b:17:1f:16:74:4f:9a:07:80:7c:1a:41:a6:49:21:
+                    2a:a8:83:75:18:3d:ed:17:8b:8b:b4:f8:46:d3:28:
+                    25:35:e1:17:df:e6:b4:f7:87:a7:71:0f:a0:b5:22:
+                    4d:48:35:2c:a3:dc:fc:58:33:76:fb:07:cf:fb:64:
+                    e9:fa:05:a8:be:63:eb:32:48:01:10:fd:44:a2:79:
+                    72:5d:33:62:1b:ad:f4:60:3f:7d:59:9c:07:cf:9c:
+                    b1:b5:e7:18:84:5e:ec:e0:78:6c:53:f0:cf:67:8d:
+                    91:95:73:72:de:70:c7:ca:ea:27:6f:d2:61:c8:7d:
+                    a5:28:28:61:c8:c9:e9:6b:7e:ae:07:9d:36:87:04:
+                    a4:97:1c:1d:f5:39:cb:b2:8a:32:8d:25:68:05:2d:
+                    86:65
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                2E:F4:CD:A1:B4:AD:03:85:D8:AF:69:97:D5:2D:95:40:D6:BF:12:BF
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        03:b6:83:af:6c:ff:2b:21:12:b9:8a:cd:8e:2f:d9:1a:28:88:
+        0c:9f:f1:6b:73:fb:76:3f:70:d8:cd:ce:5a:f6:0f:08:6a:0a:
+        a3:f7:ad:b2:72:19:eb:0e:9c:36:bb:a4:fb:3f:90:78:ba:45:
+        ee:da:c9:8e:a0:ef:b3:ac:05:4c:f4:b4:37:18:0d:bb:20:5d:
+        f4:e7:b3:77:ea:56:0c:ad:81:42:80:04:92:ca:3b:73:ed:35:
+        d5:35:f6:9f:95:a2:2d:81:4d:e6:3a:3c:13:64:f1:0f:36:7e:
+        90:c2:a0:37:c6:19:9e:13:47:92:a3:e8:18:3d:f4:d8:a0:83:
+        80:0f:7b:a7:57:9c:60:6c:6a:3e:d4:1d:cc:5e:8c:13:7f:1c:
+        d7:f6:df:ad:ae:0a:95:12:f1:71:c2:70:98:d1:2f:6c:f0:24:
+        43:b4:7e:a4:e4:31:d4:bc:50:90:03:4b:34:ba:a3:d0:fd:f5:
+        01:17:eb:11:83:44:86:65:17:bf:89:00:c7:93:d6:70:7e:0b:
+        4b:93:dc:f9:92:50:4c:3e:11:23:c5:50:1c:49:bd:8c:0c:2c:
+        60:1c:d8:e6:5f:a4:fa:21:db:8c:62:bf:74:a3:83:1c:8d:cc:
+        8e:34:8c:16:1c:c6:71:63:89:c2:c4:45:0c:90:71:98:68:2f:
+        9d:a7:87:f7
+-----BEGIN CERTIFICATE-----
+MIIEiDCCA3CgAwIBAgIEIAkFJjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI5WhcN
+NDkwNTI1MjE0NDI5WjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDOG9tzSYWkPEIUhGp9R3jS4Vgn7eR4Xl0r7sMpxaLSb/MOCtbWf1r3MG/J
+j63+UyJGql4L9ugh89xfdZtVxQerdVT9my4x2hJFPHseJ/ahW12sCrTo3dO6/6/x
+QzFMW15z1KjOk7nxnYsXHxZ0T5oHgHwaQaZJISqog3UYPe0Xi4u0+EbTKCU14Rff
+5rT3h6dxD6C1Ik1INSyj3PxYM3b7B8/7ZOn6Bai+Y+sySAEQ/USieXJdM2IbrfRg
+P31ZnAfPnLG15xiEXuzgeGxT8M9njZGVc3LecMfK6idv0mHIfaUoKGHIyelrfq4H
+nTaHBKSXHB31OcuyijKNJWgFLYZlAgMBAAGjgeswgegwHQYDVR0OBBYEFC70zaG0
+rQOF2K9pl9UtlUDWvxK/MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGOb
+IH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoT
+D2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDEN
+MAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWls
+LmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQADtoOv
+bP8rIRK5is2OL9kaKIgMn/Frc/t2P3DYzc5a9g8Iagqj962ychnrDpw2u6T7P5B4
+ukXu2smOoO+zrAVM9LQ3GA27IF3057N36lYMrYFCgASSyjtz7TXVNfaflaItgU3m
+OjwTZPEPNn6QwqA3xhmeE0eSo+gYPfTYoIOAD3unV5xgbGo+1B3MXowTfxzX9t+t
+rgqVEvFxwnCY0S9s8CRDtH6k5DHUvFCQA0s0uqPQ/fUBF+sRg0SGZRe/iQDHk9Zw
+fgtLk9z5klBMPhEjxVAcSb2MDCxgHNjmX6T6IduMYr90o4McjcyONIwWHMZxY4nC
+xEUMkHGYaC+dp4f3
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 537462053 (0x20090525)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Validity
+            Not Before: May 25 21:44:28 2009 GMT
+            Not After : May 25 21:44:28 2049 GMT
+        Subject: C=CA, ST=BC, O=juliusdavies.ca, OU=not-yet-commons-ssl, CN=root/emailAddress=juliusdavies at gmail.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:b9:db:04:16:8c:41:eb:91:c4:b8:d1:1a:73:28:
+                    59:09:b8:7a:b5:05:40:db:4f:2b:63:7b:bf:01:70:
+                    e1:0d:4c:09:3a:3b:63:9e:22:13:fa:55:d1:bc:e8:
+                    dd:31:71:df:0d:a6:0b:29:29:cc:da:bd:69:5c:cb:
+                    29:7e:6c:8c:93:82:c7:8b:00:ea:0b:8c:35:5c:fe:
+                    28:12:cf:ba:11:24:48:bc:0a:ee:37:54:a3:f2:9b:
+                    f2:76:94:7d:56:c0:52:35:f0:ff:c8:8c:08:7e:b0:
+                    49:c5:2f:fd:41:92:06:e8:c2:71:0d:f6:70:e5:93:
+                    89:80:a2:13:43:ac:53:56:ba:1a:44:44:98:cd:ba:
+                    f9:3a:93:20:71:34:93:0f:3f:34:34:2e:53:b2:d7:
+                    4a:22:3e:89:0a:c3:6e:12:40:ba:f3:22:6d:38:63:
+                    3b:f0:ef:42:2b:2d:f4:d2:f8:a9:76:ce:13:37:ce:
+                    1a:a4:bd:42:a0:7b:71:df:0e:3f:93:10:9d:22:0a:
+                    8b:61:92:c6:4c:fe:e7:bf:56:f4:5c:d3:85:98:92:
+                    a2:dc:d1:3d:f8:6e:3e:ac:e1:87:2f:e1:fb:30:d5:
+                    3d:24:fc:d9:d1:ac:b9:ca:9c:41:ff:60:aa:e4:57:
+                    7e:b1:93:ac:4f:64:b5:0a:d3:57:4e:12:68:5b:18:
+                    d2:15
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+            X509v3 Authority Key Identifier: 
+                keyid:07:D8:71:DB:2B:1A:9D:AE:C2:07:30:2E:00:AC:58:63:9B:20:7D:A6
+                DirName:/C=CA/ST=BC/O=juliusdavies.ca/OU=not-yet-commons-ssl/CN=root/emailAddress=juliusdavies at gmail.com
+                serial:20:09:05:25
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        9a:29:28:5e:4f:4f:59:f8:6b:b0:96:bf:ef:69:02:36:d1:72:
+        af:a2:f3:c0:7d:c1:50:5a:b8:63:61:18:1a:d4:4d:8f:a4:b2:
+        18:5d:1b:75:1d:b6:ce:e6:aa:b3:c1:16:ab:dd:64:ac:be:62:
+        7f:77:1d:d4:6a:eb:5d:f7:19:eb:6a:6a:60:6d:ca:d6:2a:4d:
+        ee:c9:5b:1e:05:eb:bb:3f:5f:a4:76:ae:fd:32:ac:1e:63:e7:
+        35:d3:95:1d:c9:bc:7a:2f:e7:0e:04:95:59:4d:30:51:ac:67:
+        65:41:74:b3:62:f6:4d:85:4b:88:26:15:c2:2d:03:69:16:f7:
+        6a:8a:5c:ca:ca:7b:ba:41:f9:7b:f4:ae:f8:29:56:48:9d:86:
+        2e:0a:06:7a:21:97:01:b3:d4:45:5a:14:05:d3:b1:3a:da:0a:
+        67:6d:d5:45:db:ba:88:09:4b:53:b3:69:1a:52:de:57:03:89:
+        fa:99:82:1d:79:fb:ae:55:d7:13:fd:5e:99:25:cb:75:a1:62:
+        b4:27:f0:54:4b:78:42:8b:54:63:62:f4:a3:0b:e2:26:a4:0c:
+        29:ae:49:b4:1a:34:e6:a4:07:8a:64:cb:63:46:ae:fa:ec:d0:
+        f4:e1:e2:25:11:57:27:61:e8:d1:48:ad:60:13:2d:b9:38:a3:
+        52:03:0f:ad
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
diff --git a/samples/keystores/chain-rsa_rsa_rsa.pkcs12.der b/samples/keystores/chain-rsa_rsa_rsa.pkcs12.der
new file mode 100644
index 0000000..b535a8f
Binary files /dev/null and b/samples/keystores/chain-rsa_rsa_rsa.pkcs12.der differ
diff --git a/samples/keystores/chain-rsa_rsa_rsa.pkcs12.pem b/samples/keystores/chain-rsa_rsa_rsa.pkcs12.pem
new file mode 100644
index 0000000..2a4afc9
--- /dev/null
+++ b/samples/keystores/chain-rsa_rsa_rsa.pkcs12.pem
@@ -0,0 +1,105 @@
+-----BEGIN CERTIFICATE-----
+MIIEFzCCAv+gAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlh
+dGUxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkw
+NTI1MjE0NDMxWhcNNDkwNTI1MjE0NDMxWjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNV
+BAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15
+ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHRlc3QxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDIY6+Wgj6MqdEdYq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2N
+gZWIaODvOF9uOEK2U0ZfJEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rk
+cs3qwP2ba5VKn/pSqNLlnKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7Ul
+WNO4TSlwG9qHZ1aoM3GIg5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr
+/AapxnfO8UFNxVWSOLW7ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGo
+lSU8aUyqspvd8IWJPd5d6HBHueXNAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI
+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
+BBSfFHe/Pzq2yjiCQkgWLNrQy16H2DAfBgNVHSMEGDAWgBQu9M2htK0DhdivaZfV
+LZVA1r8SvzANBgkqhkiG9w0BAQUFAAOCAQEAAupFBJx7eUu8JH20WkP6zAZI02A/
+oAS8Qu8BzA11ZIUKhjfnFAkpkvDgwdTlwWuCgnR0dK5orA0I05Xkqjtqp/326vHe
+e017cPiksSGjsuaxWoXKxUdLwzUjPc3z+PoHNX3fqX6lEYaDjwYTtZNzeKs1kA2h
+fYoR51XYFb29VOCuancaE+pMIxFk0i8s4QQsBbTHJXNtO2m+lBZtKAC8Z0j4Ht0d
+Y0xrn4XkuxD/v7byLMhTPCO2VYX9aJUnk/801yl7GBlLd4jodaW6LNZk9yUu+q8U
+Y5Ub0Xc8vAwTXzdaBreSIu2g0Wyx5z+vlcGKf0dGoHStNdBSWTG1Kzz+PQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEiDCCA3CgAwIBAgIEIAkFJjANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI5WhcN
+NDkwNTI1MjE0NDI5WjCBlDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxGTAXBgNVBAMTEHJzYS1pbnRlcm1lZGlhdGUxJTAjBgkqhkiG9w0BCQEWFmp1
+bGl1c2Rhdmllc0BnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDOG9tzSYWkPEIUhGp9R3jS4Vgn7eR4Xl0r7sMpxaLSb/MOCtbWf1r3MG/J
+j63+UyJGql4L9ugh89xfdZtVxQerdVT9my4x2hJFPHseJ/ahW12sCrTo3dO6/6/x
+QzFMW15z1KjOk7nxnYsXHxZ0T5oHgHwaQaZJISqog3UYPe0Xi4u0+EbTKCU14Rff
+5rT3h6dxD6C1Ik1INSyj3PxYM3b7B8/7ZOn6Bai+Y+sySAEQ/USieXJdM2IbrfRg
+P31ZnAfPnLG15xiEXuzgeGxT8M9njZGVc3LecMfK6idv0mHIfaUoKGHIyelrfq4H
+nTaHBKSXHB31OcuyijKNJWgFLYZlAgMBAAGjgeswgegwHQYDVR0OBBYEFC70zaG0
+rQOF2K9pl9UtlUDWvxK/MIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGOb
+IH2moYGOpIGLMIGIMQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoT
+D2p1bGl1c2Rhdmllcy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDEN
+MAsGA1UEAxMEcm9vdDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWls
+LmNvbYIEIAkFJTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQADtoOv
+bP8rIRK5is2OL9kaKIgMn/Frc/t2P3DYzc5a9g8Iagqj962ychnrDpw2u6T7P5B4
+ukXu2smOoO+zrAVM9LQ3GA27IF3057N36lYMrYFCgASSyjtz7TXVNfaflaItgU3m
+OjwTZPEPNn6QwqA3xhmeE0eSo+gYPfTYoIOAD3unV5xgbGo+1B3MXowTfxzX9t+t
+rgqVEvFxwnCY0S9s8CRDtH6k5DHUvFCQA0s0uqPQ/fUBF+sRg0SGZRe/iQDHk9Zw
+fgtLk9z5klBMPhEjxVAcSb2MDCxgHNjmX6T6IduMYr90o4McjcyONIwWHMZxY4nC
+xEUMkHGYaC+dp4f3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEfDCCA2SgAwIBAgIEIAkFJTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
+Q0ExCzAJBgNVBAgTAkJDMRgwFgYDVQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNV
+BAsTE25vdC15ZXQtY29tbW9ucy1zc2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG
+9w0BCQEWFmp1bGl1c2Rhdmllc0BnbWFpbC5jb20wHhcNMDkwNTI1MjE0NDI4WhcN
+NDkwNTI1MjE0NDI4WjCBiDELMAkGA1UEBhMCQ0ExCzAJBgNVBAgTAkJDMRgwFgYD
+VQQKEw9qdWxpdXNkYXZpZXMuY2ExHDAaBgNVBAsTE25vdC15ZXQtY29tbW9ucy1z
+c2wxDTALBgNVBAMTBHJvb3QxJTAjBgkqhkiG9w0BCQEWFmp1bGl1c2Rhdmllc0Bn
+bWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC52wQWjEHr
+kcS40RpzKFkJuHq1BUDbTytje78BcOENTAk6O2OeIhP6VdG86N0xcd8NpgspKcza
+vWlcyyl+bIyTgseLAOoLjDVc/igSz7oRJEi8Cu43VKPym/J2lH1WwFI18P/IjAh+
+sEnFL/1BkgbownEN9nDlk4mAohNDrFNWuhpERJjNuvk6kyBxNJMPPzQ0LlOy10oi
+PokKw24SQLrzIm04Yzvw70IrLfTS+Kl2zhM3zhqkvUKge3HfDj+TEJ0iCothksZM
+/ue/VvRc04WYkqLc0T34bj6s4Ycv4fsw1T0k/NnRrLnKnEH/YKrkV36xk6xPZLUK
+01dOEmhbGNIVAgMBAAGjgeswgegwHQYDVR0OBBYEFAfYcdsrGp2uwgcwLgCsWGOb
+IH2mMIG4BgNVHSMEgbAwga2AFAfYcdsrGp2uwgcwLgCsWGObIH2moYGOpIGLMIGI
+MQswCQYDVQQGEwJDQTELMAkGA1UECBMCQkMxGDAWBgNVBAoTD2p1bGl1c2Rhdmll
+cy5jYTEcMBoGA1UECxMTbm90LXlldC1jb21tb25zLXNzbDENMAsGA1UEAxMEcm9v
+dDElMCMGCSqGSIb3DQEJARYWanVsaXVzZGF2aWVzQGdtYWlsLmNvbYIEIAkFJTAM
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCaKSheT09Z+Guwlr/vaQI2
+0XKvovPAfcFQWrhjYRga1E2PpLIYXRt1HbbO5qqzwRar3WSsvmJ/dx3Uautd9xnr
+ampgbcrWKk3uyVseBeu7P1+kdq79MqweY+c105Udybx6L+cOBJVZTTBRrGdlQXSz
+YvZNhUuIJhXCLQNpFvdqilzKynu6Qfl79K74KVZInYYuCgZ6IZcBs9RFWhQF07E6
+2gpnbdVF27qICUtTs2kaUt5XA4n6mYIdefuuVdcT/V6ZJct1oWK0J/BUS3hCi1Rj
+YvSjC+ImpAwprkm0GjTmpAeKZMtjRq767ND04eIlEVcnYejRSK1gEy25OKNSAw+t
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDIY6+Wgj6MqdEd
+Yq6FgH5xMgTBmFqAonR/eshjxY2C6MHs+WmCmNSDik2NgZWIaODvOF9uOEK2U0Zf
+JEG2LcZxoeIEgg/mfII2f4DLy1JYajm/llzwFBzAd/Rkcs3qwP2ba5VKn/pSqNLl
+nKHMXkXO+9SjfHDx95x2dK1dB8eGQGculOMcTm3uK7UlWNO4TSlwG9qHZ1aoM3GI
+g5C1fIpbxJqDVjFq6fFAapE3KRIWIQmKd3E5ICcDErqr/AapxnfO8UFNxVWSOLW7
+ZAfis4w/c8/EAgyQHw42R0dNyjUOZsToF8McCsOpRjGolSU8aUyqspvd8IWJPd5d
+6HBHueXNAgMBAAECggEAV3q9MpVVPQ79TTjBO2Km0D+nt+QMzk8dUHGHfZbGejmm
+Pw96shqJ24rK5FWHs+8lEwmnD3TcGsAr3mjzjtZY5U5oXtNwoYwFRElRLqZqIlLt
+NugrVltRWeyD8j30CuGJVQoYOGWyX9d3ielg8NjO3NcvMtembttLoKK68/vrbH11
+9W7wr5p8/xyMfyl9curnmCFk5QqJ1FBpjPWY05NDIBCUJB0tGAqViCpxEeWPSlvb
+xcElqWfdbtnsYUxYU+iOTHHotoKnz4nLHYK2/njMhlCEyMXfu1DJOd8rg5yXewJF
+v6NhXgWStSexAT1bZ17LROazVcHfWB9QmXF1Fm7vOQKBgQD+dZxPDOi3Y4gCFegn
+Z+epNyl2aPTkseEZxrIqPKLHsGxUfYjQqkX2RdfTrq2vf4vFlN6uCXhSlZKXfLH/
+iQ8FAzqenhVVHK2fv5xB0SE5zNmcHDrHshl+/zUNI2u5AMFECVO2SVbgoFjvgkou
+FolK8XUXfHfb4f732LUyYI0lEwKBgQDJmkWHhzekz3P5iWaAt1SH8bZpt2hqa6Bx
+A4VvMdtmjCxEDETN0Rb3CPYxw3qa3xGfW1y1j/49xi4gr69yaT2Tbca7PFGUmWRo
+OJwfCUB5uBUi6UVytK19OVKReOm4666x8P3YO4cxxSI/HeoSU0HR1kkX9rGmrsGN
+MgUQ15+FnwKBgAKf6/DUzUG3ARwkZbSiWb1hGEhkZMJHI29EoWnWHke5BiUI9nRQ
+jVAxADzqvFfnFOYA1xssddVEPbLaUmu0WjdPBTfFoaqzFQdkzpPPOGyENGpr0B9n
+MuQgdceg6eeKnnO5NOfYcdD3VnOCAInhKaFgRDjty7604hBkZ9oRLOOJAoGBAIJ+
+dmUMlGr80XADjTLh+DhqsA1r542DDv44LkXUetS9BOYjHuIuZnQO+/UoOBNJMsn4
+xGDNzN7FihQkRCeFkZL9arbFi3TpeUGw6vV38qEXE69eWVKvOuEkmpqJLphBDfom
+KNmvZopDtTAvt9SWybL+xp9ZUpK26ZfwebD2MU63AoGBAOa2Kt01DxoqiWiQP/ds
+Mc9wOw1zJsSmIK7wEiW3FkCz8uw3UgjF9ymYY/YAW3eZtuUpuxEzyENb9f21p4b2
+zYoZ7nCUo4TmVXxgCjiEWglg3b/R3xjQr1dAABhTeI8bXMv5r/tMUsnS79uKqwGD
+2Gc1syc3+055K4qcfZHH0XWu
+-----END PRIVATE KEY-----
diff --git a/samples/keystores/generate.sh b/samples/keystores/generate.sh
new file mode 100755
index 0000000..1865d3a
--- /dev/null
+++ b/samples/keystores/generate.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+export DNAME_SUFFIX="OU=commons-ssl, O=apache, L=Victoria, ST=BC, C=CA"
+export PASS=changeit
+export KEYPASS=itchange
+export EXPIRY_IN_YEARS=40
+
+export VALIDITY=`echo 366 \* $EXPIRY_IN_YEARS | bc`
+
+# bouncy-castle BKS
+export TYPE=BKS; export NAME=BC.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# bouncy-castle UBER
+export TYPE=UBER; export NAME=BC.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# bouncy-castle PKCS12
+export TYPE=PKCS12; export NAME=BC.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# bouncy-castle PKCS12-DEF
+export TYPE=PKCS12-DEF; export NAME=BC.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# bouncy-castle PKCS12-3DES-3DES
+export TYPE=PKCS12-3DES-3DES; export NAME=BC.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# bouncy-castle PKCS12-DEF-3DES-3DES
+export TYPE=PKCS12-DEF-3DES-3DES; export NAME=BC.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# SunJCE
+export TYPE=jceks; export NAME=SunJCE.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+# SUN
+export TYPE=jks; export NAME=Sun.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $PASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
+
+
+# SUN with different key password
+export TYPE=jks; export NAME=Sun.2pass.$TYPE.ks;
+rm -f $NAME
+export CMD="$JAVA_HOME/bin/keytool -genkey -v -keyalg RSA -keysize 2048 -sigalg SHA1WithRSA -dname \"CN=$NAME, $DNAME_SUFFIX\" -validity $VALIDITY -keypass $KEYPASS -keystore $NAME -storepass $PASS -storetype $TYPE"
+bash -c "$CMD"
diff --git a/samples/keystores/rsa.key b/samples/keystores/rsa.key
new file mode 100644
index 0000000..1e87d53
--- /dev/null
+++ b/samples/keystores/rsa.key
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFETBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQId8Qhy+607E8CAggA
+MB0GCWCGSAFlAwQBBAQQac2kffj8EBtimaC+HXnM2wSCBMKaK+sjj94S1ZJ0El82
+Wt+oFB7t0Wi1oE4fCWofX4T04VGR+6NYzj0qZ+LiXS/4rw9AQjbCfkYm+WFhMs23
+b37+/jfwZ1N8WYMxfQ94Q4YiN6EknPouqBpKwUqUgXL+WJbmAzMfH877ok3Pc9YR
+5LKwShKJLAQkHlxkDMq6ZWRZuCSVhRzDOvR4bmrwxViE5nmyWJJZmdwz8uI2eEbz
+WA/hCON4N023fqAQrhFMrWtklPVvG78HtCTo9r9x8kNjdOF2rue7eE3TH7ysdr5J
+/xlWVDXjSOVuPzUOdeCmUusjpgC2vSqq+oKF+MsYDN04sUZ6MksZcJnt/aOESc09
+lOHmxoEo0fZ210HCKaCU8yDGvQNyUdAmfmoZ+yDoT7x0AD2WkNGPab6jsCOSaDxN
+RtMoQG7Py7OUElVj0wkidKd7oPOzxZx1WdNG1V/PoGfP/ITAxeBZhM6rq44pLvtL
+nfdkrasQ7zDHwbDO4f1K0KcgDrl3p3Gbj09Vh9Go6ENfImLoF7N4a/Vmh0vtfPJ/
+PsPXUv+fLP/lKJgd9fFPdBbaR2LWcl7sdDSxuFlgFkN0Z0EKT/9S4hWA2IETKGRc
+7lmq+PU2yljkISz6LgJOLO9LC71HavEbDB9VsBmfnj2RkvfXs94HpBQVATG3BF/o
+maTznQel8aMjglxhTZPwB/bGvxf3BYd2zGtDdbrBB4huhgKygyTaHAQMbb9UaIGx
+GtrUyD0mJ7Zj97z+WIbbTcCkqINeDtbatI00SQXCaldN4luSj9cF0+mHIaQJcEQK
+5/mQnDVYD06INUR7kOVI7/4EsBQ8TXkjwwjTAyRM9fcC2DKCt5RJuS++6G2eXm8s
+Iep9neO0YKF0NXARnLw+3qsY7PLUfUeWtTTpUfOBW+i44kW+mw3MqwxlgICgZfp6
+OmkArD0ZpdaMrIJi/EcAN/hqB+DEAkO6qd46cDK3PJkNGDBNCEM48bwNeRwzl5IG
+Dqq3gFyek0DaPpdiGBnP8W9VdG/mfzYCZkaMptRKQg01iN3KHujSZpTrJ+MPfwFc
+eDCIet7L2z8tI4p+Xm+XHBU4+7V4aiplXAqY3Bt3QgnyGe5L+r73nl21/2tpDNGM
+JdYvLecji7KK/uoSE7icYKXuZNM8F8vdEUE3UvSkv3UVStVijZdchV+0nHeTBo1k
+fD3LVWLTUw8SrrOUWpkFAUbNSmuoQxZti9vl+0cBaCipG1cc28opKuIEt1U/HYl+
+GTxOO2W+9vJy7nzm7cw7Tf+HC0ROAbrG0tPOFdePGAp1sWZyq+ox85PMcjqmeMPJ
+6SuMUXzZ/zeRa3MjifY9QywEJY8TsvtMadPAK+jm6otDxOneXcZwzuwHnd5Sygxo
+A1WwlcmrV9eq6748wopD330EZj1oSqz++6givL9nGxuk6IDi+HMmJCGgX0IXnB1q
+pqt2skUTVX5oWTrGnsbGb/JDBqmMl6q0NRGQInTr23GwRftIsBWPHIgpplqpBWPs
+lUXhdZWukX+RJX5oPL6esik5XJvN8d7souKmxWQjgPwzocn2FL1d9l+SfQeVjJVL
+zpyPCACnXFCygpwT6hqfYWz+yXSLQwOFc6CgHV6SAm8Sgz0CIfBVev8PYSgeuNFm
+momSCys=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/samples/rsa.html b/samples/rsa.html
index f03e594..d4d260a 100644
--- a/samples/rsa.html
+++ b/samples/rsa.html
@@ -1,114 +1,115 @@
 <pre>
-java -showversion -cp <a href="../download.html">build/not-yet-commons-ssl-0.3.7.jar</a>  org.apache.commons.ssl.PKCS8Key <a href="rsa/">samples/rsa/*.*</a>
+java -showversion -cp build/not-yet-commons-ssl-0.3.13.jar  org.apache.commons.ssl.PKCS8Key samples/rsa/*.*
 
-java version "1.6.0"
-Java(TM) SE Runtime Environment (build 1.6.0-b105)
-Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
+java version "1.6.0_45"
+Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
+Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
 
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	128	<a href="rsa/openssl_rsa_aes128_cbc.pem">samples/rsa/openssl_rsa_aes128_cbc.pem</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	128	<a href="rsa/openssl_rsa_aes128_cfb.pem">samples/rsa/openssl_rsa_aes128_cfb.pem</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	128	<a href="rsa/openssl_rsa_aes128_ecb.pem">samples/rsa/openssl_rsa_aes128_ecb.pem</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	128	<a href="rsa/openssl_rsa_aes128_ofb.pem">samples/rsa/openssl_rsa_aes128_ofb.pem</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	192	<a href="rsa/openssl_rsa_aes192_cbc.pem">samples/rsa/openssl_rsa_aes192_cbc.pem</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	192	<a href="rsa/openssl_rsa_aes192_cfb.pem">samples/rsa/openssl_rsa_aes192_cfb.pem</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	192	<a href="rsa/openssl_rsa_aes192_ecb.pem">samples/rsa/openssl_rsa_aes192_ecb.pem</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	192	<a href="rsa/openssl_rsa_aes192_ofb.pem">samples/rsa/openssl_rsa_aes192_ofb.pem</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	256	<a href="rsa/openssl_rsa_aes256_cbc.pem">samples/rsa/openssl_rsa_aes256_cbc.pem</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	256	<a href="rsa/openssl_rsa_aes256_cfb.pem">samples/rsa/openssl_rsa_aes256_cfb.pem</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	256	<a href="rsa/openssl_rsa_aes256_ecb.pem">samples/rsa/openssl_rsa_aes256_ecb.pem</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	256	<a href="rsa/openssl_rsa_aes256_ofb.pem">samples/rsa/openssl_rsa_aes256_ofb.pem</a>
-   SUCCESS    	RSA	Blowfish/CBC/PKCS5Padding	128	<a href="rsa/openssl_rsa_blowfish_cbc.pem">samples/rsa/openssl_rsa_blowfish_cbc.pem</a>
-   SUCCESS    	RSA	Blowfish/CFB/NoPadding   	128	<a href="rsa/openssl_rsa_blowfish_cfb.pem">samples/rsa/openssl_rsa_blowfish_cfb.pem</a>
-   SUCCESS    	RSA	Blowfish/ECB/PKCS5Padding	128	<a href="rsa/openssl_rsa_blowfish_ecb.pem">samples/rsa/openssl_rsa_blowfish_ecb.pem</a>
-   SUCCESS    	RSA	Blowfish/OFB/NoPadding   	128	<a href="rsa/openssl_rsa_blowfish_ofb.pem">samples/rsa/openssl_rsa_blowfish_ofb.pem</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/openssl_rsa_des1_cbc.pem">samples/rsa/openssl_rsa_des1_cbc.pem</a>
-   SUCCESS    	RSA	DES/CFB/NoPadding        	 64	<a href="rsa/openssl_rsa_des1_cfb.pem">samples/rsa/openssl_rsa_des1_cfb.pem</a>
-   SUCCESS    	RSA	DES/ECB/PKCS5Padding     	 64	<a href="rsa/openssl_rsa_des1_ecb.pem">samples/rsa/openssl_rsa_des1_ecb.pem</a>
-   SUCCESS    	RSA	DES/OFB/NoPadding        	 64	<a href="rsa/openssl_rsa_des1_ofb.pem">samples/rsa/openssl_rsa_des1_ofb.pem</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/openssl_rsa_des2_cbc.pem">samples/rsa/openssl_rsa_des2_cbc.pem</a>
-   SUCCESS    	RSA	DESede/CFB/NoPadding     	192	<a href="rsa/openssl_rsa_des2_cfb.pem">samples/rsa/openssl_rsa_des2_cfb.pem</a>
-   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	<a href="rsa/openssl_rsa_des2_ecb.pem">samples/rsa/openssl_rsa_des2_ecb.pem</a>
-   SUCCESS    	RSA	DESede/OFB/NoPadding     	192	<a href="rsa/openssl_rsa_des2_ofb.pem">samples/rsa/openssl_rsa_des2_ofb.pem</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/openssl_rsa_des3_cbc.pem">samples/rsa/openssl_rsa_des3_cbc.pem</a>
-   SUCCESS    	RSA	DESede/CFB/NoPadding     	192	<a href="rsa/openssl_rsa_des3_cfb.pem">samples/rsa/openssl_rsa_des3_cfb.pem</a>
-   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	<a href="rsa/openssl_rsa_des3_ecb.pem">samples/rsa/openssl_rsa_des3_ecb.pem</a>
-   SUCCESS    	RSA	DESede/OFB/NoPadding     	192	<a href="rsa/openssl_rsa_des3_ofb.pem">samples/rsa/openssl_rsa_des3_ofb.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	<a href="rsa/openssl_rsa_rc2_128_cbc.pem">samples/rsa/openssl_rsa_rc2_128_cbc.pem</a>
-   SUCCESS    	RSA	RC2/CFB/NoPadding        	128	<a href="rsa/openssl_rsa_rc2_128_cfb.pem">samples/rsa/openssl_rsa_rc2_128_cfb.pem</a>
-   SUCCESS    	RSA	RC2/ECB/PKCS5Padding     	128	<a href="rsa/openssl_rsa_rc2_128_ecb.pem">samples/rsa/openssl_rsa_rc2_128_ecb.pem</a>
-   SUCCESS    	RSA	RC2/OFB/NoPadding        	128	<a href="rsa/openssl_rsa_rc2_128_ofb.pem">samples/rsa/openssl_rsa_rc2_128_ofb.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	<a href="rsa/openssl_rsa_rc2_40.pem">samples/rsa/openssl_rsa_rc2_40.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/openssl_rsa_rc2_64.pem">samples/rsa/openssl_rsa_rc2_64.pem</a>
-   SUCCESS    	RSA	UNENCRYPTED              	  0	<a href="rsa/openssl_rsa_unencrypted.der">samples/rsa/openssl_rsa_unencrypted.der</a>
-   SUCCESS    	RSA	UNENCRYPTED              	  0	<a href="rsa/openssl_rsa_unencrypted.pem">samples/rsa/openssl_rsa_unencrypted.pem</a>
-   SUCCESS    	RSA	UNENCRYPTED              	  0	<a href="rsa/pkcs8_rsa_unencrypted.der">samples/rsa/pkcs8_rsa_unencrypted.der</a>
-   SUCCESS    	RSA	UNENCRYPTED              	  0	<a href="rsa/pkcs8_rsa_unencrypted.pem">samples/rsa/pkcs8_rsa_unencrypted.pem</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md2_des1.der">samples/rsa/pkcs8v1_rsa_md2_des1.der</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md2_des1.pem">samples/rsa/pkcs8v1_rsa_md2_des1.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md2_rc2_64.der">samples/rsa/pkcs8v1_rsa_md2_rc2_64.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md2_rc2_64.pem">samples/rsa/pkcs8v1_rsa_md2_rc2_64.pem</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md5_des1.der">samples/rsa/pkcs8v1_rsa_md5_des1.der</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md5_des1.pem">samples/rsa/pkcs8v1_rsa_md5_des1.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md5_rc2_64.der">samples/rsa/pkcs8v1_rsa_md5_rc2_64.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_md5_rc2_64.pem">samples/rsa/pkcs8v1_rsa_md5_rc2_64.pem</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_sha1_des1.der">samples/rsa/pkcs8v1_rsa_sha1_des1.der</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_sha1_des1.pem">samples/rsa/pkcs8v1_rsa_sha1_des1.pem</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/pkcs8v1_rsa_sha1_des2.der">samples/rsa/pkcs8v1_rsa_sha1_des2.der</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/pkcs8v1_rsa_sha1_des2.pem">samples/rsa/pkcs8v1_rsa_sha1_des2.pem</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/pkcs8v1_rsa_sha1_des3.der">samples/rsa/pkcs8v1_rsa_sha1_des3.der</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/pkcs8v1_rsa_sha1_des3.pem">samples/rsa/pkcs8v1_rsa_sha1_des3.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	<a href="rsa/pkcs8v1_rsa_sha1_rc2_128.der">samples/rsa/pkcs8v1_rsa_sha1_rc2_128.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	<a href="rsa/pkcs8v1_rsa_sha1_rc2_128.pem">samples/rsa/pkcs8v1_rsa_sha1_rc2_128.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	<a href="rsa/pkcs8v1_rsa_sha1_rc2_40.der">samples/rsa/pkcs8v1_rsa_sha1_rc2_40.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	<a href="rsa/pkcs8v1_rsa_sha1_rc2_40.pem">samples/rsa/pkcs8v1_rsa_sha1_rc2_40.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_sha1_rc2_64.der">samples/rsa/pkcs8v1_rsa_sha1_rc2_64.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v1_rsa_sha1_rc2_64.pem">samples/rsa/pkcs8v1_rsa_sha1_rc2_64.pem</a>
-   SUCCESS    	RSA	RC4                      	128	<a href="rsa/pkcs8v1_rsa_sha1_rc4_128.der">samples/rsa/pkcs8v1_rsa_sha1_rc4_128.der</a>
-   SUCCESS    	RSA	RC4                      	128	<a href="rsa/pkcs8v1_rsa_sha1_rc4_128.pem">samples/rsa/pkcs8v1_rsa_sha1_rc4_128.pem</a>
-   SUCCESS    	RSA	RC4                      	 40	<a href="rsa/pkcs8v1_rsa_sha1_rc4_40.der">samples/rsa/pkcs8v1_rsa_sha1_rc4_40.der</a>
-   SUCCESS    	RSA	RC4                      	 40	<a href="rsa/pkcs8v1_rsa_sha1_rc4_40.pem">samples/rsa/pkcs8v1_rsa_sha1_rc4_40.pem</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	128	<a href="rsa/pkcs8v2_rsa_aes128_cbc.der">samples/rsa/pkcs8v2_rsa_aes128_cbc.der</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	128	<a href="rsa/pkcs8v2_rsa_aes128_cbc.pem">samples/rsa/pkcs8v2_rsa_aes128_cbc.pem</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	128	<a href="rsa/pkcs8v2_rsa_aes128_cfb.der">samples/rsa/pkcs8v2_rsa_aes128_cfb.der</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	128	<a href="rsa/pkcs8v2_rsa_aes128_cfb.pem">samples/rsa/pkcs8v2_rsa_aes128_cfb.pem</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	128	<a href="rsa/pkcs8v2_rsa_aes128_ecb.der">samples/rsa/pkcs8v2_rsa_aes128_ecb.der</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	128	<a href="rsa/pkcs8v2_rsa_aes128_ecb.pem">samples/rsa/pkcs8v2_rsa_aes128_ecb.pem</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	128	<a href="rsa/pkcs8v2_rsa_aes128_ofb.der">samples/rsa/pkcs8v2_rsa_aes128_ofb.der</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	128	<a href="rsa/pkcs8v2_rsa_aes128_ofb.pem">samples/rsa/pkcs8v2_rsa_aes128_ofb.pem</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	192	<a href="rsa/pkcs8v2_rsa_aes192_cbc.der">samples/rsa/pkcs8v2_rsa_aes192_cbc.der</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	192	<a href="rsa/pkcs8v2_rsa_aes192_cbc.pem">samples/rsa/pkcs8v2_rsa_aes192_cbc.pem</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	192	<a href="rsa/pkcs8v2_rsa_aes192_cfb.der">samples/rsa/pkcs8v2_rsa_aes192_cfb.der</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	192	<a href="rsa/pkcs8v2_rsa_aes192_cfb.pem">samples/rsa/pkcs8v2_rsa_aes192_cfb.pem</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	192	<a href="rsa/pkcs8v2_rsa_aes192_ecb.der">samples/rsa/pkcs8v2_rsa_aes192_ecb.der</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	192	<a href="rsa/pkcs8v2_rsa_aes192_ecb.pem">samples/rsa/pkcs8v2_rsa_aes192_ecb.pem</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	192	<a href="rsa/pkcs8v2_rsa_aes192_ofb.der">samples/rsa/pkcs8v2_rsa_aes192_ofb.der</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	192	<a href="rsa/pkcs8v2_rsa_aes192_ofb.pem">samples/rsa/pkcs8v2_rsa_aes192_ofb.pem</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	256	<a href="rsa/pkcs8v2_rsa_aes256_cbc.der">samples/rsa/pkcs8v2_rsa_aes256_cbc.der</a>
-   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	256	<a href="rsa/pkcs8v2_rsa_aes256_cbc.pem">samples/rsa/pkcs8v2_rsa_aes256_cbc.pem</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	256	<a href="rsa/pkcs8v2_rsa_aes256_cfb.der">samples/rsa/pkcs8v2_rsa_aes256_cfb.der</a>
-   SUCCESS    	RSA	AES/CFB/NoPadding        	256	<a href="rsa/pkcs8v2_rsa_aes256_cfb.pem">samples/rsa/pkcs8v2_rsa_aes256_cfb.pem</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	256	<a href="rsa/pkcs8v2_rsa_aes256_ecb.der">samples/rsa/pkcs8v2_rsa_aes256_ecb.der</a>
-   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	256	<a href="rsa/pkcs8v2_rsa_aes256_ecb.pem">samples/rsa/pkcs8v2_rsa_aes256_ecb.pem</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	256	<a href="rsa/pkcs8v2_rsa_aes256_ofb.der">samples/rsa/pkcs8v2_rsa_aes256_ofb.der</a>
-   SUCCESS    	RSA	AES/OFB/NoPadding        	256	<a href="rsa/pkcs8v2_rsa_aes256_ofb.pem">samples/rsa/pkcs8v2_rsa_aes256_ofb.pem</a>
-   SUCCESS    	RSA	Blowfish/CBC/PKCS5Padding	128	<a href="rsa/pkcs8v2_rsa_blowfish_cbc.der">samples/rsa/pkcs8v2_rsa_blowfish_cbc.der</a>
-   SUCCESS    	RSA	Blowfish/CBC/PKCS5Padding	128	<a href="rsa/pkcs8v2_rsa_blowfish_cbc.pem">samples/rsa/pkcs8v2_rsa_blowfish_cbc.pem</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v2_rsa_des1_cbc.der">samples/rsa/pkcs8v2_rsa_des1_cbc.der</a>
-   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v2_rsa_des1_cbc.pem">samples/rsa/pkcs8v2_rsa_des1_cbc.pem</a>
-   SUCCESS    	RSA	DES/CFB/NoPadding        	 64	<a href="rsa/pkcs8v2_rsa_des1_cfb.der">samples/rsa/pkcs8v2_rsa_des1_cfb.der</a>
-   SUCCESS    	RSA	DES/CFB/NoPadding        	 64	<a href="rsa/pkcs8v2_rsa_des1_cfb.pem">samples/rsa/pkcs8v2_rsa_des1_cfb.pem</a>
-   SUCCESS    	RSA	DES/ECB/PKCS5Padding     	 64	<a href="rsa/pkcs8v2_rsa_des1_ecb.der">samples/rsa/pkcs8v2_rsa_des1_ecb.der</a>
-   SUCCESS    	RSA	DES/ECB/PKCS5Padding     	 64	<a href="rsa/pkcs8v2_rsa_des1_ecb.pem">samples/rsa/pkcs8v2_rsa_des1_ecb.pem</a>
-   SUCCESS    	RSA	DES/OFB/NoPadding        	 64	<a href="rsa/pkcs8v2_rsa_des1_ofb.der">samples/rsa/pkcs8v2_rsa_des1_ofb.der</a>
-   SUCCESS    	RSA	DES/OFB/NoPadding        	 64	<a href="rsa/pkcs8v2_rsa_des1_ofb.pem">samples/rsa/pkcs8v2_rsa_des1_ofb.pem</a>
-   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	<a href="rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.der">samples/rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.der</a>
-   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	<a href="rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.pem">samples/rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.pem</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/pkcs8v2_rsa_des3.der">samples/rsa/pkcs8v2_rsa_des3.der</a>
-   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	<a href="rsa/pkcs8v2_rsa_des3.pem">samples/rsa/pkcs8v2_rsa_des3.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	<a href="rsa/pkcs8v2_rsa_rc2_128.der">samples/rsa/pkcs8v2_rsa_rc2_128.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	<a href="rsa/pkcs8v2_rsa_rc2_128.pem">samples/rsa/pkcs8v2_rsa_rc2_128.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	<a href="rsa/pkcs8v2_rsa_rc2_40.der">samples/rsa/pkcs8v2_rsa_rc2_40.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	<a href="rsa/pkcs8v2_rsa_rc2_40.pem">samples/rsa/pkcs8v2_rsa_rc2_40.pem</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v2_rsa_rc2_64.der">samples/rsa/pkcs8v2_rsa_rc2_64.der</a>
-   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	<a href="rsa/pkcs8v2_rsa_rc2_64.pem">samples/rsa/pkcs8v2_rsa_rc2_64.pem</a>
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	128	samples/rsa/openssl_rsa_aes128_cbc.pem
+   SUCCESS    	RSA	AES/CFB/NoPadding        	128	samples/rsa/openssl_rsa_aes128_cfb.pem
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	128	samples/rsa/openssl_rsa_aes128_ecb.pem
+   SUCCESS    	RSA	AES/OFB/NoPadding        	128	samples/rsa/openssl_rsa_aes128_ofb.pem
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	192	samples/rsa/openssl_rsa_aes192_cbc.pem
+   SUCCESS    	RSA	AES/CFB/NoPadding        	192	samples/rsa/openssl_rsa_aes192_cfb.pem
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	192	samples/rsa/openssl_rsa_aes192_ecb.pem
+   SUCCESS    	RSA	AES/OFB/NoPadding        	192	samples/rsa/openssl_rsa_aes192_ofb.pem
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	256	samples/rsa/openssl_rsa_aes256_cbc.pem
+   SUCCESS    	RSA	AES/CFB/NoPadding        	256	samples/rsa/openssl_rsa_aes256_cfb.pem
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	256	samples/rsa/openssl_rsa_aes256_ecb.pem
+   SUCCESS    	RSA	AES/OFB/NoPadding        	256	samples/rsa/openssl_rsa_aes256_ofb.pem
+   SUCCESS    	RSA	Blowfish/CBC/PKCS5Padding	128	samples/rsa/openssl_rsa_blowfish_cbc.pem
+   SUCCESS    	RSA	Blowfish/CFB/NoPadding   	128	samples/rsa/openssl_rsa_blowfish_cfb.pem
+   SUCCESS    	RSA	Blowfish/ECB/PKCS5Padding	128	samples/rsa/openssl_rsa_blowfish_ecb.pem
+   SUCCESS    	RSA	Blowfish/OFB/NoPadding   	128	samples/rsa/openssl_rsa_blowfish_ofb.pem
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/openssl_rsa_des1_cbc.pem
+   SUCCESS    	RSA	DES/CFB/NoPadding        	 64	samples/rsa/openssl_rsa_des1_cfb.pem
+   SUCCESS    	RSA	DES/ECB/PKCS5Padding     	 64	samples/rsa/openssl_rsa_des1_ecb.pem
+   SUCCESS    	RSA	DES/OFB/NoPadding        	 64	samples/rsa/openssl_rsa_des1_ofb.pem
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/openssl_rsa_des2_cbc.pem
+   SUCCESS    	RSA	DESede/CFB/NoPadding     	192	samples/rsa/openssl_rsa_des2_cfb.pem
+   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	samples/rsa/openssl_rsa_des2_ecb.pem
+   SUCCESS    	RSA	DESede/OFB/NoPadding     	192	samples/rsa/openssl_rsa_des2_ofb.pem
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/openssl_rsa_des3_cbc.pem
+   SUCCESS    	RSA	DESede/CFB/NoPadding     	192	samples/rsa/openssl_rsa_des3_cfb.pem
+   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	samples/rsa/openssl_rsa_des3_ecb.pem
+   SUCCESS    	RSA	DESede/OFB/NoPadding     	192	samples/rsa/openssl_rsa_des3_ofb.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	samples/rsa/openssl_rsa_rc2_128_cbc.pem
+   SUCCESS    	RSA	RC2/CFB/NoPadding        	128	samples/rsa/openssl_rsa_rc2_128_cfb.pem
+   SUCCESS    	RSA	RC2/ECB/PKCS5Padding     	128	samples/rsa/openssl_rsa_rc2_128_ecb.pem
+   SUCCESS    	RSA	RC2/OFB/NoPadding        	128	samples/rsa/openssl_rsa_rc2_128_ofb.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	samples/rsa/openssl_rsa_rc2_40.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/openssl_rsa_rc2_64.pem
+   SUCCESS    	RSA	UNENCRYPTED              	  0	samples/rsa/openssl_rsa_unencrypted.der
+   SUCCESS    	RSA	UNENCRYPTED              	  0	samples/rsa/openssl_rsa_unencrypted.pem
+   SUCCESS    	RSA	UNENCRYPTED              	  0	samples/rsa/pkcs8_rsa_unencrypted.der
+   SUCCESS    	RSA	UNENCRYPTED              	  0	samples/rsa/pkcs8_rsa_unencrypted.pem
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md2_des1.der
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md2_des1.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md2_rc2_64.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md2_rc2_64.pem
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md5_des1.der
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md5_des1.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md5_rc2_64.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_md5_rc2_64.pem
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_sha1_des1.der
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_sha1_des1.pem
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/pkcs8v1_rsa_sha1_des2.der
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/pkcs8v1_rsa_sha1_des2.pem
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/pkcs8v1_rsa_sha1_des3.der
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/pkcs8v1_rsa_sha1_des3.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	samples/rsa/pkcs8v1_rsa_sha1_rc2_128.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	samples/rsa/pkcs8v1_rsa_sha1_rc2_128.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	samples/rsa/pkcs8v1_rsa_sha1_rc2_40.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	samples/rsa/pkcs8v1_rsa_sha1_rc2_40.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_sha1_rc2_64.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v1_rsa_sha1_rc2_64.pem
+   SUCCESS    	RSA	RC4                      	128	samples/rsa/pkcs8v1_rsa_sha1_rc4_128.der
+   SUCCESS    	RSA	RC4                      	128	samples/rsa/pkcs8v1_rsa_sha1_rc4_128.pem
+   SUCCESS    	RSA	RC4                      	 40	samples/rsa/pkcs8v1_rsa_sha1_rc4_40.der
+   SUCCESS    	RSA	RC4                      	 40	samples/rsa/pkcs8v1_rsa_sha1_rc4_40.pem
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	128	samples/rsa/pkcs8v2_rsa_aes128_cbc.der
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	128	samples/rsa/pkcs8v2_rsa_aes128_cbc.pem
+   SUCCESS    	RSA	AES/CFB/NoPadding        	128	samples/rsa/pkcs8v2_rsa_aes128_cfb.der
+   SUCCESS    	RSA	AES/CFB/NoPadding        	128	samples/rsa/pkcs8v2_rsa_aes128_cfb.pem
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	128	samples/rsa/pkcs8v2_rsa_aes128_ecb.der
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	128	samples/rsa/pkcs8v2_rsa_aes128_ecb.pem
+   SUCCESS    	RSA	AES/OFB/NoPadding        	128	samples/rsa/pkcs8v2_rsa_aes128_ofb.der
+   SUCCESS    	RSA	AES/OFB/NoPadding        	128	samples/rsa/pkcs8v2_rsa_aes128_ofb.pem
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	192	samples/rsa/pkcs8v2_rsa_aes192_cbc.der
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	192	samples/rsa/pkcs8v2_rsa_aes192_cbc.pem
+   SUCCESS    	RSA	AES/CFB/NoPadding        	192	samples/rsa/pkcs8v2_rsa_aes192_cfb.der
+   SUCCESS    	RSA	AES/CFB/NoPadding        	192	samples/rsa/pkcs8v2_rsa_aes192_cfb.pem
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	192	samples/rsa/pkcs8v2_rsa_aes192_ecb.der
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	192	samples/rsa/pkcs8v2_rsa_aes192_ecb.pem
+   SUCCESS    	RSA	AES/OFB/NoPadding        	192	samples/rsa/pkcs8v2_rsa_aes192_ofb.der
+   SUCCESS    	RSA	AES/OFB/NoPadding        	192	samples/rsa/pkcs8v2_rsa_aes192_ofb.pem
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	256	samples/rsa/pkcs8v2_rsa_aes256_cbc.der
+   SUCCESS    	RSA	AES/CBC/PKCS5Padding     	256	samples/rsa/pkcs8v2_rsa_aes256_cbc.pem
+   SUCCESS    	RSA	AES/CFB/NoPadding        	256	samples/rsa/pkcs8v2_rsa_aes256_cfb.der
+   SUCCESS    	RSA	AES/CFB/NoPadding        	256	samples/rsa/pkcs8v2_rsa_aes256_cfb.pem
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	256	samples/rsa/pkcs8v2_rsa_aes256_ecb.der
+   SUCCESS    	RSA	AES/ECB/PKCS5Padding     	256	samples/rsa/pkcs8v2_rsa_aes256_ecb.pem
+   SUCCESS    	RSA	AES/OFB/NoPadding        	256	samples/rsa/pkcs8v2_rsa_aes256_ofb.der
+   SUCCESS    	RSA	AES/OFB/NoPadding        	256	samples/rsa/pkcs8v2_rsa_aes256_ofb.pem
+   SUCCESS    	RSA	Blowfish/CBC/PKCS5Padding	128	samples/rsa/pkcs8v2_rsa_blowfish_cbc.der
+   SUCCESS    	RSA	Blowfish/CBC/PKCS5Padding	128	samples/rsa/pkcs8v2_rsa_blowfish_cbc.pem
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v2_rsa_des1_cbc.der
+   SUCCESS    	RSA	DES/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v2_rsa_des1_cbc.pem
+   SUCCESS    	RSA	DES/CFB/NoPadding        	 64	samples/rsa/pkcs8v2_rsa_des1_cfb.der
+   SUCCESS    	RSA	DES/CFB/NoPadding        	 64	samples/rsa/pkcs8v2_rsa_des1_cfb.pem
+   SUCCESS    	RSA	DES/ECB/PKCS5Padding     	 64	samples/rsa/pkcs8v2_rsa_des1_ecb.der
+   SUCCESS    	RSA	DES/ECB/PKCS5Padding     	 64	samples/rsa/pkcs8v2_rsa_des1_ecb.pem
+   SUCCESS    	RSA	DES/OFB/NoPadding        	 64	samples/rsa/pkcs8v2_rsa_des1_ofb.der
+   SUCCESS    	RSA	DES/OFB/NoPadding        	 64	samples/rsa/pkcs8v2_rsa_des1_ofb.pem
+   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	samples/rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.der
+   SUCCESS    	RSA	DESede/ECB/PKCS5Padding  	192	samples/rsa/pkcs8v2_rsa_des2_ecb_SEEMS_WRONG.pem
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/pkcs8v2_rsa_des3.der
+   SUCCESS    	RSA	DESede/CBC/PKCS5Padding  	192	samples/rsa/pkcs8v2_rsa_des3.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	samples/rsa/pkcs8v2_rsa_rc2_128.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	128	samples/rsa/pkcs8v2_rsa_rc2_128.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	samples/rsa/pkcs8v2_rsa_rc2_40.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 40	samples/rsa/pkcs8v2_rsa_rc2_40.pem
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v2_rsa_rc2_64.der
+   SUCCESS    	RSA	RC2/CBC/PKCS5Padding     	 64	samples/rsa/pkcs8v2_rsa_rc2_64.pem
 </pre>
+
diff --git a/src/java/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java b/src/java/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java
index 03bf14e..df7f095 100644
--- a/src/java/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java
+++ b/src/java/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java
@@ -1,7 +1,7 @@
 /*
  * $Header$
- * $Revision: 129 $
- * $Date: 2007-11-14 19:21:33 -0800 (Wed, 14 Nov 2007) $
+ * $Revision: 168 $
+ * $Date: 2014-05-06 16:25:46 -0700 (Tue, 06 May 2014) $
  *
  * ====================================================================
  *
@@ -36,6 +36,7 @@ import org.apache.commons.ssl.TrustMaterial;
 import java.io.IOException;
 import java.net.URL;
 import java.security.GeneralSecurityException;
+import java.security.KeyStoreException;
 
 /**
  * <p/>
@@ -182,13 +183,20 @@ public class AuthSSLProtocolSocketFactory extends HttpSecureProtocol {
             super.setKeyMaterial(km);
         }
 
-        // prepare trust material1
+        // prepare trust material
         if (truststoreUrl != null) {
             char[] tsPass = null;
             if (truststorePassword != null) {
                 tsPass = truststorePassword.toCharArray();
             }
-            TrustMaterial tm = new KeyMaterial(truststoreUrl, tsPass);
+            TrustMaterial tm;
+            try {
+                tm = new KeyMaterial(truststoreUrl, tsPass);
+            } catch (KeyStoreException kse) {
+                // KeyMaterial constructor blows up in no keys found,
+                // so we fall back to TrustMaterial constructor instead.
+                tm = new TrustMaterial(truststoreUrl, tsPass);
+            }
             super.setTrustMaterial(tm);
         }
     }
diff --git a/src/java/org/apache/commons/httpclient/contrib/ssl/TrustSSLProtocolSocketFactory.java b/src/java/org/apache/commons/httpclient/contrib/ssl/TrustSSLProtocolSocketFactory.java
index fc1a847..bb3dba2 100644
--- a/src/java/org/apache/commons/httpclient/contrib/ssl/TrustSSLProtocolSocketFactory.java
+++ b/src/java/org/apache/commons/httpclient/contrib/ssl/TrustSSLProtocolSocketFactory.java
@@ -27,6 +27,7 @@ package org.apache.commons.httpclient.contrib.ssl;
 
 import org.apache.commons.ssl.HttpSecureProtocol;
 import org.apache.commons.ssl.KeyMaterial;
+import org.apache.commons.ssl.TrustMaterial;
 
 import java.io.IOException;
 import java.net.Socket;
@@ -192,8 +193,15 @@ public class TrustSSLProtocolSocketFactory extends HttpSecureProtocol {
     public TrustSSLProtocolSocketFactory(String pathToTrustStore, char[] password)
         throws GeneralSecurityException, IOException {
         super();
-        KeyMaterial km = new KeyMaterial(pathToTrustStore, password);
-        super.setTrustMaterial(km);
+        TrustMaterial tm;
+        try {
+            tm = new KeyMaterial(pathToTrustStore, password);
+        } catch (KeyStoreException kse) {
+            // KeyMaterial constructor blows up in no keys found,
+            // so we fall back to TrustMaterial constructor instead.
+            tm = new TrustMaterial(pathToTrustStore, password);
+        }
+        super.setTrustMaterial(tm);
     }
 
 }
diff --git a/src/java/org/apache/commons/ssl/ASN1Structure.java b/src/java/org/apache/commons/ssl/ASN1Structure.java
index 6dd69ca..8ae66c4 100644
--- a/src/java/org/apache/commons/ssl/ASN1Structure.java
+++ b/src/java/org/apache/commons/ssl/ASN1Structure.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/ASN1Structure.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/ASN1Structure.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/ASN1Util.java b/src/java/org/apache/commons/ssl/ASN1Util.java
index c73a224..5a62bf8 100644
--- a/src/java/org/apache/commons/ssl/ASN1Util.java
+++ b/src/java/org/apache/commons/ssl/ASN1Util.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/ASN1Util.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/ASN1Util.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/Base64.java b/src/java/org/apache/commons/ssl/Base64.java
index aac382f..99dc717 100644
--- a/src/java/org/apache/commons/ssl/Base64.java
+++ b/src/java/org/apache/commons/ssl/Base64.java
@@ -1,55 +1,64 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Base64.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
  *
- * ====================================================================
- * 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/>.
+ *      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.
  */
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.UTF8;
+
+import java.math.BigInteger;
+
 /**
  * Provides Base64 encoding and decoding as defined by RFC 2045.
- * <p/>
- * <p>This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite>
- * from RFC 2045 <cite>Multipurpose Internet Mail Extensions (MIME) Part One:
- * Format of Internet Message Bodies</cite> by Freed and Borenstein.</p>
  *
- * @author Apache Software Foundation
- * @version $Id: Base64.java 121 2007-11-14 05:26:57Z julius $
+ * <p>
+ * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
+ * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
+ * </p>
+ * <p>
+ * The class can be parameterized in the following manner with various constructors:
+ * <ul>
+ * <li>URL-safe mode: Default off.</li>
+ * <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of
+ * 4 in the encoded data.
+ * <li>Line separator: Default is CRLF ("\r\n")</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
+ * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
+ * </p>
+ *
  * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
- * @since 1.0-dev
+ * @author Apache Software Foundation
+ * @since 1.0
+ * @version $Id: Base64.java 155 2009-09-17 21:00:58Z julius $
  */
 public class Base64 {
+    private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
+
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
 
     /**
      * Chunk size per RFC 2045 section 6.8.
-     * <p/>
-     * <p>The character limit does not count the trailing CRLF, but counts
-     * all other characters, including any equal signs.</p>
+     *
+     * <p>
+     * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
+     * equal signs.
+     * </p>
      *
      * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
      */
@@ -58,125 +67,545 @@ public class Base64 {
     /**
      * Chunk separator per RFC 2045 section 2.1.
      *
+     * <p>
+     * N.B. The next major release may break compatibility and make this field private.
+     * </p>
+     *
      * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
      */
-    static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
+    static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
+
+    /**
+     * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
+     * equivalents as specified in Table 1 of RFC 2045.
+     *
+     * Thanks to "commons" project in ws.apache.org for this code.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     */
+    private static final byte[] STANDARD_ENCODE_TABLE = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+    };
 
-    /** The base length. */
-    static final int BASELENGTH = 255;
+    /**
+     * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and /
+     * changed to - and _ to make the encoded Base64 results more URL-SAFE.
+     * This table is only used when the Base64's mode is set to URL-SAFE.
+     */
+    private static final byte[] URL_SAFE_ENCODE_TABLE = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
+    };
 
-    /** Lookup length. */
-    static final int LOOKUPLENGTH = 64;
+    /**
+     * Byte used to pad output.
+     */
+    private static final byte PAD = '=';
 
-    /** Used to calculate the number of bits in a byte. */
-    static final int EIGHTBIT = 8;
+    /**
+     * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in
+     * Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64
+     * alphabet but fall within the bounds of the array are translated to -1.
+     *
+     * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both
+     * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
+     *
+     * Thanks to "commons" project in ws.apache.org for this code.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     */
+    private static final byte[] DECODE_TABLE = {
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
+            55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
+            5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+            24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+            35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+    };
+
+    /** Mask used to extract 6 bits, used when encoding */
+    private static final int MASK_6BITS = 0x3f;
+
+    /** Mask used to extract 8 bits, used in decoding base64 bytes */
+    private static final int MASK_8BITS = 0xff;
+
+    // The static final fields above are used for the original static byte[] methods on Base64.
+    // The private member fields below are used with the new streaming approach, which requires
+    // some state be preserved between calls of encode() and decode().
 
-    /** Used when encoding something which has fewer than 24 bits. */
-    static final int SIXTEENBIT = 16;
+    /**
+     * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able
+     * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch
+     * between the two modes.
+     */
+    private final byte[] encodeTable;
 
-    /** Used to determine how many bits data contains. */
-    static final int TWENTYFOURBITGROUP = 24;
+    /**
+     * Line length for encoding. Not used when decoding. A value of zero or less implies no chunking of the base64
+     * encoded data.
+     */
+    private final int lineLength;
 
-    /** Used to get the number of Quadruples. */
-    static final int FOURBYTE = 4;
+    /**
+     * Line separator for encoding. Not used when decoding. Only used if lineLength > 0.
+     */
+    private final byte[] lineSeparator;
 
-    /** Used to test the sign of a byte. */
-    static final int SIGN = -128;
+    /**
+     * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
+     * <code>decodeSize = 3 + lineSeparator.length;</code>
+     */
+    private final int decodeSize;
 
-    /** Byte used to pad output. */
-    static final byte PAD = (byte) '=';
+    /**
+     * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
+     * <code>encodeSize = 4 + lineSeparator.length;</code>
+     */
+    private final int encodeSize;
+
+    /**
+     * Buffer for streaming.
+     */
+    private byte[] buffer;
+
+    /**
+     * Position where next character should be written in the buffer.
+     */
+    private int pos;
+
+    /**
+     * Position where next character should be read from the buffer.
+     */
+    private int readPos;
+
+    /**
+     * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
+     * make sure each encoded line never goes beyond lineLength (if lineLength > 0).
+     */
+    private int currentLinePos;
+
+    /**
+     * Writes to the buffer only occur after every 3 reads when encoding, an every 4 reads when decoding. This variable
+     * helps track that.
+     */
+    private int modulus;
+
+    /**
+     * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this Base64 object becomes useless,
+     * and must be thrown away.
+     */
+    private boolean eof;
+
+    /**
+     * Place holder for the 3 bytes we're dealing with for our base64 logic. Bitwise operations store and extract the
+     * base64 encoding or decoding from this variable.
+     */
+    private int x;
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
+     * </p>
+     *
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     */
+    public Base64() {
+        this(false);
+    }
+
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode.
+     * <p>
+     * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
+     * </p>
+     *
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     *
+     * @param urlSafe
+     *            if <code>true</code>, URL-safe encoding is used. In most cases this should be set to
+     *            <code>false</code>.
+     * @since 1.4
+     */
+    public Base64(boolean urlSafe) {
+        this(CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe);
+    }
 
     /**
-     * Contains the Base64 values <code>0</code> through <code>63</code> accessed by using character encodings as
-     * indices.
-     * <p/>
-     * For example, <code>base64Alphabet['+']</code> returns <code>62</code>.
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is
+     * STANDARD_ENCODE_TABLE.
+     * </p>
+     * <p>
+     * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
      * </p>
-     * <p/>
-     * The value of undefined encodings is <code>-1</code>.
+     * <p>
+     * When decoding all variants are supported.
      * </p>
+     *
+     * @param lineLength
+     *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
+     *            If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding.
+     * @since 1.4
      */
-    private static byte[] base64Alphabet = new byte[BASELENGTH];
+    public Base64(int lineLength) {
+        this(lineLength, CHUNK_SEPARATOR);
+    }
 
     /**
-     * <p/>
-     * Contains the Base64 encodings <code>A</code> through <code>Z</code>, followed by <code>a</code> through
-     * <code>z</code>, followed by <code>0</code> through <code>9</code>, followed by <code>+</code>, and
-     * <code>/</code>.
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length and line separator are given in the constructor, and the encoding table is
+     * STANDARD_ENCODE_TABLE.
      * </p>
-     * <p/>
-     * This array is accessed by using character values as indices.
+     * <p>
+     * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
      * </p>
-     * <p/>
-     * For example, <code>lookUpBase64Alphabet[62] </code> returns <code>'+'</code>.
+     * <p>
+     * When decoding all variants are supported.
      * </p>
+     *
+     * @param lineLength
+     *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
+     *            If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding.
+     * @param lineSeparator
+     *            Each line of encoded data will end with this sequence of bytes.
+     * @throws IllegalArgumentException
+     *             Thrown when the provided lineSeparator included some base64 characters.
+     * @since 1.4
      */
-    private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
+    public Base64(int lineLength, byte[] lineSeparator) {
+        this(lineLength, lineSeparator, false);
+    }
 
-    // Populating the lookup and character arrays
-    static {
-        for (int i = 0; i < BASELENGTH; i++) {
-            base64Alphabet[i] = (byte) -1;
+    /**
+     * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
+     * <p>
+     * When encoding the line length and line separator are given in the constructor, and the encoding table is
+     * STANDARD_ENCODE_TABLE.
+     * </p>
+     * <p>
+     * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
+     * </p>
+     * <p>
+     * When decoding all variants are supported.
+     * </p>
+     *
+     * @param lineLength
+     *            Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
+     *            If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding.
+     * @param lineSeparator
+     *            Each line of encoded data will end with this sequence of bytes.
+     * @param urlSafe
+     *            Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode
+     *            operations. Decoding seamlessly handles both modes.
+     * @throws IllegalArgumentException
+     *             The provided lineSeparator included some base64 characters. That's not going to work!
+     * @since 1.4
+     */
+    public Base64(int lineLength, byte[] lineSeparator, boolean urlSafe) {
+        if (lineSeparator == null) {
+            lineLength = 0;  // disable chunk-separating
+            lineSeparator = CHUNK_SEPARATOR;  // this just gets ignored
         }
-        for (int i = 'Z'; i >= 'A'; i--) {
-            base64Alphabet[i] = (byte) (i - 'A');
+        this.lineLength = lineLength > 0 ? (lineLength / 4) * 4 : 0;
+        this.lineSeparator = new byte[lineSeparator.length];
+        System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
+        if (lineLength > 0) {
+            this.encodeSize = 4 + lineSeparator.length;
+        } else {
+            this.encodeSize = 4;
         }
-        for (int i = 'z'; i >= 'a'; i--) {
-            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        this.decodeSize = this.encodeSize - 1;
+        if (containsBase64Byte(lineSeparator)) {
+            String sep = UTF8.toString(lineSeparator);
+            throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]");
         }
-        for (int i = '9'; i >= '0'; i--) {
-            base64Alphabet[i] = (byte) (i - '0' + 52);
+        this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
+    }
+
+    /**
+     * Returns our current encode mode. True if we're URL-SAFE, false otherwise.
+     *
+     * @return true if we're in URL-SAFE mode, false otherwise.
+     * @since 1.4
+     */
+    public boolean isUrlSafe() {
+        return this.encodeTable == URL_SAFE_ENCODE_TABLE;
+    }
+
+    /**
+     * Returns true if this Base64 object has buffered data for reading.
+     *
+     * @return true if there is Base64 object still available for reading.
+     */
+    boolean hasData() {
+        return this.buffer != null;
+    }
+
+    /**
+     * Returns the amount of buffered data available for reading.
+     *
+     * @return The amount of buffered data available for reading.
+     */
+    int avail() {
+        return buffer != null ? pos - readPos : 0;
+    }
+
+    /** Doubles our buffer. */
+    private void resizeBuffer() {
+        if (buffer == null) {
+            buffer = new byte[DEFAULT_BUFFER_SIZE];
+            pos = 0;
+            readPos = 0;
+        } else {
+            byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR];
+            System.arraycopy(buffer, 0, b, 0, buffer.length);
+            buffer = b;
         }
+    }
 
-        base64Alphabet['+'] = 62;
-        base64Alphabet['/'] = 63;
+    /**
+     * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail
+     * bytes. Returns how many bytes were actually extracted.
+     *
+     * @param b
+     *            byte[] array to extract the buffered data into.
+     * @param bPos
+     *            position in byte[] array to start extraction at.
+     * @param bAvail
+     *            amount of bytes we're allowed to extract. We may extract fewer (if fewer are available).
+     * @return The number of bytes successfully extracted into the provided byte[] array.
+     */
+    int readResults(byte[] b, int bPos, int bAvail) {
+        if (buffer != null) {
+            int len = Math.min(avail(), bAvail);
+            if (buffer != b) {
+                System.arraycopy(buffer, readPos, b, bPos, len);
+                readPos += len;
+                if (readPos >= pos) {
+                    buffer = null;
+                }
+            } else {
+                // Re-using the original consumer's output array is only
+                // allowed for one round.
+                buffer = null;
+            }
+            return len;
+        }
+        return eof ? -1 : 0;
+    }
 
-        for (int i = 0; i <= 25; i++) {
-            lookUpBase64Alphabet[i] = (byte) ('A' + i);
+    /**
+     * Sets the streaming buffer. This is a small optimization where we try to buffer directly to the consumer's output
+     * array for one round (if the consumer calls this method first) instead of starting our own buffer.
+     *
+     * @param out
+     *            byte[] array to buffer directly to.
+     * @param outPos
+     *            Position to start buffering into.
+     * @param outAvail
+     *            Amount of bytes available for direct buffering.
+     */
+    void setInitialBuffer(byte[] out, int outPos, int outAvail) {
+        // We can re-use consumer's original output array under
+        // special circumstances, saving on some System.arraycopy().
+        if (out != null && out.length == outAvail) {
+            buffer = out;
+            pos = outPos;
+            readPos = outPos;
         }
+    }
 
-        for (int i = 26, j = 0; i <= 51; i++, j++) {
-            lookUpBase64Alphabet[i] = (byte) ('a' + j);
+    /**
+     * <p>
+     * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with
+     * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last
+     * remaining bytes (if not multiple of 3).
+     * </p>
+     * <p>
+     * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     * </p>
+     *
+     * @param in
+     *            byte[] array of binary data to base64 encode.
+     * @param inPos
+     *            Position to start reading data from.
+     * @param inAvail
+     *            Amount of bytes available from input for encoding.
+     */
+    void encode(byte[] in, int inPos, int inAvail) {
+        if (eof) {
+            return;
         }
+        // inAvail < 0 is how we're informed of EOF in the underlying data we're
+        // encoding.
+        if (inAvail < 0) {
+            eof = true;
+            if (buffer == null || buffer.length - pos < encodeSize) {
+                resizeBuffer();
+            }
+            switch (modulus) {
+                case 1 :
+                    buffer[pos++] = encodeTable[(x >> 2) & MASK_6BITS];
+                    buffer[pos++] = encodeTable[(x << 4) & MASK_6BITS];
+                    // URL-SAFE skips the padding to further reduce size.
+                    if (encodeTable == STANDARD_ENCODE_TABLE) {
+                        buffer[pos++] = PAD;
+                        buffer[pos++] = PAD;
+                    }
+                    break;
+
+                case 2 :
+                    buffer[pos++] = encodeTable[(x >> 10) & MASK_6BITS];
+                    buffer[pos++] = encodeTable[(x >> 4) & MASK_6BITS];
+                    buffer[pos++] = encodeTable[(x << 2) & MASK_6BITS];
+                    // URL-SAFE skips the padding to further reduce size.
+                    if (encodeTable == STANDARD_ENCODE_TABLE) {
+                        buffer[pos++] = PAD;
+                    }
+                    break;
+            }
+            if (lineLength > 0 && pos > 0) {
+                System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
+                pos += lineSeparator.length;
+            }
+        } else {
+            for (int i = 0; i < inAvail; i++) {
+                if (buffer == null || buffer.length - pos < encodeSize) {
+                    resizeBuffer();
+                }
+                modulus = (++modulus) % 3;
+                int b = in[inPos++];
+                if (b < 0) {
+                    b += 256;
+                }
+                x = (x << 8) + b;
+                if (0 == modulus) {
+                    buffer[pos++] = encodeTable[(x >> 18) & MASK_6BITS];
+                    buffer[pos++] = encodeTable[(x >> 12) & MASK_6BITS];
+                    buffer[pos++] = encodeTable[(x >> 6) & MASK_6BITS];
+                    buffer[pos++] = encodeTable[x & MASK_6BITS];
+                    currentLinePos += 4;
+                    if (lineLength > 0 && lineLength <= currentLinePos) {
+                        System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
+                        pos += lineSeparator.length;
+                        currentLinePos = 0;
+                    }
+                }
+            }
+        }
+    }
 
-        for (int i = 52, j = 0; i <= 61; i++, j++) {
-            lookUpBase64Alphabet[i] = (byte) ('0' + j);
+    /**
+     * <p>
+     * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
+     * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
+     * call is not necessary when decoding, but it doesn't hurt, either.
+     * </p>
+     * <p>
+     * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are
+     * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in,
+     * garbage-out philosophy: it will not check the provided data for validity.
+     * </p>
+     * <p>
+     * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
+     * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+     * </p>
+     *
+     * @param in
+     *            byte[] array of ascii data to base64 decode.
+     * @param inPos
+     *            Position to start reading data from.
+     * @param inAvail
+     *            Amount of bytes available from input for encoding.
+     */
+    void decode(byte[] in, int inPos, int inAvail) {
+        if (eof) {
+            return;
+        }
+        if (inAvail < 0) {
+            eof = true;
+        }
+        for (int i = 0; i < inAvail; i++) {
+            if (buffer == null || buffer.length - pos < decodeSize) {
+                resizeBuffer();
+            }
+            byte b = in[inPos++];
+            if (b == PAD) {
+                // We're done.
+                eof = true;
+                break;
+            } else {
+                if (b >= 0 && b < DECODE_TABLE.length) {
+                    int result = DECODE_TABLE[b];
+                    if (result >= 0) {
+                        modulus = (++modulus) % 4;
+                        x = (x << 6) + result;
+                        if (modulus == 0) {
+                            buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
+                            buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS);
+                            buffer[pos++] = (byte) (x & MASK_8BITS);
+                        }
+                    }
+                }
+            }
         }
 
-        lookUpBase64Alphabet[62] = (byte) '+';
-        lookUpBase64Alphabet[63] = (byte) '/';
+        // Two forms of EOF as far as base64 decoder is concerned: actual
+        // EOF (-1) and first time '=' character is encountered in stream.
+        // This approach makes the '=' padding characters completely optional.
+        if (eof && modulus != 0) {
+            x = x << 6;
+            switch (modulus) {
+                case 2 :
+                    x = x << 6;
+                    buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
+                    break;
+                case 3 :
+                    buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS);
+                    buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS);
+                    break;
+            }
+        }
     }
 
     /**
-     * Returns whether or not the <code>octect</code> is in the base 64 alphabet.
+     * Returns whether or not the <code>octet</code> is in the base 64 alphabet.
      *
-     * @param b The value to test
+     * @param octet
+     *            The value to test
      * @return <code>true</code> if the value is defined in the the base 64 alphabet, <code>false</code> otherwise.
+     * @since 1.4
      */
-    public static boolean isBase64(byte b) {
-        return (b == PAD) || (b >= 0 && base64Alphabet[b] >= 0);
+    public static boolean isBase64(byte octet) {
+        return octet == PAD || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1);
     }
 
     /**
-     * Tests a given byte array to see if it contains
-     * only valid characters within the Base64 alphabet.
+     * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
+     * method treats whitespace as valid.
      *
-     * @param arrayOctect byte array to test
-     * @return <code>true</code> if all bytes are valid characters in the Base64
-     *         alphabet or if the byte array is empty; false, otherwise
+     * @param arrayOctet
+     *            byte array to test
+     * @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
+     *         false, otherwise
      */
-    public static boolean isArrayByteBase64(byte[] arrayOctect) {
-
-        arrayOctect = discardWhitespace(arrayOctect);
-
-        int length = arrayOctect.length;
-        if (length == 0) {
-            // shouldn't a 0 length array be valid base64 data?
-            // return false;
-            return true;
-        }
-        for (int i = 0; i < length; i++) {
-            if (!isBase64(arrayOctect[i])) {
+    public static boolean isArrayByteBase64(byte[] arrayOctet) {
+        for (int i = 0; i < arrayOctet.length; i++) {
+            if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) {
                 return false;
             }
         }
@@ -184,337 +613,286 @@ public class Base64 {
     }
 
     /**
-     * Encodes binary data using the base64 algorithm but
-     * does not chunk the output.
+     * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet.
+     *
+     * @param arrayOctet
+     *            byte array to test
+     * @return <code>true</code> if any byte is a valid character in the Base64 alphabet; false herwise
+     */
+    private static boolean containsBase64Byte(byte[] arrayOctet) {
+        for (int i = 0; i < arrayOctet.length; i++) {
+            if (isBase64(arrayOctet[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm but does not chunk the output.
      *
-     * @param binaryData binary data to encode
-     * @return Base64 characters
+     * @param binaryData
+     *            binary data to encode
+     * @return byte[] containing Base64 characters in their UTF-8 representation.
      */
     public static byte[] encodeBase64(byte[] binaryData) {
         return encodeBase64(binaryData, false);
     }
 
     /**
-     * Encodes binary data using the base64 algorithm and chunks
-     * the encoded output into 76 character blocks
+     * Encodes binary data using the base64 algorithm into 76 character blocks separated by CRLF.
      *
-     * @param binaryData binary data to encode
+     * @param binaryData
+     *            binary data to encode
+     * @return String containing Base64 characters.
+     * @since 1.4
+     */
+    public static String encodeBase64String(byte[] binaryData) {
+        return UTF8.toString(encodeBase64(binaryData, true));
+    }
+
+    /**
+     * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
+     * url-safe variation emits - and _ instead of + and / characters.
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return byte[] containing Base64 characters in their UTF-8 representation.
+     * @since 1.4
+     */
+    public static byte[] encodeBase64URLSafe(byte[] binaryData) {
+        return encodeBase64(binaryData, false, true);
+    }
+
+    /**
+     * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
+     * url-safe variation emits - and _ instead of + and / characters.
+     *
+     * @param binaryData
+     *            binary data to encode
+     * @return String containing Base64 characters
+     * @since 1.4
+     */
+    public static String encodeBase64URLSafeString(byte[] binaryData) {
+        return UTF8.toString(encodeBase64(binaryData, false, true));
+    }
+
+    /**
+     * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks
+     *
+     * @param binaryData
+     *            binary data to encode
      * @return Base64 characters chunked in 76 character blocks
      */
     public static byte[] encodeBase64Chunked(byte[] binaryData) {
         return encodeBase64(binaryData, true);
     }
 
-
     /**
-     * Decodes an Object using the base64 algorithm.  This method
-     * is provided in order to satisfy the requirements of the
-     * Decoder interface, and will throw a DecoderException if the
-     * supplied object is not of type byte[].
+     * Decodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the
+     * Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String.
      *
-     * @param pObject Object to decode
-     * @return An object (of type byte[]) containing the
-     *         binary data which corresponds to the byte[] supplied.
-     * @throws IllegalArgumentException if the parameter supplied is not
-     *                                  of type byte[]
+     * @param pObject
+     *            Object to decode
+     * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String supplied.
      */
-    public Object decode(Object pObject) throws IllegalArgumentException {
-        if (!(pObject instanceof byte[])) {
-            throw new IllegalArgumentException("Parameter supplied to Base64 decode is not a byte[]");
+    public Object decode(Object pObject) {
+        if (pObject instanceof byte[]) {
+            return decode((byte[]) pObject);
+        } else if (pObject instanceof String) {
+            return decode((String) pObject);
+        } else {
+            throw new IllegalArgumentException("Parameter supplied to Base64 decode is not a byte[] or a String");
         }
-        return decode((byte[]) pObject);
     }
 
     /**
-     * Decodes a byte[] containing containing
-     * characters in the Base64 alphabet.
+     * Decodes a String containing containing characters in the Base64 alphabet.
      *
-     * @param pArray A byte array containing Base64 character data
+     * @param pArray
+     *            A String containing Base64 character data
+     * @return a byte array containing binary data
+     * @since 1.4
+     */
+    public byte[] decode(String pArray) {
+        return decode(UTF8.toBytes(pArray));
+    }
+
+    /**
+     * Decodes a byte[] containing containing characters in the Base64 alphabet.
+     *
+     * @param pArray
+     *            A byte array containing Base64 character data
      * @return a byte array containing binary data
      */
     public byte[] decode(byte[] pArray) {
-        return decodeBase64(pArray);
+        reset();
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
+        long len = (pArray.length * 3) / 4;
+        byte[] buf = new byte[(int) len];
+        setInitialBuffer(buf, 0, buf.length);
+        decode(pArray, 0, pArray.length);
+        decode(pArray, 0, -1); // Notify decoder of EOF.
+
+        // Would be nice to just return buf (like we sometimes do in the encode
+        // logic), but we have no idea what the line-length was (could even be
+        // variable).  So we cannot determine ahead of time exactly how big an
+        // array is necessary.  Hence the need to construct a 2nd byte array to
+        // hold the final result:
+
+        byte[] result = new byte[pos];
+        readResults(result, 0, result.length);
+        return result;
     }
 
     /**
-     * Encodes binary data using the base64 algorithm, optionally
-     * chunking the output into 76 character blocks.
+     * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
      *
-     * @param binaryData Array containing binary data to encode.
-     * @param isChunked  if <code>true</code> this encoder will chunk
-     *                   the base64 output into 76 character blocks
+     * @param binaryData
+     *            Array containing binary data to encode.
+     * @param isChunked
+     *            if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
      * @return Base64-encoded data.
+     * @throws IllegalArgumentException
+     *             Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
      */
     public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
-        int lengthDataBits = binaryData.length * EIGHTBIT;
-        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
-        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
-        byte encodedData[];
-        int encodedDataLength;
-        int nbrChunks = 0;
-
-        if (fewerThan24bits != 0) {
-            //data not divisible by 24 bit
-            encodedDataLength = (numberTriplets + 1) * 4;
-        } else {
-            // 16 or 8 bit
-            encodedDataLength = numberTriplets * 4;
-        }
-
-        // If the output is to be "chunked" into 76 character sections,
-        // for compliance with RFC 2045 MIME, then it is important to
-        // allow for extra length to account for the separator(s)
-        if (isChunked) {
+        return encodeBase64(binaryData, isChunked, false);
+    }
 
-            nbrChunks =
-                (CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE));
-            encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
-        }
+    /**
+     * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
+     *
+     * @param binaryData
+     *            Array containing binary data to encode.
+     * @param isChunked
+     *            if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
+     * @param urlSafe
+     *            if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters.
+     * @return Base64-encoded data.
+     * @throws IllegalArgumentException
+     *             Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
+     * @since 1.4
+     */
+    public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe) {
+        return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE);
+    }
 
-        encodedData = new byte[encodedDataLength];
-
-        byte k, l, b1, b2, b3;
-        int dataIndex;
-        int i;
-        int encodedIndex = 0;
-        int nextSeparatorIndex = CHUNK_SIZE;
-        int chunksSoFar = 0;
-
-        //log.debug("number of triplets = " + numberTriplets);
-        for (i = 0; i < numberTriplets; i++) {
-            dataIndex = i * 3;
-            b1 = binaryData[dataIndex];
-            b2 = binaryData[dataIndex + 1];
-            b3 = binaryData[dataIndex + 2];
-
-            //log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3);
-
-            l = (byte) (b2 & 0x0f);
-            k = (byte) (b1 & 0x03);
-
-            byte val1 =
-                ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
-            byte val2 =
-                ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
-            byte val3 =
-                ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
-
-            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
-            //log.debug( "val2 = " + val2 );
-            //log.debug( "k4   = " + (k<<4) );
-            //log.debug(  "vak  = " + (val2 | (k<<4)) );
-            encodedData[encodedIndex + 1] =
-                lookUpBase64Alphabet[val2 | (k << 4)];
-            encodedData[encodedIndex + 2] =
-                lookUpBase64Alphabet[(l << 2) | val3];
-            encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
-
-            encodedIndex += 4;
-
-            // If we are chunking, let's put a chunk separator down.
-            if (isChunked) {
-                // this assumes that CHUNK_SIZE % 4 == 0
-                if (encodedIndex == nextSeparatorIndex) {
-                    System.arraycopy(CHUNK_SEPARATOR,
-                        0,
-                        encodedData,
-                        encodedIndex,
-                        CHUNK_SEPARATOR.length);
-                    chunksSoFar++;
-                    nextSeparatorIndex =
-                        (CHUNK_SIZE * (chunksSoFar + 1)) +
-                        (chunksSoFar * CHUNK_SEPARATOR.length);
-                    encodedIndex += CHUNK_SEPARATOR.length;
-                }
-            }
+    /**
+     * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
+     *
+     * @param binaryData
+     *            Array containing binary data to encode.
+     * @param isChunked
+     *            if <code>true</code> this encoder will chunk the base64 output into 76 character blocks
+     * @param urlSafe
+     *            if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters.
+     * @param maxResultSize
+     *            The maximum result size to accept.
+     * @return Base64-encoded data.
+     * @throws IllegalArgumentException
+     *             Thrown when the input array needs an output array bigger than maxResultSize
+     * @since 1.4
+     */
+    public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) {
+        if (binaryData == null || binaryData.length == 0) {
+            return binaryData;
         }
 
-        // form integral number of 6-bit groups
-        dataIndex = i * 3;
-
-        if (fewerThan24bits == EIGHTBIT) {
-            b1 = binaryData[dataIndex];
-            k = (byte) (b1 & 0x03);
-            //log.debug("b1=" + b1);
-            //log.debug("b1<<2 = " + (b1>>2) );
-            byte val1 =
-                ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
-            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
-            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
-            encodedData[encodedIndex + 2] = PAD;
-            encodedData[encodedIndex + 3] = PAD;
-        } else if (fewerThan24bits == SIXTEENBIT) {
-
-            b1 = binaryData[dataIndex];
-            b2 = binaryData[dataIndex + 1];
-            l = (byte) (b2 & 0x0f);
-            k = (byte) (b1 & 0x03);
-
-            byte val1 =
-                ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
-            byte val2 =
-                ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
-
-            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
-            encodedData[encodedIndex + 1] =
-                lookUpBase64Alphabet[val2 | (k << 4)];
-            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
-            encodedData[encodedIndex + 3] = PAD;
+        long len = getEncodeLength(binaryData, CHUNK_SIZE, CHUNK_SEPARATOR);
+        if (len > maxResultSize) {
+            throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
+                len +
+                ") than the specified maxium size of " +
+                maxResultSize);
         }
 
-        if (isChunked) {
-            // we also add a separator to the end of the final chunk.
-            if (chunksSoFar < nbrChunks) {
-                System.arraycopy(CHUNK_SEPARATOR,
-                    0,
-                    encodedData,
-                    encodedDataLength - CHUNK_SEPARATOR.length,
-                    CHUNK_SEPARATOR.length);
-            }
-        }
+        Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe);
+        return b64.encode(binaryData);
+    }
 
-        return encodedData;
+    /**
+     * Decodes a Base64 String into octets
+     *
+     * @param base64String
+     *            String containing Base64 data
+     * @return Array containing decoded data.
+     * @since 1.4
+     */
+    public static byte[] decodeBase64(String base64String) {
+        return new Base64().decode(base64String);
     }
 
     /**
-     * Decodes Base64 data into octects
+     * Decodes Base64 data into octets
      *
-     * @param base64Data Byte array containing Base64 data
+     * @param base64Data
+     *            Byte array containing Base64 data
      * @return Array containing decoded data.
      */
     public static byte[] decodeBase64(byte[] base64Data) {
-        // RFC 2045 requires that we discard ALL non-Base64 characters
-        base64Data = discardNonBase64(base64Data);
-
-        // handle the edge case, so we don't have to worry about it later
-        if (base64Data.length == 0) {
-            return new byte[0];
-        }
-
-        int numberQuadruple = base64Data.length / FOURBYTE;
-        byte decodedData[];
-        byte b1, b2, b3, b4, marker0, marker1;
-
-        // Throw away anything not in base64Data
-        int dataIndex;
-        int encodedIndex = 0;
-        {
-            // this sizes the output array properly - rlw
-            int lastData = base64Data.length;
-            // ignore the '=' padding
-            while (base64Data[lastData - 1] == PAD) {
-                if (--lastData == 0) {
-                    return new byte[0];
-                }
-            }
-            decodedData = new byte[lastData - numberQuadruple];
-        }
-
-        for (int i = 0; i < numberQuadruple; i++) {
-            dataIndex = i * 4;
-            marker0 = base64Data[dataIndex + 2];
-            marker1 = base64Data[dataIndex + 3];
-
-            b1 = base64Alphabet[base64Data[dataIndex]];
-            b2 = base64Alphabet[base64Data[dataIndex + 1]];
-
-            if (marker0 != PAD && marker1 != PAD) {
-                //No PAD e.g 3cQl
-                b3 = base64Alphabet[marker0];
-                b4 = base64Alphabet[marker1];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-                decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
-            } else if (marker0 == PAD) {
-                //Two PAD e.g. 3c[Pad][Pad]
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-            } else // if ( marker1 == PAD ) (always true at this point)
-            {
-                //One PAD e.g. 3cQ[Pad]
-                b3 = base64Alphabet[marker0];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-            }
-            encodedIndex += 3;
-        }
-        return decodedData;
+        return new Base64().decode(base64Data);
     }
 
     /**
      * Discards any whitespace from a base-64 encoded block.
      *
-     * @param data The base-64 encoded data to discard the whitespace
-     *             from.
+     * @param data
+     *            The base-64 encoded data to discard the whitespace from.
      * @return The data, less whitespace (see RFC 2045).
+     * @deprecated This method is no longer needed
      */
     static byte[] discardWhitespace(byte[] data) {
         byte groomedData[] = new byte[data.length];
         int bytesCopied = 0;
-
         for (int i = 0; i < data.length; i++) {
             switch (data[i]) {
-                case (byte) ' ':
-                case (byte) '\n':
-                case (byte) '\r':
-                case (byte) '\t':
+                case ' ' :
+                case '\n' :
+                case '\r' :
+                case '\t' :
                     break;
-                default:
+                default :
                     groomedData[bytesCopied++] = data[i];
             }
         }
-
         byte packedData[] = new byte[bytesCopied];
-
         System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
         return packedData;
     }
 
     /**
-     * Discards any characters outside of the base64 alphabet, per
-     * the requirements on page 25 of RFC 2045 - "Any characters
-     * outside of the base64 alphabet are to be ignored in base64
-     * encoded data."
+     * Checks if a byte value is whitespace or not.
      *
-     * @param data The base-64 encoded data to groom
-     * @return The data, less non-base64 characters (see RFC 2045).
+     * @param byteToCheck
+     *            the byte to check
+     * @return true if byte is whitespace, false otherwise
      */
-    static byte[] discardNonBase64(byte[] data) {
-        byte groomedData[] = new byte[data.length];
-        int bytesCopied = 0;
-
-        for (int i = 0; i < data.length; i++) {
-            if (isBase64(data[i])) {
-                groomedData[bytesCopied++] = data[i];
-            }
+    private static boolean isWhiteSpace(byte byteToCheck) {
+        switch (byteToCheck) {
+            case ' ' :
+            case '\n' :
+            case '\r' :
+            case '\t' :
+                return true;
+            default :
+                return false;
         }
-
-        byte packedData[] = new byte[bytesCopied];
-
-        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
-        return packedData;
     }
 
     // Implementation of the Encoder Interface
 
     /**
-     * Encodes an Object using the base64 algorithm.  This method
-     * is provided in order to satisfy the requirements of the
-     * Encoder interface, and will throw an EncoderException if the
-     * supplied object is not of type byte[].
+     * Encodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the
+     * Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[].
      *
-     * @param pObject Object to encode
-     * @return An object (of type byte[]) containing the
-     *         base64 encoded data which corresponds to the byte[] supplied.
-     * @throws IllegalArgumentException if the parameter supplied is not
-     *                                  of type byte[]
+     * @param pObject
+     *            Object to encode
+     * @return An object (of type byte[]) containing the base64 encoded data which corresponds to the byte[] supplied.
      */
-    public Object encode(Object pObject) throws IllegalArgumentException {
+    public Object encode(Object pObject) {
         if (!(pObject instanceof byte[])) {
             throw new IllegalArgumentException("Parameter supplied to Base64 encode is not a byte[]");
         }
@@ -522,14 +900,149 @@ public class Base64 {
     }
 
     /**
-     * Encodes a byte[] containing binary data, into a byte[] containing
-     * characters in the Base64 alphabet.
+     * Encodes a byte[] containing binary data, into a String containing characters in the Base64 alphabet.
+     *
+     * @param pArray
+     *            a byte array containing binary data
+     * @return A String containing only Base64 character data
+     * @since 1.4
+     */
+    public String encodeToString(byte[] pArray) {
+        return UTF8.toString(encode(pArray));
+    }
+
+    /**
+     * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet.
      *
-     * @param pArray a byte array containing binary data
+     * @param pArray
+     *            a byte array containing binary data
      * @return A byte array containing only Base64 character data
      */
     public byte[] encode(byte[] pArray) {
-        return encodeBase64(pArray, false);
+        reset();
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
+        long len = getEncodeLength(pArray, lineLength, lineSeparator);
+        byte[] buf = new byte[(int) len];
+        setInitialBuffer(buf, 0, buf.length);
+        encode(pArray, 0, pArray.length);
+        encode(pArray, 0, -1); // Notify encoder of EOF.
+        // Encoder might have resized, even though it was unnecessary.
+        if (buffer != buf) {
+            readResults(buf, 0, buf.length);
+        }
+        // In URL-SAFE mode we skip the padding characters, so sometimes our
+        // final length is a bit smaller.
+        if (isUrlSafe() && pos < buf.length) {
+            byte[] smallerBuf = new byte[pos];
+            System.arraycopy(buf, 0, smallerBuf, 0, pos);
+            buf = smallerBuf;
+        }
+        return buf;
+    }
+
+    /**
+     * Pre-calculates the amount of space needed to base64-encode the supplied array.
+     *
+     * @param pArray byte[] array which will later be encoded
+     * @param chunkSize line-length of the output (<= 0 means no chunking) between each
+     *        chunkSeparator (e.g. CRLF).
+     * @param chunkSeparator the sequence of bytes used to separate chunks of output (e.g. CRLF).
+     *
+     * @return amount of space needed to encoded the supplied array.  Returns
+     *         a long since a max-len array will require Integer.MAX_VALUE + 33%.
+     */
+    private static long getEncodeLength(byte[] pArray, int chunkSize, byte[] chunkSeparator) {
+        // base64 always encodes to multiples of 4.
+        chunkSize = (chunkSize / 4) * 4;
+
+        long len = (pArray.length * 4) / 3;
+        long mod = len % 4;
+        if (mod != 0) {
+            len += 4 - mod;
+        }
+        if (chunkSize > 0) {
+            boolean lenChunksPerfectly = len % chunkSize == 0;
+            len += (len / chunkSize) * chunkSeparator.length;
+            if (!lenChunksPerfectly) {
+                len += chunkSeparator.length;
+            }
+        }
+        return len;
+    }
+
+    // Implementation of integer encoding used for crypto
+    /**
+     * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature
+     *
+     * @param pArray
+     *            a byte array containing base64 character data
+     * @return A BigInteger
+     * @since 1.4
+     */
+    public static BigInteger decodeInteger(byte[] pArray) {
+        return new BigInteger(1, decodeBase64(pArray));
+    }
+
+    /**
+     * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature
+     *
+     * @param bigInt
+     *            a BigInteger
+     * @return A byte array containing base64 character data
+     * @throws NullPointerException
+     *             if null is passed in
+     * @since 1.4
+     */
+    public static byte[] encodeInteger(BigInteger bigInt) {
+        if (bigInt == null) {
+            throw new NullPointerException("encodeInteger called with null parameter");
+        }
+        return encodeBase64(toIntegerBytes(bigInt), false);
+    }
+
+    /**
+     * Returns a byte-array representation of a <code>BigInteger</code> without sign bit.
+     *
+     * @param bigInt
+     *            <code>BigInteger</code> to be converted
+     * @return a byte array representation of the BigInteger parameter
+     */
+    static byte[] toIntegerBytes(BigInteger bigInt) {
+        int bitlen = bigInt.bitLength();
+        // round bitlen
+        bitlen = ((bitlen + 7) >> 3) << 3;
+        byte[] bigBytes = bigInt.toByteArray();
+
+        if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) {
+            return bigBytes;
+        }
+        // set up params for copying everything but sign bit
+        int startSrc = 0;
+        int len = bigBytes.length;
+
+        // if bigInt is exactly byte-aligned, just skip signbit in copy
+        if ((bigInt.bitLength() % 8) == 0) {
+            startSrc = 1;
+            len--;
+        }
+        int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec
+        byte[] resizedBytes = new byte[bitlen / 8];
+        System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len);
+        return resizedBytes;
+    }
+
+    /**
+     * Resets this Base64 object to its initial newly constructed state.
+     */
+    private void reset() {
+        buffer = null;
+        pos = 0;
+        readPos = 0;
+        currentLinePos = 0;
+        modulus = 0;
+        eof = false;
     }
 
 }
diff --git a/src/java/org/apache/commons/ssl/Base64InputStream.java b/src/java/org/apache/commons/ssl/Base64InputStream.java
index ef55f64..8b90575 100644
--- a/src/java/org/apache/commons/ssl/Base64InputStream.java
+++ b/src/java/org/apache/commons/ssl/Base64InputStream.java
@@ -1,32 +1,18 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Base64InputStream.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
  *
- * ====================================================================
- * 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/>.
+ *      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.
  */
 
 package org.apache.commons.ssl;
@@ -36,85 +22,153 @@ 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 at cucbc.com">juliusdavies at cucbc.com</a>
- * @since 22-Feb-2007
+ * Provides Base64 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength
+ * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate
+ * constructor.
+ * <p>
+ * The default behaviour of the Base64InputStream is to DECODE, whereas the default behaviour of the Base64OutputStream
+ * is to ENCODE, but this behaviour can be overridden by using a different constructor.
+ * </p>
+ * <p>
+ * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
+ * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
+ * </p>
+ * <p>
+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
+ * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
+ * </p>
+ *
+ * @author Apache Software Foundation
+ * @version $Id: Base64InputStream.java 155 2009-09-17 21:00:58Z julius $
+ * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
+ * @since 1.4
  */
 public class Base64InputStream extends FilterInputStream {
-    private final static byte[] LINE_ENDING =
-        System.getProperty("line.separator").getBytes();
 
-    final boolean decodeMode;
+    private final boolean doEncode;
+
+    private final Base64 base64;
 
-    byte[] currentLine = null;
-    int pos = 0;
+    private final byte[] singleByte = new byte[1];
 
-    public Base64InputStream(InputStream base64, boolean decodeMode) {
-        super(base64);
-        this.decodeMode = decodeMode;
+    /**
+     * Creates a Base64InputStream such that all data read is Base64-decoded from the original provided InputStream.
+     *
+     * @param in
+     *            InputStream to wrap.
+     */
+    public Base64InputStream(InputStream in) {
+        this(in, false);
     }
 
+    /**
+     * Creates a Base64InputStream such that all data read is either Base64-encoded or Base64-decoded from the original
+     * provided InputStream.
+     *
+     * @param in
+     *            InputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data read from us, false if we should decode.
+     */
+    public Base64InputStream(InputStream in, boolean doEncode) {
+        super(in);
+        this.doEncode = doEncode;
+        this.base64 = new Base64();
+    }
+
+    /**
+     * Creates a Base64InputStream such that all data read is either Base64-encoded or Base64-decoded from the original
+     * provided InputStream.
+     *
+     * @param in
+     *            InputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data read from us, false if we should decode.
+     * @param lineLength
+     *            If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to
+     *            nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is
+     *            false, lineLength is ignored.
+     * @param lineSeparator
+     *            If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n).
+     *            If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored.
+     */
+    public Base64InputStream(InputStream in, boolean doEncode, int lineLength, byte[] lineSeparator) {
+        super(in);
+        this.doEncode = doEncode;
+        this.base64 = new Base64(lineLength, lineSeparator);
+    }
+
+    /**
+     * Reads one <code>byte</code> from this input stream.
+     *
+     * @return the byte as an integer in the range 0 to 255. Returns -1 if EOF has been reached.
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
     public int read() throws IOException {
-        getLine();
-        if (currentLine == null) {
-            return -1;
-        } else {
-            byte b = currentLine[pos++];
-            if (pos >= currentLine.length) {
-                currentLine = null;
-            }
-            return b;
+        int r = read(singleByte, 0, 1);
+        while (r == 0) {
+            r = read(singleByte, 0, 1);
         }
+        if (r > 0) {
+            return singleByte[0] < 0 ? 256 + singleByte[0] : singleByte[0];
+        }
+        return -1;
     }
 
-    public int read(byte b[], int off, int len) throws IOException {
+    /**
+     * Attempts to read <code>len</code> bytes into the specified <code>b</code> array starting at <code>offset</code>
+     * from this InputStream.
+     *
+     * @param b
+     *            destination byte array
+     * @param offset
+     *            where to start writing the bytes
+     * @param len
+     *            maximum number of bytes to read
+     *
+     * @return number of bytes read
+     * @throws IOException
+     *             if an I/O error occurs.
+     * @throws NullPointerException
+     *             if the byte array parameter is null
+     * @throws IndexOutOfBoundsException
+     *             if offset, len or buffer size are invalid
+     */
+    public int read(byte b[], int offset, int len) throws IOException {
         if (b == null) {
             throw new NullPointerException();
-        } else if ((off < 0) || (off > b.length) || (len < 0) ||
-                   ((off + len) > b.length) || ((off + len) < 0)) {
+        } else if (offset < 0 || len < 0) {
+            throw new IndexOutOfBoundsException();
+        } else if (offset > b.length || offset + len > b.length) {
             throw new IndexOutOfBoundsException();
         } else if (len == 0) {
             return 0;
-        }
-
-        getLine();
-        if (currentLine == null) {
-            return -1;
-        }
-        int size = Math.min(currentLine.length - pos, len);
-        System.arraycopy(currentLine, pos, b, off, size);
-        if (size >= currentLine.length - pos) {
-            currentLine = null;
         } else {
-            pos += size;
-        }
-        return size;
-    }
-
-    private void getLine() throws IOException {
-        if (currentLine == null) {
-            if (decodeMode) {
-                String line = Util.readLine(in);
-                if (line != null) {
-                    byte[] b = line.getBytes();
-                    currentLine = Base64.decodeBase64(b);
-                    pos = 0;
+            if (!base64.hasData()) {
+                byte[] buf = new byte[doEncode ? 4096 : 8192];
+                int c = in.read(buf);
+                // A little optimization to avoid System.arraycopy()
+                // when possible.
+                if (c > 0 && b.length == len) {
+                    base64.setInitialBuffer(b, offset, len);
                 }
-            } else {
-                // It will expand to 64 bytes (16 * 4) after base64 encoding!
-                byte[] b = Util.streamToBytes(in, 16 * 3);
-                if (b.length > 0) {
-                    b = Base64.encodeBase64(b);
-
-                    int lfLen = LINE_ENDING.length;
-                    currentLine = new byte[b.length + lfLen];
-                    System.arraycopy(b, 0, currentLine, 0, b.length);
-                    System.arraycopy(LINE_ENDING, 0, currentLine, b.length, lfLen);
+                if (doEncode) {
+                    base64.encode(buf, 0, c);
+                } else {
+                    base64.decode(buf, 0, c);
                 }
             }
+            return base64.readResults(b, offset, len);
         }
     }
 
-
+    /**
+     * {@inheritDoc}
+     *
+     * @return false
+     */
+    public boolean markSupported() {
+        return false; // not an easy job to support marks
+    }
 }
diff --git a/src/java/org/apache/commons/ssl/Base64OutputStream.java b/src/java/org/apache/commons/ssl/Base64OutputStream.java
new file mode 100644
index 0000000..78f422c
--- /dev/null
+++ b/src/java/org/apache/commons/ssl/Base64OutputStream.java
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.ssl;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Provides Base64 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength
+ * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate
+ * constructor.
+ * <p>
+ * The default behaviour of the Base64OutputStream is to ENCODE, whereas the default behaviour of the Base64InputStream
+ * is to DECODE. But this behaviour can be overridden by using a different constructor.
+ * </p>
+ * <p>
+ * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
+ * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
+ * </p>
+ * <p>
+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
+ * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
+ * </p>
+ *
+ * @author Apache Software Foundation
+ * @version $Id$
+ * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
+ * @since 1.4
+ */
+public class Base64OutputStream extends FilterOutputStream {
+    private final boolean doEncode;
+
+    private final Base64 base64;
+
+    private final byte[] singleByte = new byte[1];
+
+    /**
+     * Creates a Base64OutputStream such that all data written is Base64-encoded to the original provided OutputStream.
+     *
+     * @param out
+     *            OutputStream to wrap.
+     */
+    public Base64OutputStream(OutputStream out) {
+        this(out, true);
+    }
+
+    /**
+     * Creates a Base64OutputStream such that all data written is either Base64-encoded or Base64-decoded to the
+     * original provided OutputStream.
+     *
+     * @param out
+     *            OutputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data written to us, false if we should decode.
+     */
+    public Base64OutputStream(OutputStream out, boolean doEncode) {
+        super(out);
+        this.doEncode = doEncode;
+        this.base64 = new Base64();
+    }
+
+    /**
+     * Creates a Base64OutputStream such that all data written is either Base64-encoded or Base64-decoded to the
+     * original provided OutputStream.
+     *
+     * @param out
+     *            OutputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data written to us, false if we should decode.
+     * @param lineLength
+     *            If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to
+     *            nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is
+     *            false, lineLength is ignored.
+     * @param lineSeparator
+     *            If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n).
+     *            If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored.
+     */
+    public Base64OutputStream(OutputStream out, boolean doEncode, int lineLength, byte[] lineSeparator) {
+        super(out);
+        this.doEncode = doEncode;
+        this.base64 = new Base64(lineLength, lineSeparator);
+    }
+
+    /**
+     * Writes the specified <code>byte</code> to this output stream.
+     *
+     * @param i
+     *            source byte
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public void write(int i) throws IOException {
+        singleByte[0] = (byte) i;
+        write(singleByte, 0, 1);
+    }
+
+    /**
+     * Writes <code>len</code> bytes from the specified <code>b</code> array starting at <code>offset</code> to this
+     * output stream.
+     *
+     * @param b
+     *            source byte array
+     * @param offset
+     *            where to start reading the bytes
+     * @param len
+     *            maximum number of bytes to write
+     *
+     * @throws IOException
+     *             if an I/O error occurs.
+     * @throws NullPointerException
+     *             if the byte array parameter is null
+     * @throws IndexOutOfBoundsException
+     *             if offset, len or buffer size are invalid
+     */
+    public void write(byte b[], int offset, int len) throws IOException {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if (offset < 0 || len < 0) {
+            throw new IndexOutOfBoundsException();
+        } else if (offset > b.length || offset + len > b.length) {
+            throw new IndexOutOfBoundsException();
+        } else if (len > 0) {
+            if (doEncode) {
+                base64.encode(b, offset, len);
+            } else {
+                base64.decode(b, offset, len);
+            }
+            flush(false);
+        }
+    }
+
+    /**
+     * Flushes this output stream and forces any buffered output bytes to be written out to the stream. If propogate is
+     * true, the wrapped stream will also be flushed.
+     *
+     * @param propogate
+     *            boolean flag to indicate whether the wrapped OutputStream should also be flushed.
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    private void flush(boolean propogate) throws IOException {
+        int avail = base64.avail();
+        if (avail > 0) {
+            byte[] buf = new byte[avail];
+            int c = base64.readResults(buf, 0, avail);
+            if (c > 0) {
+                out.write(buf, 0, c);
+            }
+        }
+        if (propogate) {
+            out.flush();
+        }
+    }
+
+    /**
+     * Flushes this output stream and forces any buffered output bytes to be written out to the stream.
+     *
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public void flush() throws IOException {
+        flush(true);
+    }
+
+    /**
+     * Closes this output stream and releases any system resources associated with the stream.
+     *
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public void close() throws IOException {
+        // Notify encoder of EOF (-1).
+        if (doEncode) {
+            base64.encode(singleByte, 0, -1);
+        } else {
+            base64.decode(singleByte, 0, -1);
+        }
+        flush();
+        out.close();
+    }
+
+}
diff --git a/src/java/org/apache/commons/ssl/CRLSocket.java b/src/java/org/apache/commons/ssl/CRLSocket.java
new file mode 100644
index 0000000..3a81e18
--- /dev/null
+++ b/src/java/org/apache/commons/ssl/CRLSocket.java
@@ -0,0 +1,100 @@
+package org.apache.commons.ssl;
+
+import javax.net.SocketFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.security.GeneralSecurityException;
+
+public class CRLSocket extends SSLClient {
+    private final static CRLSocket secureInstance;
+    private final static CRLSocket plainInstance;    
+
+    static {
+        CRLSocket sf1 = null, sf2 = null;
+        try {
+            sf1 = new CRLSocket();
+            sf2 = new CRLSocket();
+            sf2.setIsSecure(false);
+        }
+        catch (Exception e) {
+            System.out.println("could not create CRLSocket: " + e);
+            e.printStackTrace();
+        }
+        finally {
+            secureInstance = sf1;
+            plainInstance = sf2;            
+        }
+    }
+
+    private CRLSocket() throws GeneralSecurityException, IOException {
+        super();
+
+        // For now we setup the usual trust infrastructure, but consumers
+        // are encouraged to call getInstance().addTrustMaterial() or
+        // getInstance().setTrustMaterial() to customize the trust.
+        if (TrustMaterial.JSSE_CACERTS != null) {
+            setTrustMaterial(TrustMaterial.JSSE_CACERTS);
+        } else {
+            setTrustMaterial(TrustMaterial.CACERTS);
+        }
+        setConnectTimeout(5000);
+        setSoTimeout(5000);
+        setCheckCRL(false);
+    }
+
+    public static SocketFactory getDefault() {
+        return getSecureInstance();
+    }
+
+    public static CRLSocket getSecureInstance() {
+        return secureInstance;
+    }
+
+    public static CRLSocket getPlainInstance() {
+        return plainInstance;
+    }
+
+    public static void main(String[] args) throws Exception {
+        String host = args[0];
+        String port = args[1];
+        String hello
+                = "HEAD / HTTP/1.1\r\n"
+                + "Host:" + host + ":" + port + "\r\n\r\n";
+        byte[] helloBytes = hello.getBytes("UTF-8");
+
+        System.out.println("About to getInstance() ");
+        CRLSocket sf = getPlainInstance();
+        long now = System.currentTimeMillis();
+        System.out.println("About to create socket: [" + host + ":" + port + "]");
+        Socket s = sf.createSocket(host, Integer.parseInt(port));
+        long delay = System.currentTimeMillis() - now;
+        System.out.println("Created socket! took " + delay + "ms ");
+        OutputStream out = s.getOutputStream();
+        out.write(helloBytes);
+        out.flush();
+
+        System.out.println("\n" + new String(helloBytes, "UTF-8"));
+
+        InputStream in = s.getInputStream();
+        int c = in.read();
+        StringBuffer buf = new StringBuffer();
+        System.out.println("Reading: ");
+        System.out.println("================================================================================");
+        while (c >= 0) {
+            byte b = (byte) c;
+            buf.append((char) b);
+            System.out.print((char) b);
+            if (-1 == buf.toString().indexOf("\r\n\r\n")) {
+                c = in.read();
+            } else {
+                break;
+            }
+        }
+        in.close();
+        out.close();
+        s.close();
+    }
+
+}
diff --git a/src/java/org/apache/commons/ssl/CRLUtil.java b/src/java/org/apache/commons/ssl/CRLUtil.java
index 744502d..ccae3fb 100644
--- a/src/java/org/apache/commons/ssl/CRLUtil.java
+++ b/src/java/org/apache/commons/ssl/CRLUtil.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/CRLUtil.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/CRLUtil.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/Certificates.java b/src/java/org/apache/commons/ssl/Certificates.java
index 2c8926f..0ab9263 100644
--- a/src/java/org/apache/commons/ssl/Certificates.java
+++ b/src/java/org/apache/commons/ssl/Certificates.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Certificates.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Certificates.java $
+ * $Revision: 172 $
+ * $Date: 2014-09-06 16:52:31 -0700 (Sat, 06 Sep 2014) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,42 +31,27 @@
 
 package org.apache.commons.ssl;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
+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.CRL;
-import java.security.cert.CRLException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.security.cert.X509Extension;
+import java.security.cert.*;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
+import java.util.*;
+import java.lang.reflect.Method;
 
 /**
  * @author Credit Union Central of British Columbia
@@ -397,13 +382,44 @@ public class Certificates {
             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, new Integer[]{new Integer(5000)});
+                            setReadTimeout.invoke(httpConn, new Integer[]{new Integer(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(url.openStream());
+                    InputStream in = new BufferedInputStream(urlConn.getInputStream());
                     try {
                         Util.pipeStream(in, out);
                     }
@@ -457,48 +473,32 @@ public class Certificates {
     }
 
     public static String[] getCNs(X509Certificate cert) {
-        LinkedList cnList = new LinkedList();
-        /*
-          Sebastian Hauer's original StrictSSLProtocolSocketFactory used
-          getName() and had the following comment:
-
-             Parses a X.500 distinguished name for the value of the
-             "Common Name" field.  This is done a bit sloppy right
-             now and should probably be done a bit more according to
-             <code>RFC 2253</code>.
-
-           I've noticed that toString() seems to do a better job than
-           getName() on these X500Principal objects, so I'm hoping that
-           addresses Sebastian's concern.
-
-           For example, getName() gives me this:
-           1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d
-
-           whereas toString() gives me this:
-           EMAILADDRESS=juliusdavies at cucbc.com
-
-           Looks like toString() even works with non-ascii domain names!
-           I tested it with "&#x82b1;&#x5b50;.co.jp" and it worked fine.
-          */
-        String subjectPrincipal = cert.getSubjectX500Principal().toString();
-        StringTokenizer st = new StringTokenizer(subjectPrincipal, ",");
-        while (st.hasMoreTokens()) {
-            String tok = st.nextToken();
-            int x = tok.indexOf("CN=");
-            if (x >= 0) {
-                cnList.add(tok.substring(x + 3));
+        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) {
         }
-        if (!cnList.isEmpty()) {
-            String[] cns = new String[cnList.size()];
-            cnList.toArray(cns);
-            return cns;
-        } else {
-            return null;
-        }
+        return null;
     }
 
-
     /**
      * Extracts the array of SubjectAlt DNS names from an X509Certificate.
      * Returns null if there aren't any.
@@ -550,7 +550,7 @@ public class Certificates {
      * @param chain X509Certificate[] chain to trim
      * @return Shrunk array with all trailing null entries removed.
      */
-    public static X509Certificate[] trimChain(X509Certificate[] chain) {
+    public static Certificate[] trimChain(Certificate[] chain) {
         for (int i = 0; i < chain.length; i++) {
             if (chain[i] == null) {
                 X509Certificate[] newChain = new X509Certificate[i];
diff --git a/src/java/org/apache/commons/ssl/ComboInputStream.java b/src/java/org/apache/commons/ssl/ComboInputStream.java
index d431009..ad06022 100644
--- a/src/java/org/apache/commons/ssl/ComboInputStream.java
+++ b/src/java/org/apache/commons/ssl/ComboInputStream.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/ComboInputStream.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/ComboInputStream.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/DerivedKey.java b/src/java/org/apache/commons/ssl/DerivedKey.java
index 9e1ed4d..1fd7771 100644
--- a/src/java/org/apache/commons/ssl/DerivedKey.java
+++ b/src/java/org/apache/commons/ssl/DerivedKey.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/DerivedKey.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/DerivedKey.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/HostPort.java b/src/java/org/apache/commons/ssl/HostPort.java
index 1826c0a..c09e1d9 100644
--- a/src/java/org/apache/commons/ssl/HostPort.java
+++ b/src/java/org/apache/commons/ssl/HostPort.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/HostPort.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
@@ -31,6 +31,8 @@
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.IPAddressParser;
+
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
@@ -48,7 +50,7 @@ public class HostPort {
     public HostPort(String host, int port) throws UnknownHostException {
         this.host = host;
         this.port = port;
-        this.addr = InetAddress.getByName(host);
+        this.addr = Util.toInetAddress(host);
     }
 
     public String toString() { return host + ":" + port; }
diff --git a/src/java/org/apache/commons/ssl/HostnameVerifier.java b/src/java/org/apache/commons/ssl/HostnameVerifier.java
index c6f22c2..d7fecfe 100644
--- a/src/java/org/apache/commons/ssl/HostnameVerifier.java
+++ b/src/java/org/apache/commons/ssl/HostnameVerifier.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/HostnameVerifier.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/HostnameVerifier.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/HttpSecureProtocol.java b/src/java/org/apache/commons/ssl/HttpSecureProtocol.java
index 9624865..2b4d808 100644
--- a/src/java/org/apache/commons/ssl/HttpSecureProtocol.java
+++ b/src/java/org/apache/commons/ssl/HttpSecureProtocol.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/HttpSecureProtocol.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
diff --git a/src/java/org/apache/commons/ssl/Java13.java b/src/java/org/apache/commons/ssl/Java13.java
index b8a2721..3ad7e4e 100644
--- a/src/java/org/apache/commons/ssl/Java13.java
+++ b/src/java/org/apache/commons/ssl/Java13.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java13.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
@@ -80,7 +80,7 @@ public final class Java13 extends JavaImpl {
             Class[] sig = {String.class};
             String[] args = {"DES/CBC/PKCS5Padding"};
             Method m = c.getMethod("getInstance", sig);
-            m.invoke(null, args);
+            m.invoke(null, (Object[]) args);
         }
         catch (Exception e) {
             try {
@@ -150,10 +150,6 @@ public final class Java13 extends JavaImpl {
         String alg = KeyManagerFactory.getDefaultAlgorithm();
         KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
         kmf.init(ks, password);
-        // overwrite password
-        for (int i = 0; i < password.length; i++) {
-            password[i] = '*';
-        }
         return kmf;
     }
 
@@ -205,19 +201,36 @@ public final class Java13 extends JavaImpl {
         throws IOException {
         // Connect Timeout ignored for Java 1.3
         SSLSocketFactory sf = ssl.getSSLSocketFactory();
-        SSLSocket s = (SSLSocket) connectSocket(null, sf, remoteHost,
-            remotePort, localHost,
-            localPort, -1);
+        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)
+                                         int timeout, SSL ssl)
         throws IOException {
+
+        remoteHost = ssl.dnsOverride(remoteHost);
+
         // Connect Timeout ignored for Java 1.3
         if (s == null) {
             if (sf == null) {
diff --git a/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java b/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java
index 9222496..afdd790 100644
--- a/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java
+++ b/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Java13KeyManagerWrapper.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java b/src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java
index 0821015..325cc56 100644
--- a/src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java
+++ b/src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java13TrustManagerWrapper.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
@@ -67,7 +67,12 @@ public class Java13TrustManagerWrapper implements X509TrustManager {
     }
 
     public X509Certificate[] getAcceptedIssuers() {
-        return trustManager.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) {
@@ -78,7 +83,6 @@ public class Java13TrustManagerWrapper implements X509TrustManager {
                 return false;
             }
         }
-
         try {
             for (int i = 0; i < chain.length; i++) {
                 X509Certificate c = chain[i];
diff --git a/src/java/org/apache/commons/ssl/Java14.java b/src/java/org/apache/commons/ssl/Java14.java
index d416391..e6a22e2 100644
--- a/src/java/org/apache/commons/ssl/Java14.java
+++ b/src/java/org/apache/commons/ssl/Java14.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java14.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Java14.java $
+ * $Revision: 166 $
+ * $Date: 2014-04-28 11:40:25 -0700 (Mon, 28 Apr 2014) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,6 +31,22 @@
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.IPAddressParser;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 import javax.net.SocketFactory;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
@@ -45,19 +61,6 @@ import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509KeyManager;
 import javax.net.ssl.X509TrustManager;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 
 
 /**
@@ -105,10 +108,6 @@ public final class Java14 extends JavaImpl {
         String alg = KeyManagerFactory.getDefaultAlgorithm();
         KeyManagerFactory kmf = KeyManagerFactory.getInstance(alg);
         kmf.init(ks, password);
-        // overwrite password
-        for (int i = 0; i < password.length; i++) {
-            password[i] = '*';
-        }
         return kmf;
     }
 
@@ -155,15 +154,28 @@ public final class Java14 extends JavaImpl {
         throws IOException {
         SSLSocket s = buildSocket(ssl);
         s = (SSLSocket) connectSocket(s, null, remoteHost, remotePort,
-            localHost, localPort, timeout);
+            localHost, localPort, timeout, ssl);
+        ssl.doPostConnectSocketStuff(s, remoteHost);
+        return s;
+    }
+
+
+    protected final Socket buildPlainSocket(
+            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout
+    ) throws IOException {
+        Socket s = SocketFactory.getDefault().createSocket();
+        ssl.doPreConnectSocketStuff(s);
+        s = connectSocket(
+                s, null, remoteHost, remotePort, localHost, localPort, timeout, ssl
+        );
         ssl.doPostConnectSocketStuff(s, remoteHost);
         return s;
     }
 
     protected final Socket connectSocket(Socket s, SocketFactory sf,
-                                         String remoteHost, int remotePort,
+                                         String host, int remotePort,
                                          InetAddress localHost, int localPort,
-                                         int timeout)
+                                         int timeout, SSL ssl)
         throws IOException {
         if (s == null) {
             if (sf == null) {
@@ -172,6 +184,8 @@ public final class Java14 extends JavaImpl {
                 s = sf.createSocket();
             }
         }
+        host = ssl.dnsOverride(host);
+        InetAddress remoteHost = Util.toInetAddress(host);
         InetSocketAddress dest = new InetSocketAddress(remoteHost, remotePort);
         InetSocketAddress src = new InetSocketAddress(localHost, localPort);
         s.bind(src);
diff --git a/src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java b/src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java
index 2f8f03d..f4a89c9 100644
--- a/src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java
+++ b/src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Java14KeyManagerWrapper.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java b/src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java
index 93f0ac6..06a39c0 100644
--- a/src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java
+++ b/src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Java14TrustManagerWrapper.java $
+ * $Revision: 138 $
+ * $Date: 2008-03-03 23:50:07 -0800 (Mon, 03 Mar 2008) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -80,7 +80,12 @@ public class Java14TrustManagerWrapper implements X509TrustManager {
     }
 
     public X509Certificate[] getAcceptedIssuers() {
-        return trustManager.getAcceptedIssuers();
+        if (trustChain.containsTrustAll()) {
+            // Counter-intuitively, this means we accept all issuers.
+            return new X509Certificate[0];
+        } else {
+            return trustManager.getAcceptedIssuers();
+        }
     }
 
     private void testShouldWeThrow(CertificateException checkException,
diff --git a/src/java/org/apache/commons/ssl/JavaImpl.java b/src/java/org/apache/commons/ssl/JavaImpl.java
index b189fb2..a9c821d 100644
--- a/src/java/org/apache/commons/ssl/JavaImpl.java
+++ b/src/java/org/apache/commons/ssl/JavaImpl.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/JavaImpl.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/JavaImpl.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -113,20 +113,22 @@ public abstract class JavaImpl {
     protected abstract SSLSocketFactory buildSSLSocketFactory(Object ssl);
 
     protected abstract SSLServerSocketFactory buildSSLServerSocketFactory(Object ssl);
-
+    
     protected abstract SSLSocket buildSocket(SSL ssl)
         throws IOException;
 
-    protected abstract SSLSocket buildSocket(SSL ssl, String remoteHost,
-                                             int remotePort,
-                                             InetAddress localHost,
-                                             int localPort, int connectTimeout)
-        throws IOException;
+    protected abstract SSLSocket buildSocket(
+            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int connectTimeout
+    ) throws IOException;
+
+    protected abstract Socket buildPlainSocket(
+            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort, int connectTimeout
+    ) throws IOException;
 
     protected abstract Socket connectSocket(Socket s, SocketFactory sf,
                                             String remoteHost, int remotePort,
                                             InetAddress localHost, int localPort,
-                                            int timeout)
+                                            int timeout, SSL ssl)
         throws IOException;
 
     protected abstract SSLServerSocket buildServerSocket(SSL ssl)
@@ -205,13 +207,22 @@ public abstract class JavaImpl {
             localPort, connectTimeout);
     }
 
+    public static Socket createPlainSocket(
+            SSL ssl, String remoteHost, int remotePort, InetAddress localHost, int localPort,
+            int connectTimeout
+    ) throws IOException {
+        return HANDLER.buildPlainSocket(
+                ssl, remoteHost, remotePort, localHost, localPort, connectTimeout
+        );
+    }    
+
     protected static Socket connect(Socket s, SocketFactory sf,
                                     String remoteHost, int remotePort,
                                     InetAddress localHost, int localPort,
-                                    int timeout)
+                                    int timeout, SSL ssl)
         throws IOException {
         return HANDLER.connectSocket(s, sf, remoteHost, remotePort, localHost,
-            localPort, timeout);
+            localPort, timeout, ssl);
     }
 
     public static SSLServerSocket createServerSocket(SSL ssl)
diff --git a/src/java/org/apache/commons/ssl/KeyMaterial.java b/src/java/org/apache/commons/ssl/KeyMaterial.java
index fcfc9a3..85be255 100644
--- a/src/java/org/apache/commons/ssl/KeyMaterial.java
+++ b/src/java/org/apache/commons/ssl/KeyMaterial.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/KeyMaterial.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/KeyMaterial.java $
+ * $Revision: 138 $
+ * $Date: 2008-03-03 23:50:07 -0800 (Mon, 03 Mar 2008) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -42,7 +42,11 @@ import java.security.KeyStoreException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * @author Credit Union Central of British Columbia
@@ -52,14 +56,19 @@ import java.util.Enumeration;
  */
 public class KeyMaterial extends TrustMaterial {
     private final Object keyManagerFactory;
-    private final String alias;
-    private final X509Certificate[] associatedChain;
+    private final List aliases;
+    private final List associatedChains;
 
     public KeyMaterial(InputStream jks, char[] password)
         throws GeneralSecurityException, IOException {
         this(Util.streamToBytes(jks), password);
     }
 
+    public KeyMaterial(InputStream jks, char[] jksPass, char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(Util.streamToBytes(jks), jksPass, keyPass);
+    }
+
     public KeyMaterial(InputStream jks, InputStream key, char[] password)
         throws GeneralSecurityException, IOException {
         this(jks != null ? Util.streamToBytes(jks) : null,
@@ -67,11 +76,24 @@ public class KeyMaterial extends TrustMaterial {
             password);
     }
 
+    public KeyMaterial(InputStream jks, InputStream key, char[] jksPass,
+                       char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(jks != null ? Util.streamToBytes(jks) : null,
+            key != null ? Util.streamToBytes(key) : null,
+            jksPass, keyPass);
+    }
+
     public KeyMaterial(String pathToJksFile, char[] password)
         throws GeneralSecurityException, IOException {
         this(new File(pathToJksFile), password);
     }
 
+    public KeyMaterial(String pathToJksFile, char[] jksPass, char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(new File(pathToJksFile), jksPass, keyPass);
+    }
+
     public KeyMaterial(String pathToCerts, String pathToKey, char[] password)
         throws GeneralSecurityException, IOException {
         this(pathToCerts != null ? new File(pathToCerts) : null,
@@ -79,11 +101,24 @@ public class KeyMaterial extends TrustMaterial {
             password);
     }
 
+    public KeyMaterial(String pathToCerts, String pathToKey, char[] jksPass,
+                       char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(pathToCerts != null ? new File(pathToCerts) : null,
+            pathToKey != null ? new File(pathToKey) : null,
+            jksPass, keyPass);
+    }
+
     public KeyMaterial(File jksFile, char[] password)
         throws GeneralSecurityException, IOException {
         this(new FileInputStream(jksFile), password);
     }
 
+    public KeyMaterial(File jksFile, char[] jksPass, char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(new FileInputStream(jksFile), jksPass, keyPass);
+    }
+
     public KeyMaterial(File certsFile, File keyFile, char[] password)
         throws GeneralSecurityException, IOException {
         this(certsFile != null ? new FileInputStream(certsFile) : null,
@@ -91,74 +126,109 @@ public class KeyMaterial extends TrustMaterial {
             password);
     }
 
+    public KeyMaterial(File certsFile, File keyFile, char[] jksPass,
+                       char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(certsFile != null ? new FileInputStream(certsFile) : null,
+            keyFile != null ? new FileInputStream(keyFile) : null,
+            jksPass, keyPass);
+    }
 
     public KeyMaterial(URL urlToJKS, char[] password)
         throws GeneralSecurityException, IOException {
         this(urlToJKS.openStream(), password);
     }
 
+    public KeyMaterial(URL urlToJKS, char[] jksPass, char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(urlToJKS.openStream(), jksPass, keyPass);
+    }
+
     public KeyMaterial(URL urlToCerts, URL urlToKey, char[] password)
         throws GeneralSecurityException, IOException {
         this(urlToCerts.openStream(), urlToKey.openStream(), password);
     }
 
+    public KeyMaterial(URL urlToCerts, URL urlToKey, char[] jksPass,
+                       char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(urlToCerts.openStream(), urlToKey.openStream(), jksPass, keyPass);
+    }
+
     public KeyMaterial(byte[] jks, char[] password)
         throws GeneralSecurityException, IOException {
-        this(jks, null, password);
+        this(jks, (byte[]) null, password);
+    }
+
+    public KeyMaterial(byte[] jks, char[] jksPass, char[] keyPass)
+        throws GeneralSecurityException, IOException {
+        this(jks, null, jksPass, keyPass);
     }
 
     public KeyMaterial(byte[] jksOrCerts, byte[] key, char[] password)
         throws GeneralSecurityException, IOException {
+        this(jksOrCerts, key, password, password);
+    }
+
+
+    public KeyMaterial(byte[] jksOrCerts, byte[] key, char[] jksPass,
+                       char[] keyPass)
+        throws GeneralSecurityException, IOException {
         // We're not a simple trust type, so set "simpleTrustType" value to 0.
         // Only TRUST_ALL and TRUST_THIS_JVM are simple trust types.
-        super(KeyStoreBuilder.build(jksOrCerts, key, password), 0);
+        super(KeyStoreBuilder.build(jksOrCerts, key, jksPass, keyPass), 0);
         KeyStore ks = getKeyStore();
         Enumeration en = ks.aliases();
-        String myAlias = null;
-        X509Certificate[] myChain;
+        List myAliases = new LinkedList();
+        List myChains = new LinkedList();
         while (en.hasMoreElements()) {
+            X509Certificate[] c; // chain
             String alias = (String) en.nextElement();
             if (ks.isKeyEntry(alias)) {
-                if (myAlias != null) {
-                    throw new KeyStoreException("commons-ssl KeyMaterial only supports keystores with a single private key.");
+                try {
+                    ks.getKey(alias, keyPass);
+                    // No Exception thrown, so we're good!
+                    myAliases.add(alias);
+                    Certificate[] chain = ks.getCertificateChain(alias);
+                    if (chain != null) {
+                        c = Certificates.x509ifyChain(chain);
+                        // Cleanup chain to remove any spurious entries.
+                        if (c != null) {
+                            X509Certificate l = c[0]; // The leaf node.
+                            c = X509CertificateChainBuilder.buildPath(l, c);
+                        }
+                        myChains.add(c);
+                    } else {
+                        throw new KeyStoreException("Could not find KeyMaterial's associated certificate chain with alis=[" + alias + "]");
+                    }
+
+                } catch (GeneralSecurityException gse) {
+                    // oh well, we can't use that KeyStore alias.
                 }
-                myAlias = alias;
             }
         }
-        if (myAlias != null) {
-            Certificate[] chain = ks.getCertificateChain(myAlias);
-            if (chain != null) {
-                myChain = Certificates.x509ifyChain(chain);
-            } else {
-                // is password wrong?
-                throw new KeyStoreException("Could not find KeyMaterial's associated certificate chain!");
-            }
-        } else {
+        if (myAliases.isEmpty()) {
             throw new KeyStoreException("KeyMaterial provided does not contain any keys!");
         }
-        this.alias = myAlias;
-        // Cleanup chain to remove any spurious entries.
-        if (myChain != null) {
-            myChain = X509CertificateChainBuilder.buildPath(myChain[0], myChain);
-        }
-        this.associatedChain = myChain;
-        this.keyManagerFactory = JavaImpl.newKeyManagerFactory(ks, password);
+        this.aliases = Collections.unmodifiableList(myAliases);
+        this.associatedChains = Collections.unmodifiableList(myChains);
+        this.keyManagerFactory = JavaImpl.newKeyManagerFactory(ks, keyPass);
     }
 
     public Object[] getKeyManagers() {
         return JavaImpl.getKeyManagers(keyManagerFactory);
     }
 
-    public X509Certificate[] getAssociatedCertificateChain() {
-        return associatedChain;
+    public List getAssociatedCertificateChains() {
+        return associatedChains;
     }
 
     public KeyStore getKeyStore() {
         return super.getKeyStore();
     }
 
-    public String getAlias() {
-        return alias;
+    public List getAliases() {
+        return aliases;
     }
 
     public static void main(String[] args) throws Exception {
@@ -167,32 +237,50 @@ public class KeyMaterial extends TrustMaterial {
             System.out.println("Usage2:  java org.apache.commons.ssl.KeyMaterial [password] [private-key] [cert-chain]");
             System.exit(1);
         }
-        char[] password = args[0].toCharArray();
+        char[] jksPass = args[0].toCharArray();
+        char[] keyPass = jksPass;
         String path1 = args[1];
         String path2 = null;
         if (args.length >= 3) {
             path2 = args[2];
         }
+        if (args.length >= 4) {
+            keyPass = args[3].toCharArray();
+        } else if (path2 != null) {
+            File f = new File(path2);
+            if (!f.exists()) {
+                // Hmmm... maybe it's a password.
+                keyPass = path2.toCharArray();
+                path2 = null;
+            }
+        }
 
-        KeyMaterial km = new KeyMaterial(path1, path2, password);
+        KeyMaterial km = new KeyMaterial(path1, path2, jksPass, keyPass);
         System.out.println(km);
     }
 
     public String toString() {
-        X509Certificate[] certs = getAssociatedCertificateChain();
-        StringBuffer buf = new StringBuffer(1024);
-        buf.append("Alias: ");
-        buf.append(alias);
-        buf.append('\n');
-        if (certs != null) {
-            for (int i = 0; i < certs.length; i++) {
-                buf.append(Certificates.toString(certs[i]));
-                try {
-                    buf.append(Certificates.toPEMString(certs[i]));
-                }
-                catch (CertificateEncodingException cee) {
-                    buf.append(cee.toString());
-                    buf.append('\n');
+        List chains = getAssociatedCertificateChains();
+        List aliases = getAliases();
+        Iterator it = chains.iterator();
+        Iterator aliasesIt = aliases.iterator();
+        StringBuffer buf = new StringBuffer(8192);
+        while (it.hasNext()) {
+            X509Certificate[] certs = (X509Certificate[]) it.next();
+            String alias = (String) aliasesIt.next();
+            buf.append("Alias: ");
+            buf.append(alias);
+            buf.append('\n');
+            if (certs != null) {
+                for (int i = 0; i < certs.length; i++) {
+                    buf.append(Certificates.toString(certs[i]));
+                    try {
+                        buf.append(Certificates.toPEMString(certs[i]));
+                    }
+                    catch (CertificateEncodingException cee) {
+                        buf.append(cee.toString());
+                        buf.append('\n');
+                    }
                 }
             }
         }
diff --git a/src/java/org/apache/commons/ssl/KeyStoreBuilder.java b/src/java/org/apache/commons/ssl/KeyStoreBuilder.java
index ab5008b..075f47e 100644
--- a/src/java/org/apache/commons/ssl/KeyStoreBuilder.java
+++ b/src/java/org/apache/commons/ssl/KeyStoreBuilder.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/KeyStoreBuilder.java $
- * $Revision: 129 $
- * $Date: 2007-11-14 19:21:33 -0800 (Wed, 14 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/KeyStoreBuilder.java $
+ * $Revision: 176 $
+ * $Date: 2014-09-07 11:36:28 -0700 (Sun, 07 Sep 2014) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -34,7 +34,6 @@ package org.apache.commons.ssl;
 import org.apache.commons.ssl.asn1.ASN1EncodableVector;
 import org.apache.commons.ssl.asn1.DERInteger;
 import org.apache.commons.ssl.asn1.DERSequence;
-import org.apache.commons.ssl.util.Hex;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -95,13 +94,28 @@ public class KeyStoreBuilder {
         NoSuchAlgorithmException, InvalidKeyException,
         NoSuchProviderException, ProbablyBadPasswordException,
         UnrecoverableKeyException {
-        BuildResult br1 = parse(jksOrCerts, password);
+        return build(jksOrCerts, privateKey, password, null);
+    }
+
+
+    public static KeyStore build(byte[] jksOrCerts, byte[] privateKey,
+                                 char[] jksPassword, char[] keyPassword)
+        throws IOException, CertificateException, KeyStoreException,
+        NoSuchAlgorithmException, InvalidKeyException,
+        NoSuchProviderException, ProbablyBadPasswordException,
+        UnrecoverableKeyException {
+
+        if (keyPassword == null || keyPassword.length <= 0) {
+            keyPassword = jksPassword;
+        }
+
+        BuildResult br1 = parse(jksOrCerts, jksPassword, keyPassword);
         BuildResult br2 = null;
         KeyStore jks = null;
         if (br1.jks != null) {
             jks = br1.jks;
         } else if (privateKey != null && privateKey.length > 0) {
-            br2 = parse(privateKey, password);
+            br2 = parse(privateKey, jksPassword, keyPassword);
             if (br2.jks != null) {
                 jks = br2.jks;
             }
@@ -112,50 +126,57 @@ public class KeyStoreBuilder {
         // and a JKS file!).
         if (jks != null) {
             // Make sure the keystore we found is not corrupt.
-            validate(jks, password);
-            return jks;
+            br1 = validate(jks, keyPassword);
+            if (br1 == null) {
+                return jks;
+            }
         }
 
-        Key key = br1.key;
-        X509Certificate[] chain = br1.chain;
-        boolean atLeastOneNotSet = key == null || chain == null;
+        List keys = br1.keys;
+        List chains = br1.chains;        
+        boolean atLeastOneNotSet = keys == null || chains == null || keys.isEmpty() || chains.isEmpty();
         if (atLeastOneNotSet && br2 != null) {
-            if (br2.key != null) {
+            if (br2.keys != null && !br2.keys.isEmpty()) {
                 // Notice that the key from build-result-2 gets priority over the
                 // key from build-result-1 (if both had valid keys).
-                key = br2.key;
+                keys = br2.keys;
             }
-            if (chain == null) {
-                chain = br2.chain;
+            if (chains == null || chains.isEmpty()) {
+                chains = br2.chains;
             }
         }
 
-        atLeastOneNotSet = key == null || chain == null;
+        atLeastOneNotSet = keys == null || chains == null || keys.isEmpty() || chains.isEmpty();
         if (atLeastOneNotSet) {
             String missing = "";
-            if (key == null) {
+            if (keys == null) {
                 missing = " [Private key missing (bad password?)]";
             }
-            if (chain == null) {
+            if (chains == null) {
                 missing += " [Certificate chain missing]";
             }
             throw new KeyStoreException("Can't build keystore:" + missing);
         } else {
-
-            X509Certificate theOne = buildChain(key, chain);
-            String alias = "alias";
-            // The theOne is not null, then our chain was probably altered.
-            // Need to trim out the newly introduced null entries at the end of
-            // our chain.
-            if (theOne != null) {
-                chain = Certificates.trimChain(chain);
-                alias = Certificates.getCN(theOne);
-                alias = alias.replace(' ', '_');
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(null, jksPassword);
+            Iterator keysIt = keys.iterator();
+            Iterator chainsIt = chains.iterator();
+            int i = 1;
+            while (keysIt.hasNext() && chainsIt.hasNext()) {
+                Key key = (Key) keysIt.next();
+                Certificate[] c = (Certificate[]) chainsIt.next();
+                X509Certificate theOne = buildChain(key, c);
+                String alias = "alias_" + i++;
+                // The theOne is not null, then our chain was probably altered.
+                // Need to trim out the newly introduced null entries at the end of
+                // our chain.
+                if (theOne != null) {
+                    c = Certificates.trimChain(c);
+                    alias = Certificates.getCN(theOne);
+                    alias = alias.replace(' ', '_');
+                }
+                ks.setKeyEntry(alias, key, keyPassword, c);
             }
-
-            KeyStore ks = KeyStore.getInstance("jks");
-            ks.load(null, password);
-            ks.setKeyEntry(alias, key, password, chain);
             return ks;
         }
     }
@@ -205,69 +226,109 @@ public class KeyStoreBuilder {
         return theOne;
     }
 
-    public static void validate(KeyStore jks, char[] password)
+    public static BuildResult validate(KeyStore jks, char[] keyPass)
         throws CertificateException, KeyStoreException,
         NoSuchAlgorithmException, InvalidKeyException,
         NoSuchProviderException, UnrecoverableKeyException {
         Enumeration en = jks.aliases();
-        String privateKeyAlias = null;
+        boolean atLeastOneSuccess = false;
+        boolean atLeastOneFailure = false;
+
+        List keys = new LinkedList();
+        List chains = new LinkedList();
         while (en.hasMoreElements()) {
             String alias = (String) en.nextElement();
-            boolean isKey = jks.isKeyEntry(alias);
-            if (isKey) {
-                if (privateKeyAlias != null) {
-                    throw new KeyStoreException("Only 1 private key per keystore allowed for Commons-SSL");
-                } else {
-                    privateKeyAlias = alias;
+            if (jks.isKeyEntry(alias)) {
+                try {
+                    PrivateKey key = (PrivateKey) jks.getKey(alias, keyPass);
+                    // No Exception thrown, so we're good!
+                    atLeastOneSuccess = true;
+                    Certificate[] chain = jks.getCertificateChain(alias);
+                    X509Certificate[] c;
+                    if (chain != null) {
+                        c = Certificates.x509ifyChain(chain);
+                        X509Certificate theOne = buildChain(key, c);
+                        // The theOne is not null, then our chain was probably
+                        // altered.  Need to trim out the newly introduced null
+                        // entries at the end of our chain.
+                        if (theOne != null) {
+                            c = (X509Certificate[]) Certificates.trimChain(c);
+                            jks.deleteEntry(alias);
+                            jks.setKeyEntry(alias, key, keyPass, c);
+                        }
+                        keys.add(key);
+                        chains.add(c);
+                    }
+                } catch (GeneralSecurityException gse) {
+                    atLeastOneFailure = true;
+                    // This is not the key you're looking for.
                 }
             }
         }
-        if (privateKeyAlias == null) {
+        if (!atLeastOneSuccess) {
             throw new KeyStoreException("No private keys found in keystore!");
         }
-        PrivateKey key = (PrivateKey) jks.getKey(privateKeyAlias, password);
-        Certificate[] chain = jks.getCertificateChain(privateKeyAlias);
-        X509Certificate[] x509Chain = Certificates.x509ifyChain(chain);
-        X509Certificate theOne = buildChain(key, x509Chain);
-        // The theOne is not null, then our chain was probably altered.
-        // Need to trim out the newly introduced null entries at the end of
-        // our chain.
-        if (theOne != null) {
-            x509Chain = Certificates.trimChain(x509Chain);
-            jks.deleteEntry(privateKeyAlias);
-            jks.setKeyEntry(privateKeyAlias, key, password, x509Chain);
-        }
+        // The idea is a bit hacky:  if we return null, all is cool.  If
+        // we return a list, we're telling upstairs to abandon the JKS and
+        // build a new one from the BuildResults we provide.
+        // (Sun's builtin SSL refuses to deal with keystores where not all
+        // keys can be decrypted).
+        return atLeastOneFailure ? new BuildResult(keys, chains, null) : null;
     }
 
-    protected static class BuildResult {
-        protected final Key key;
-        protected final X509Certificate[] chain;
+    public static class BuildResult {
+        protected final List keys;
+        protected final List chains;
         protected final KeyStore jks;
 
-        protected BuildResult(Key key, Certificate[] chain, KeyStore jks) {
-            this.key = key;
+        protected BuildResult(List keys, List chains, KeyStore jks) {
+            if (keys == null || keys.isEmpty()) {
+                this.keys = null;
+            } else {
+                this.keys = Collections.unmodifiableList(keys);
+            }
             this.jks = jks;
-            if (chain == null) {
-                this.chain = null;
-            } else if (chain instanceof X509Certificate[]) {
-                this.chain = (X509Certificate[]) chain;
+            List x509Chains = new LinkedList();
+            if (chains != null) {
+                Iterator it = chains.iterator();
+                while (it.hasNext()) {
+                    Certificate[] chain = (Certificate[]) it.next();
+                    if (chain != null && chain.length > 0) {
+                        int len = chain.length;
+                        X509Certificate[] x509 = new X509Certificate[len];
+                        for (int i = 0; i < x509.length; i++) {
+                            x509[i] = (X509Certificate) chain[i];
+                        }
+                        x509Chains.add(x509);
+                    }
+                }
+            }
+            if (x509Chains == null || x509Chains.isEmpty()) {
+                this.chains = null;
             } else {
-                X509Certificate[] x509 = new X509Certificate[chain.length];
-                System.arraycopy(chain, 0, x509, 0, chain.length);
-                this.chain = x509;
+                this.chains = Collections.unmodifiableList(x509Chains);
             }
         }
     }
 
 
-    public static BuildResult parse(byte[] stuff, char[] password)
+    public static BuildResult parse(byte[] stuff, char[] jksPass,
+                                    char[] keyPass)
+            throws IOException, CertificateException, KeyStoreException,
+            ProbablyBadPasswordException {
+
+        return parse(stuff, jksPass, keyPass, false);
+    }
+
+    static BuildResult parse(byte[] stuff, char[] jksPass,
+                             char[] keyPass, boolean forTrustMaterial)
         throws IOException, CertificateException, KeyStoreException,
         ProbablyBadPasswordException {
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
         Key key = null;
         Certificate[] chain = null;
         try {
-            PKCS8Key pkcs8Key = new PKCS8Key(stuff, password);
+            PKCS8Key pkcs8Key = new PKCS8Key(stuff, jksPass);
             key = pkcs8Key.getPrivateKey();
         }
         catch (ProbablyBadPasswordException pbpe) {
@@ -295,17 +356,13 @@ public class KeyStoreBuilder {
         }
 
         if (chain != null || key != null) {
-            return new BuildResult(key, chain, null);
+            List chains = chain != null ? Collections.singletonList(chain) : null;
+            List keys = key != null ? Collections.singletonList(key) : null;
+            return new BuildResult(keys, chains, null);
         }
 
         boolean isProbablyPKCS12 = false;
         boolean isASN = false;
-        boolean isProbablyJKS = stuff.length >= 4 &&
-                                stuff[0] == (byte) 0xFE &&
-                                stuff[1] == (byte) 0xED &&
-                                stuff[2] == (byte) 0xFE &&
-                                stuff[3] == (byte) 0xED;
-
         ASN1Structure asn1 = null;
         try {
             asn1 = ASN1Util.analyze(stuff);
@@ -321,159 +378,147 @@ public class KeyStoreBuilder {
         }
 
         ByteArrayInputStream stuffStream = new ByteArrayInputStream(stuff);
-        if (isProbablyJKS) {
-            try {
-                return tryJKS("jks", stuffStream, password);
-            }
-            catch (ProbablyBadPasswordException pbpe) {
-                throw pbpe;
-            }
-            catch (GeneralSecurityException gse) {
-                // jks didn't work.
-            }
-            catch (IOException ioe) {
-                // jks didn't work.
+        // Try default keystore... then try others.
+        BuildResult br = tryJKS(KeyStore.getDefaultType(), stuffStream, jksPass, keyPass, forTrustMaterial);
+        if (br == null) {
+            br = tryJKS("jks", stuffStream, jksPass, keyPass, forTrustMaterial);
+            if (br == null) {
+                br = tryJKS("jceks", stuffStream, jksPass, keyPass, forTrustMaterial);
+                if (br == null) {
+                    br = tryJKS("BKS", stuffStream, jksPass, keyPass, forTrustMaterial);
+                    if (br == null) {
+                        br = tryJKS("UBER", stuffStream, jksPass, keyPass, forTrustMaterial);
+                    }
+                }
             }
         }
+        if (br != null) {
+            return br;
+        }
         if (isASN) {
             if (isProbablyPKCS12) {
-                try {
-                    return tryJKS("pkcs12", stuffStream, password);
-                }
-                catch (ProbablyBadPasswordException pbpe) {
-                    throw pbpe;
-                }
-                catch (GeneralSecurityException gse) {
-                    // pkcs12 didn't work.
-                }
-                catch (IOException ioe) {
-                    // pkcs12 didn't work.
-                }
-            } else {
-                // Okay, it's ASN.1, but it's not PKCS12.  Only one possible
-                // interesting things remains:  X.509.
-                stuffStream.reset();
-
-                try {
-                    certificates = new LinkedList();
-                    Collection certs = cf.generateCertificates(stuffStream);
-                    it = certs.iterator();
-                    while (it.hasNext()) {
-                        X509Certificate x509 = (X509Certificate) it.next();
-                        certificates.add(x509);
-                    }
-                    chain = toChain(certificates);
-                    if (chain != null && chain.length > 0) {
-                        return new BuildResult(null, chain, null);
-                    }
-                }
-                catch (CertificateException ce) {
-                    // oh well
-                }
+                return tryJKS("pkcs12", stuffStream, jksPass, null, forTrustMaterial);
+            }
+        } else {
+            // Okay, it's ASN.1, but it's not PKCS12.  Only one possible
+            // interesting things remains:  X.509.
+            stuffStream.reset();
 
-                stuffStream.reset();
-                // Okay, still no luck.  Maybe it's an ASN.1 DER stream
-                // containing only a single certificate?  (I don't completely
-                // trust CertificateFactory.generateCertificates).
-                try {
-                    Certificate c = cf.generateCertificate(stuffStream);
-                    X509Certificate x509 = (X509Certificate) c;
-                    chain = toChain(Collections.singleton(x509));
-                    if (chain != null && chain.length > 0) {
-                        return new BuildResult(null, chain, null);
-                    }
+            try {
+                certificates = new LinkedList();
+                Collection certs = cf.generateCertificates(stuffStream);
+                it = certs.iterator();
+                while (it.hasNext()) {
+                    X509Certificate x509 = (X509Certificate) it.next();
+                    certificates.add(x509);
                 }
-                catch (CertificateException ce) {
-                    // oh well
+                chain = toChain(certificates);
+                if (chain != null && chain.length > 0) {
+                    List chains = Collections.singletonList(chain);
+                    return new BuildResult(null, chains, null);
                 }
             }
-        }
+            catch (CertificateException ce) {
+                // oh well
+            }
 
-        if (!isProbablyJKS) {
-            String hex = Hex.encode(stuff, 0, 4);
+            stuffStream.reset();
+            // Okay, still no luck.  Maybe it's an ASN.1 DER stream
+            // containing only a single certificate?  (I don't completely
+            // trust CertificateFactory.generateCertificates).
             try {
-                BuildResult br = tryJKS("jks", stuffStream, password);
-                // no exception thrown, so must be JKS.
-                System.out.println("Please report bug!");
-                System.out.println("JKS usually start with binary FE ED FE ED, but this JKS started with: [" + hex + "]");
-                return br;
-            }
-            catch (ProbablyBadPasswordException pbpe) {
-                System.out.println("Please report bug!");
-                System.out.println("JKS usually start with binary FE ED FE ED, but this JKS started with: [" + hex + "]");
-                throw pbpe;
-            }
-            catch (GeneralSecurityException gse) {
-                // jks didn't work.
+                Certificate c = cf.generateCertificate(stuffStream);
+                X509Certificate x509 = (X509Certificate) c;
+                chain = toChain(Collections.singleton(x509));
+                if (chain != null && chain.length > 0) {
+                    List chains = Collections.singletonList(chain);
+                    return new BuildResult(null, chains, null);
+                }
             }
-            catch (IOException ioe) {
-                // jks didn't work.
+            catch (CertificateException ce) {
+                // oh well
             }
         }
 
-        if (!isProbablyPKCS12) {
-            try {
-                BuildResult br = tryJKS("pkcs12", stuffStream, password);
-                // no exception thrown, so must be PKCS12.
-                System.out.println("Please report bug!");
-                System.out.println("PKCS12 detection failed to realize this was PKCS12!");
-                System.out.println(asn1);
-                return br;
-            }
-            catch (ProbablyBadPasswordException pbpe) {
-                System.out.println("Please report bug!");
-                System.out.println("PKCS12 detection failed to realize this was PKCS12!");
-                System.out.println(asn1);
-                throw pbpe;
-            }
-            catch (GeneralSecurityException gse) {
-                // pkcs12 didn't work.
-            }
-            catch (IOException ioe) {
-                // pkcs12 didn't work.
-            }
+        br = tryJKS("pkcs12", stuffStream, jksPass, null, forTrustMaterial);
+        if (br != null) {
+            // no exception thrown, so must be PKCS12.
+            /*
+            Hmm, well someone finally reported this bug!   And they want the library to be quiet....
+            Commenting out for now, maybe investigate why it's happening one day....
+
+            System.out.println("Please report bug!");
+            System.out.println("PKCS12 detection failed to realize this was PKCS12!");
+            System.out.println(asn1);
+            */
+            return br;
         }
         throw new KeyStoreException("failed to extract any certificates or private keys - maybe bad password?");
     }
 
-    private static BuildResult tryJKS(String keystoreType,
-                                      ByteArrayInputStream in,
-                                      char[] password)
-        throws GeneralSecurityException, IOException {
+    private static BuildResult tryJKS(
+            String keystoreType, ByteArrayInputStream in, char[] jksPassword, char[] keyPassword,
+            boolean forTrustMaterial
+    ) throws ProbablyBadPasswordException {
         in.reset();
+        if (keyPassword == null || keyPassword.length <= 0) {
+            keyPassword = jksPassword;
+        }
+
         keystoreType = keystoreType.trim().toLowerCase();
-        boolean isPKCS12 = "pkcs12".equals(keystoreType);
-        KeyStore jksKeyStore = KeyStore.getInstance(keystoreType);
+        boolean isPKCS12 = "pkcs12".equalsIgnoreCase(keystoreType);
         try {
             Key key = null;
             Certificate[] chain = null;
-            jksKeyStore.load(in, password);
+            UnrecoverableKeyException uke = null;
+            KeyStore jksKeyStore = KeyStore.getInstance(keystoreType);
+            jksKeyStore.load(in, jksPassword);
             Enumeration en = jksKeyStore.aliases();
             while (en.hasMoreElements()) {
                 String alias = (String) en.nextElement();
                 if (jksKeyStore.isKeyEntry(alias)) {
-                    key = jksKeyStore.getKey(alias, password);
-                    if (key != null && key instanceof PrivateKey) {
-                        chain = jksKeyStore.getCertificateChain(alias);
-                        break;
+                    try {
+                        if (keyPassword != null) {
+                            key = jksKeyStore.getKey(alias, keyPassword);
+                        }
+                        if (key instanceof PrivateKey) {
+                            chain = jksKeyStore.getCertificateChain(alias);
+                            break;
+                        }
+                    } catch (UnrecoverableKeyException e) {
+                        uke = e;  // We might throw this one later. 
+                    } catch (GeneralSecurityException gse) {
+                        // Swallow... keep looping.
                     }
                 }
                 if (isPKCS12 && en.hasMoreElements()) {
                     System.out.println("what kind of weird pkcs12 file has more than one alias?");
                 }
             }
+            if (key == null && uke != null) {
+                // If we're trying to load KeyMaterial, then we *need* that key we spotted.
+                // But if we're trying to load TrustMaterial, then we're fine, and we can ignore the key.
+                if (!forTrustMaterial) {
+                    throw new ProbablyBadPasswordException("Probably bad JKS-Key password: " + uke);
+                }
+            }
             if (isPKCS12) {
                 // PKCS12 is supposed to be just a key and a chain, anyway.
                 jksKeyStore = null;
             }
-            return new BuildResult(key, chain, jksKeyStore);
+
+            List keys = Collections.singletonList(key);
+            List chains = Collections.singletonList(chain);
+            return new BuildResult(keys, chains, jksKeyStore);
+        }
+        catch (ProbablyBadPasswordException pbpe) {
+            throw pbpe;
         }
         catch (GeneralSecurityException gse) {
-            throw gse;
+            // swallow it, return null
+            return null;
         }
         catch (IOException ioe) {
-            ioe.printStackTrace();
-
             String msg = ioe.getMessage();
             msg = msg != null ? msg.trim().toLowerCase() : "";
             if (isPKCS12) {
@@ -489,8 +534,8 @@ public class KeyStoreBuilder {
                     throw new ProbablyBadPasswordException("Probably bad JKS password: " + ioe);
                 }
             }
-            ioe.printStackTrace();
-            throw ioe;
+            // swallow it, return null.
+            return null;
         }
     }
 
@@ -539,28 +584,51 @@ public class KeyStoreBuilder {
 
         KeyStore ks = build(bytes1, bytes2, password);
         Enumeration en = ks.aliases();
-        String alias = null;
+        String alias = "keystorebuilder";
+
+        // We're going to assume that the biggest key is the one we want
+        // to convert to PKCS8 (PEM).  That's until someone figures out a
+        // better way to deal with this annoying situation (more than 1
+        // key in the KeyStore).
+        int biggestKey = 0;
         while (en.hasMoreElements()) {
-            if (alias == null) {
-                alias = (String) en.nextElement();
-            } else {
-                System.out.println("Generated keystore contains more than 1 alias!?!?");
+            String s = (String) en.nextElement();
+            try {
+                PrivateKey pk = (PrivateKey) ks.getKey(s, password);
+                byte[] encoded = pk.getEncoded();
+                int len = encoded != null ? encoded.length : 0;
+                if (len >= biggestKey) {
+                    biggestKey = len;
+                    alias = s;
+                }
+            } catch (Exception e) {
+                // oh well, try next one.
             }
         }
 
         String suffix = toPKCS8 ? ".pem" : ".jks";
-        File f = new File(alias + suffix);
+        String fileName = alias;
+        Certificate[] chain = ks.getCertificateChain(alias);
+        if (chain != null && chain[0] != null) {
+            String cn = Certificates.getCN((X509Certificate) chain[0]);
+            cn = cn != null ? cn.trim() : "";
+            if (!"".equals(cn)) {
+                fileName = cn;
+            }
+        }
+
+        File f = new File(fileName + suffix);
         int count = 1;
         while (f.exists()) {
             f = new File(alias + "_" + count + suffix);
             count++;
         }
 
-        FileOutputStream jks = new FileOutputStream(f);
+        FileOutputStream fout = new FileOutputStream(f);
         if (toPKCS8) {
             List pemItems = new LinkedList();
             PrivateKey key = (PrivateKey) ks.getKey(alias, password);
-            Certificate[] chain = ks.getCertificateChain(alias);
+            chain = ks.getCertificateChain(alias);
             byte[] pkcs8DerBytes = null;
             if (key instanceof RSAPrivateCrtKey) {
                 RSAPrivateCrtKey rsa = (RSAPrivateCrtKey) key;
@@ -612,12 +680,17 @@ public class KeyStoreBuilder {
                 pemItems.add(item);
             }
             byte[] pem = PEMUtil.encode(pemItems);
-            jks.write(pem);
+            fout.write(pem);
         } else {
-            ks.store(jks, password);
+            // If we're not converting to unencrypted PKCS8 style PEM,
+            // then we are converting to Sun JKS.  It happens right here:
+            KeyStore jks = KeyStore.getInstance(KeyStore.getDefaultType());
+            jks.load(null, password);
+            jks.setKeyEntry(alias, ks.getKey(alias, password), password, ks.getCertificateChain(alias));
+            jks.store(fout, password);
         }
-        jks.flush();
-        jks.close();
+        fout.flush();
+        fout.close();
         System.out.println("Successfuly wrote: [" + f.getPath() + "]");
     }
 
diff --git a/src/java/org/apache/commons/ssl/LDAPSocket.java b/src/java/org/apache/commons/ssl/LDAPSocket.java
index 9a2fd78..8d0d393 100644
--- a/src/java/org/apache/commons/ssl/LDAPSocket.java
+++ b/src/java/org/apache/commons/ssl/LDAPSocket.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/LDAPSocket.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/LDAPSocket.java $
+ * $Revision: 165 $
+ * $Date: 2014-04-24 16:48:09 -0700 (Thu, 24 Apr 2014) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
diff --git a/src/java/org/apache/commons/ssl/LogHelper.java b/src/java/org/apache/commons/ssl/LogHelper.java
index 63c80d3..5cc70b4 100644
--- a/src/java/org/apache/commons/ssl/LogHelper.java
+++ b/src/java/org/apache/commons/ssl/LogHelper.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/LogHelper.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/LogHelper.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/LogWrapper.java b/src/java/org/apache/commons/ssl/LogWrapper.java
index 3646b76..0af6c90 100644
--- a/src/java/org/apache/commons/ssl/LogWrapper.java
+++ b/src/java/org/apache/commons/ssl/LogWrapper.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/LogWrapper.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/LogWrapper.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/OpenSSL.java b/src/java/org/apache/commons/ssl/OpenSSL.java
index f580d4a..51c304a 100644
--- a/src/java/org/apache/commons/ssl/OpenSSL.java
+++ b/src/java/org/apache/commons/ssl/OpenSSL.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/OpenSSL.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/OpenSSL.java $
+ * $Revision: 144 $
+ * $Date: 2009-05-25 11:14:29 -0700 (Mon, 25 May 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -35,10 +35,7 @@ import org.apache.commons.ssl.util.Hex;
 
 import javax.crypto.Cipher;
 import javax.crypto.CipherInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.security.GeneralSecurityException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -138,7 +135,7 @@ public class OpenSSL {
                 InputStream head = new ByteArrayInputStream(saltLine);
                 // Need to put that 16 byte "saltLine" back into the Stream.
                 encrypted = new ComboInputStream(head, encrypted);
-                encrypted = new Base64InputStream(encrypted, true);
+                encrypted = new Base64InputStream(encrypted);
                 saltLine = Util.streamToBytes(encrypted, 16);
 
                 if (saltLine.length >= 8) {
@@ -348,7 +345,7 @@ public class OpenSSL {
             cipherStream = new ComboInputStream(head, cipherStream);
         }
         if (toBase64) {
-            cipherStream = new Base64InputStream(cipherStream, false);
+            cipherStream = new Base64InputStream(cipherStream, true);
         }
         return cipherStream;
     }
@@ -371,7 +368,7 @@ public class OpenSSL {
             InputStream head = new ByteArrayInputStream(firstLine);
             // Need to put that 16 byte "firstLine" back into the Stream.
             encrypted = new ComboInputStream(head, encrypted);
-            encrypted = new Base64InputStream(encrypted, true);
+            encrypted = new Base64InputStream(encrypted);
         } else {
             // Encrypted data wasn't base64.  Need to put the "firstLine" we
             // extracted back into the stream.
@@ -436,7 +433,7 @@ public class OpenSSL {
 
         InputStream cipherStream = new CipherInputStream(data, c);
         if (toBase64) {
-            cipherStream = new Base64InputStream(cipherStream, false);
+            cipherStream = new Base64InputStream(cipherStream, true);
         }
         return cipherStream;
     }
@@ -711,9 +708,10 @@ public class OpenSSL {
 
         // in = encrypt( args[ 1 ], pwdAsBytes, in, true );
 
-        Util.pipeStream(in, System.out, false);
-        byte[] output = Util.streamToBytes(in);
-        System.out.write(output);
+        in = new BufferedInputStream(in);
+        BufferedOutputStream bufOut = new BufferedOutputStream( System.out );
+        Util.pipeStream(in, bufOut, false);
+        bufOut.flush();
         System.out.flush();
     }
 
diff --git a/src/java/org/apache/commons/ssl/OpenSSLTest.java b/src/java/org/apache/commons/ssl/OpenSSLTest.java
deleted file mode 100644
index 1b1c034..0000000
--- a/src/java/org/apache/commons/ssl/OpenSSLTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.apache.commons.ssl;
-
-import org.apache.commons.ssl.util.Hex;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.Arrays;
-
-/**
- * @author Julius Davies
- * @since 3-Jul-2007
- */
-public class OpenSSLTest {
-
-    public static void main(String[] args) throws Exception {
-        String path = args[0];
-        File f = new File(path);
-        if (f.isDirectory()) {
-            File[] files = f.listFiles();
-            Arrays.sort(files);
-            for (int i = 0; i < files.length; i++) {
-                process(files[i], 0);
-            }
-        } else {
-            System.out.println("Attempting decrypt!");
-
-            String keyS = "1234567890ABDEF01234567890ABDEFF";
-            String ivS = "1234567890ABDEF01234567890ABDEFF";
-            byte[] key = Hex.decode(keyS.getBytes());
-            byte[] iv = Hex.decode(ivS.getBytes());
-            FileInputStream in = new FileInputStream(f);
-            InputStream decrypted = OpenSSL.decrypt("aes128", key, iv, in);
-            byte[] b = Util.streamToBytes(decrypted);
-            System.out.println(new String(b));
-        }
-    }
-
-
-    private static void process(File f, int depth) {
-        String name = f.getName();
-        if ("CVS".equalsIgnoreCase(name)) {
-            return;
-        }
-        if (name.toUpperCase().startsWith("README")) {
-            return;
-        }
-
-        if (f.isDirectory()) {
-            if (depth <= 3) {
-                File[] files = f.listFiles();
-                Arrays.sort(files);
-                for (int i = 0; i < files.length; i++) {
-                    process(files[i], 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;
-                }
-                String cipher = fileName.substring(0, x);
-                String cipherPadded = Util.pad(cipher, 20, false);
-                String filePadded = Util.pad(fileName, 25, false);
-                try {
-                    FileInputStream in = new FileInputStream(f);
-                    byte[] encrypted = Util.streamToBytes(in);
-                    char[] pwd = "changeit".toCharArray();
-
-                    byte[] result = OpenSSL.decrypt(cipher, pwd, encrypted);
-                    String s = new String(result, "ISO-8859-1");
-
-                    boolean success = "Hello World!".equals(s);
-                    if (success) {
-                        System.out.println("SUCCESS \t" + cipherPadded + "\t" + filePadded);
-                    } else {
-                        System.out.println("FAILURE*\t" + cipherPadded + "\t" + filePadded + "\tDECRYPT RESULTS DON'T MATCH");
-                    }
-                }
-                catch (Exception e) {
-                    System.out.println("FAILURE*\t" + cipherPadded + "\t" + filePadded + "\t" + e);
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-}
diff --git a/src/java/org/apache/commons/ssl/PEMItem.java b/src/java/org/apache/commons/ssl/PEMItem.java
index 9b40464..d006595 100644
--- a/src/java/org/apache/commons/ssl/PEMItem.java
+++ b/src/java/org/apache/commons/ssl/PEMItem.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/PEMItem.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/PEMItem.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/PEMUtil.java b/src/java/org/apache/commons/ssl/PEMUtil.java
index 69cab97..1abf9c7 100644
--- a/src/java/org/apache/commons/ssl/PEMUtil.java
+++ b/src/java/org/apache/commons/ssl/PEMUtil.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/PEMUtil.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/PEMUtil.java $
+ * $Revision: 153 $
+ * $Date: 2009-09-15 22:40:53 -0700 (Tue, 15 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,18 +31,17 @@
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.ByteArrayReadLine;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.security.interfaces.RSAPrivateCrtKey;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.security.interfaces.RSAPublicKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.PublicKey;
+import java.util.*;
 
 /**
  * @author Credit Union Central of British Columbia
@@ -55,7 +54,7 @@ public class PEMUtil {
 
     public static byte[] encode(Collection items) throws IOException {
         final byte[] LINE_SEPARATOR_BYTES = LINE_SEPARATOR.getBytes("UTF-8");
-        ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+        ByteArrayOutputStream out = new ByteArrayOutputStream(8192);
         Iterator it = items.iterator();
         while (it.hasNext()) {
             PEMItem item = (PEMItem) it.next();
@@ -89,7 +88,8 @@ public class PEMUtil {
     public static List decode(byte[] pemBytes) {
         LinkedList pemItems = new LinkedList();
         ByteArrayInputStream in = new ByteArrayInputStream(pemBytes);
-        String line = Util.readLine(in);
+        ByteArrayReadLine readLine = new ByteArrayReadLine(in);
+        String line = readLine.next();
         while (line != null) {
             int len = 0;
             byte[] decoded;
@@ -97,14 +97,14 @@ public class PEMUtil {
             Map properties = new HashMap();
             String type = "[unknown]";
             while (line != null && !beginBase64(line)) {
-                line = Util.readLine(in);
+                line = readLine.next();
             }
             if (line != null) {
                 String upperLine = line.toUpperCase();
                 int x = upperLine.indexOf("-BEGIN") + "-BEGIN".length();
                 int y = upperLine.indexOf("-", x);
                 type = upperLine.substring(x, y).trim();
-                line = Util.readLine(in);
+                line = readLine.next();
             }
             while (line != null && !endBase64(line)) {
                 line = Util.trim(line);
@@ -124,10 +124,10 @@ public class PEMUtil {
                         len += rawBinary.length;
                     }
                 }
-                line = Util.readLine(in);
+                line = readLine.next();
             }
             if (line != null) {
-                line = Util.readLine(in);
+                line = readLine.next();
             }
 
             if (!listOfByteArrays.isEmpty()) {
@@ -234,5 +234,17 @@ public class PEMUtil {
         return buf.toString();
     }
 
+    public static String toPem(PublicKey key) throws IOException {
+        PEMItem item = null;
+        if (key instanceof RSAPublicKey) {
+            item = new PEMItem(key.getEncoded(), "PUBLIC KEY");
+        } else if (key instanceof DSAPublicKey) {
+            item = new PEMItem(key.getEncoded(), "PUBLIC KEY");
+        } else {
+            throw new IOException("Not an RSA or DSA key");
+        }
+        byte[] pem = encode(Collections.singleton(item));
+        return new String(pem, "UTF-8");
+    }
 
 }
diff --git a/src/java/org/apache/commons/ssl/PKCS8Key.java b/src/java/org/apache/commons/ssl/PKCS8Key.java
index 195b02a..7225482 100644
--- a/src/java/org/apache/commons/ssl/PKCS8Key.java
+++ b/src/java/org/apache/commons/ssl/PKCS8Key.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/PKCS8Key.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/PKCS8Key.java $
+ * $Revision: 153 $
+ * $Date: 2009-09-15 22:40:53 -0700 (Tue, 15 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,41 +31,23 @@
 
 package org.apache.commons.ssl;
 
-import org.apache.commons.ssl.asn1.ASN1EncodableVector;
-import org.apache.commons.ssl.asn1.ASN1OutputStream;
-import org.apache.commons.ssl.asn1.DEREncodable;
-import org.apache.commons.ssl.asn1.DERInteger;
-import org.apache.commons.ssl.asn1.DERNull;
-import org.apache.commons.ssl.asn1.DERObjectIdentifier;
-import org.apache.commons.ssl.asn1.DEROctetString;
-import org.apache.commons.ssl.asn1.DERSequence;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.Mac;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
+import org.apache.commons.ssl.asn1.*;
+
+import javax.crypto.*;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.RC2ParameterSpec;
 import javax.crypto.spec.RC5ParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
+import java.security.*;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.DSAPublicKeySpec;
 import java.security.spec.KeySpec;
 import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPublicKeySpec;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
@@ -318,6 +300,29 @@ public class PKCS8Key {
         return privateKey;
     }
 
+    public PublicKey getPublicKey() throws GeneralSecurityException {
+        if (privateKey instanceof DSAPrivateKey) {
+            DSAPrivateKey dsa = (DSAPrivateKey) privateKey;
+            DSAParams params = dsa.getParams();
+            BigInteger g = params.getG();
+            BigInteger p = params.getP();
+            BigInteger q = params.getQ();
+            BigInteger x = dsa.getX();
+            BigInteger y = q.modPow( x, p );
+            DSAPublicKeySpec dsaKeySpec = new DSAPublicKeySpec(y, p, q, g);
+            return KeyFactory.getInstance("DSA").generatePublic(dsaKeySpec);
+        } else if (privateKey instanceof RSAPrivateCrtKey) {
+            RSAPrivateCrtKey rsa = (RSAPrivateCrtKey) privateKey;
+            RSAPublicKeySpec rsaKeySpec = new RSAPublicKeySpec(
+                    rsa.getModulus(),
+                    rsa.getPublicExponent()
+            );
+            return KeyFactory.getInstance("RSA").generatePublic(rsaKeySpec);
+        } else {
+            throw new GeneralSecurityException("Not an RSA or DSA key");
+        }
+    }
+
     public static class DecryptResult {
         public final String transformation;
         public final int keySize;
diff --git a/src/java/org/apache/commons/ssl/Ping.java b/src/java/org/apache/commons/ssl/Ping.java
index 87bdf60..14a25bf 100644
--- a/src/java/org/apache/commons/ssl/Ping.java
+++ b/src/java/org/apache/commons/ssl/Ping.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Ping.java $
- * $Revision: 129 $
- * $Date: 2007-11-14 19:21:33 -0800 (Wed, 14 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Ping.java $
+ * $Revision: 142 $
+ * $Date: 2008-03-04 00:13:37 -0800 (Tue, 04 Mar 2008) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,6 +31,8 @@
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.ReadLine;
+
 import javax.net.ssl.SSLSocket;
 import java.io.File;
 import java.io.InputStream;
@@ -78,7 +80,7 @@ public class Ping {
     private static File clientCert;
     private static File certChain;
     private static char[] password;
-    private static TrustChain trustChain = new TrustChain();
+    private static TrustChain trustChain = null;
 
     static {
         ARGS = Collections.unmodifiableSortedSet(ARGS);
@@ -104,7 +106,7 @@ public class Ping {
                 parseException.printStackTrace(System.out);
                 System.out.println();
             }
-            System.out.println("Usage:  java -jar not-yet-commons-ssl-0.3.9.jar [options]");
+            System.out.println("Usage:  java -jar not-yet-commons-ssl-" + Version.VERSION + ".jar [options]");
             System.out.println(Version.versionString());
             System.out.println("Options:   (*=required)");
             Iterator it = ARGS.iterator();
@@ -158,7 +160,7 @@ public class Ping {
                     ssl.setKeyMaterial(km);
                 }
 
-                if (!trustChain.isEmpty()) {
+                if (trustChain != null) {
                     ssl.addTrustMaterial(trustChain);
                 }
 
@@ -180,7 +182,8 @@ public class Ping {
                     out.write(line3.getBytes());
                     out.flush();
 
-                    String read1 = Util.readLine(in);
+                    ReadLine readLine = new ReadLine(in);
+                    String read1 = readLine.next();
                     if (read1.startsWith("HTTP/1.1 200")) {
                         int avail = in.available();
                         in.skip(avail);
@@ -199,10 +202,10 @@ public class Ping {
                         System.out.println("Server returned unexpected proxy response!");
                         System.out.println("=============================================");
                         System.out.println(read1);
-                        String line = Util.readLine(in);
+                        String line = readLine.next();
                         while (line != null) {
                             System.out.println(line);
-                            line = Util.readLine(in);
+                            line = readLine.next();
                         }
                         System.exit(1);
                     }
@@ -256,7 +259,7 @@ public class Ping {
             catch (Exception e) {
                 socketException = e;
             }
-            trustException = testTrust(ssl, sslCipher);
+            trustException = testTrust(ssl, sslCipher, trustChain);
             hostnameException = testHostname(ssl);
             crlException = testCRL(ssl);
             expiryException = testExpiry(ssl);
@@ -312,7 +315,8 @@ public class Ping {
         }
     }
 
-    private static Exception testTrust(SSLClient ssl, String cipher) {
+    private static Exception testTrust(SSLClient ssl, String cipher,
+                                       TrustChain tc) {
         try {
             X509Certificate[] chain = ssl.getCurrentServerChain();
             String authType = Util.cipherToAuthType(cipher);
@@ -321,7 +325,10 @@ public class Ping {
                 authType = "RSA";
             }
             if (chain != null) {
-                Object[] trustManagers = TrustMaterial.DEFAULT.getTrustManagers();
+                if (tc == null) {
+                    tc = TrustMaterial.DEFAULT;
+                }
+                Object[] trustManagers = tc.getTrustManagers();
                 for (int i = 0; i < trustManagers.length; i++) {
                     JavaImpl.testTrust(trustManagers[i], chain, authType);
                 }
@@ -446,6 +453,9 @@ public class Ping {
                 for (int i = 0; i < values.length; i++) {
                     File f = new File(values[i]);
                     if (f.exists()) {
+                        if (trustChain == null) {
+                            trustChain = new TrustChain();
+                        }
                         TrustMaterial tm = new TrustMaterial(f);
                         trustChain.addTrustMaterial(tm);
                     }
diff --git a/src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java b/src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java
index 83e96b6..973e28b 100644
--- a/src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java
+++ b/src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/ProbablyBadPasswordException.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java b/src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java
index d0e54b5..bdc4939 100644
--- a/src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java
+++ b/src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/ProbablyNotPKCS8Exception.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java b/src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java
index 3bbe2c5..09ee983 100644
--- a/src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java
+++ b/src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/RMISocketFactoryImpl.java $
+ * $Revision: 166 $
+ * $Date: 2014-04-28 11:40:25 -0700 (Mon, 28 Apr 2014) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -506,7 +506,7 @@ public class RMISocketFactoryImpl extends RMISocketFactory {
         // have made it this far).  Maybe plain socket will work in these three
         // cases.
         sf = plainClient;
-        s = JavaImpl.connect(null, sf, host, port, local, 0, 15000);
+        s = JavaImpl.connect(null, sf, host, port, local, 0, 15000, null);
         if (soTimeout != Integer.MIN_VALUE) {
             s.setSoTimeout(soTimeout);
         }
@@ -537,7 +537,7 @@ public class RMISocketFactoryImpl extends RMISocketFactory {
             // This code doesn't actually send any packets (so no firewalls can
             // get in the way).  It's just a neat trick for getting our
             // internet-facing interface card.
-            InetAddress addr = InetAddress.getByName(anInternetIP);
+            InetAddress addr = Util.toInetAddress(anInternetIP);
             dg.connect(addr, 12345);
             InetAddress localAddr = dg.getLocalAddress();
             ip = localAddr.getHostAddress();
diff --git a/src/java/org/apache/commons/ssl/SSL.java b/src/java/org/apache/commons/ssl/SSL.java
index f688694..4e7f9bf 100644
--- a/src/java/org/apache/commons/ssl/SSL.java
+++ b/src/java/org/apache/commons/ssl/SSL.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSL.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSL.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,11 +31,8 @@
 
 package org.apache.commons.ssl;
 
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
+import javax.net.SocketFactory;
+import javax.net.ssl.*;
 import java.io.File;
 import java.io.IOException;
 import java.net.InetAddress;
@@ -48,17 +45,7 @@ import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.*;
 
 /**
  * Not thread-safe.  (But who would ever share this thing across multiple
@@ -71,7 +58,7 @@ import java.util.TreeSet;
  */
 public class SSL {
     private final static String[] KNOWN_PROTOCOLS =
-        {"TLSv1", "SSLv3", "SSLv2", "SSLv2Hello"};
+            {"TLSv1", "SSLv3", "SSLv2", "SSLv2Hello"};
 
     // SUPPORTED_CIPHERS_ARRAY is initialized in the static constructor.
     private final static String[] SUPPORTED_CIPHERS;
@@ -118,8 +105,8 @@ public class SSL {
     private SSLSocketFactory socketFactory = null;
     private SSLServerSocketFactory serverSocketFactory = null;
     private HostnameVerifier hostnameVerifier = HostnameVerifier.DEFAULT;
+    private boolean isSecure = true;  // if false, the client-style operations only create plain sockets.
     private boolean checkHostname = true;
-    private final ArrayList allowedNames = new ArrayList();
     private boolean checkCRL = true;
     private boolean checkExpiry = true;
     private boolean useClientMode = false;
@@ -136,11 +123,12 @@ public class SSL {
     private boolean wantClientAuth = true;
     private boolean needClientAuth = false;
     private SSLWrapperFactory sslWrapperFactory = SSLWrapperFactory.NO_WRAP;
+    private Map dnsOverride;
 
     protected final boolean usingSystemProperties;
 
     public SSL()
-        throws GeneralSecurityException, IOException {
+            throws GeneralSecurityException, IOException {
         boolean usingSysProps = false;
         Properties props = System.getProperties();
         boolean ksSet = props.containsKey("javax.net.ssl.keyStore");
@@ -211,8 +199,8 @@ public class SSL {
     }
 
     private void dirtyAndReloadIfYoung()
-        throws NoSuchAlgorithmException, KeyStoreException,
-        KeyManagementException, IOException, CertificateException {
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
         dirty();
         if (initCount >= 0 && initCount <= 5) {
             // The first five init's we do early (before any sockets are
@@ -227,8 +215,30 @@ public class SSL {
         }
     }
 
+    String dnsOverride(String host) {
+        if (dnsOverride != null && dnsOverride.containsKey(host)) {
+            String override = (String) dnsOverride.get(host);
+            if (override != null && !"".equals(override.trim())) {
+                return override;
+            }
+        }
+        return host;
+    }
+
+    public void setDnsOverride(Map m) {
+        this.dnsOverride = m;
+    }
+
+    public void setIsSecure(boolean b) {
+        this.isSecure = b;
+    }
+
+    public boolean isSecure() {
+        return isSecure;
+    }
+
     public SSLContext getSSLContext()
-        throws GeneralSecurityException, IOException
+            throws GeneralSecurityException, IOException
 
     {
         Object obj = getSSLContextAsObject();
@@ -250,7 +260,7 @@ public class SSL {
      * @throws IOException              problem creating SSLContext
      */
     public Object getSSLContextAsObject()
-        throws GeneralSecurityException, IOException
+            throws GeneralSecurityException, IOException
 
     {
         if (sslContext == null) {
@@ -260,8 +270,8 @@ public class SSL {
     }
 
     public void addTrustMaterial(TrustChain trustChain)
-        throws NoSuchAlgorithmException, KeyStoreException,
-        KeyManagementException, IOException, CertificateException {
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
         if (this.trustChain == null || trustChain == TrustMaterial.TRUST_ALL) {
             this.trustChain = trustChain;
         } else {
@@ -271,22 +281,23 @@ public class SSL {
     }
 
     public void setTrustMaterial(TrustChain trustChain)
-        throws NoSuchAlgorithmException, KeyStoreException,
-        KeyManagementException, IOException, CertificateException {
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
         this.trustChain = trustChain;
         dirtyAndReloadIfYoung();
     }
 
     public void setKeyMaterial(KeyMaterial keyMaterial)
-        throws NoSuchAlgorithmException, KeyStoreException,
-        KeyManagementException, IOException, CertificateException {
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
         this.keyMaterial = keyMaterial;
         dirtyAndReloadIfYoung();
     }
 
     public X509Certificate[] getAssociatedCertificateChain() {
         if (keyMaterial != null) {
-            return keyMaterial.getAssociatedCertificateChain();
+            List list = keyMaterial.getAssociatedCertificateChains();
+            return (X509Certificate[]) list.get(0);
         } else {
             return null;
         }
@@ -365,54 +376,6 @@ public class SSL {
         return checkHostname;
     }
 
-    /**
-     * @return String[] array of alternate "allowed names" to try against a
-     *         server's x509 CN field if the host/ip we used didn't match.
-     *         Returns an empty list if there are no "allowedNames" currently
-     *         set.
-     */
-    public List getAllowedNames() {
-        return Collections.unmodifiableList(allowedNames);
-    }
-
-    /**
-     * Offers a secure way to use virtual-hosting and SSL in some situations:
-     * for example you want to connect to "bar.com" but you know in advance
-     * that the SSL Certificate on that server only contains "CN=foo.com".  If
-     * you setAllowedNames( new String[] { "foo.com" } ) on your SSLClient in
-     * advance, you can connect securely, while still using "bar.com" as the
-     * host.
-     * <p/>
-     * Here's a code example using "cucbc.com" to connect, but anticipating
-     * "www.cucbc.com" in the server's certificate:
-     * <pre>
-     * SSLClient client = new SSLClient();
-     * client.setAllowedNames( new String[] { "www.cucbc.com" } );
-     * Socket s = client.createSocket( "cucbc.com", 443 );
-     * </pre>
-     * <p/>
-     * This technique is also useful if you don't want to use DNS, and want to
-     * connect using the IP address.
-     *
-     * @param allowedNames Collection of alternate "allowed names" to try against
-     *                     a server's x509 CN field if the host/ip we used didn't
-     *                     match.  Set to null to force strict matching against
-     *                     host/ip passed into createSocket().  Null is the
-     *                     default value.  Must be set in advance, before
-     *                     createSocket() is called.
-     */
-    public void addAllowedNames(Collection allowedNames) {
-        this.allowedNames.addAll(allowedNames);
-    }
-
-    public void addAllowedName(String allowedName) {
-        this.allowedNames.add(allowedName);
-    }
-
-    public void clearAllowedNames() {
-        this.allowedNames.clear();
-    }
-
     public void setCheckHostname(boolean checkHostname) {
         this.checkHostname = checkHostname;
     }
@@ -512,47 +475,46 @@ public class SSL {
     }
 
     private void init()
-        throws NoSuchAlgorithmException, KeyStoreException,
-        KeyManagementException, IOException, CertificateException {
+            throws NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException, IOException, CertificateException {
         socketFactory = null;
         serverSocketFactory = null;
         this.sslContext = JavaImpl.init(this, trustChain, keyMaterial);
         initCount++;
     }
 
-    public void doPreConnectSocketStuff(SSLSocket s)
-        throws IOException {
-        if (!useClientModeDefault) {
-            s.setUseClientMode(useClientMode);
+    public void doPreConnectSocketStuff(Socket s) throws IOException {
+        if (s instanceof SSLSocket && !useClientModeDefault) {
+            ((SSLSocket) s).setUseClientMode(useClientMode);
         }
         if (soTimeout > 0) {
             s.setSoTimeout(soTimeout);
         }
-        if (enabledProtocols != null) {
-            JavaImpl.setEnabledProtocols(s, enabledProtocols);
-        }
-        if (enabledCiphers != null) {
-            s.setEnabledCipherSuites(enabledCiphers);
+        if (s instanceof SSLSocket) {
+            if (enabledProtocols != null) {
+                JavaImpl.setEnabledProtocols(s, enabledProtocols);
+            }
+            if (enabledCiphers != null) {
+                ((SSLSocket) s).setEnabledCipherSuites(enabledCiphers);
+            }
         }
     }
 
-    public void doPostConnectSocketStuff(SSLSocket s, String host)
-        throws IOException {
-        if (checkHostname) {
-            int size = allowedNames.size() + 1;
-            String[] hosts = new String[size];
-            // hosts[ 0 ] MUST ALWAYS be the host given to createSocket().
-            hosts[0] = host;
-            int i = 1;
-            for (Iterator it = allowedNames.iterator(); it.hasNext(); i++) {
-                hosts[i] = (String) it.next();
-            }
-            hostnameVerifier.check(hosts, s);
+    public void doPostConnectSocketStuff(Socket s, String host)
+            throws IOException {
+        if (checkHostname && s instanceof SSLSocket) {
+            hostnameVerifier.check(host, (SSLSocket) s);
         }
     }
 
-    public SSLSocket createSocket() throws IOException {
-        return sslWrapperFactory.wrap(JavaImpl.createSocket(this));
+    public Socket createSocket() throws IOException {
+        if (isSecure) {
+            return sslWrapperFactory.wrap(JavaImpl.createSocket(this));
+        } else {
+            Socket s = SocketFactory.getDefault().createSocket();
+            doPreConnectSocketStuff(s);
+            return s;
+        }
     }
 
     /**
@@ -569,28 +531,34 @@ public class SSL {
      * @throws UnknownHostException if the IP address of the host cannot be
      *                              determined
      */
-    public Socket createSocket(String remoteHost, int remotePort,
-                               InetAddress localHost, int localPort,
-                               int timeout)
-        throws IOException {
+    public Socket createSocket(
+            String remoteHost, int remotePort, InetAddress localHost, int localPort, int timeout
+    ) throws IOException {
         // Only use our factory-wide connectTimeout if this method was passed
         // in a timeout of 0 (infinite).
         int factoryTimeout = getConnectTimeout();
         int connectTimeout = timeout == 0 ? factoryTimeout : timeout;
-        SSLSocket s = JavaImpl.createSocket(this, remoteHost, remotePort,
-            localHost, localPort,
-            connectTimeout);
+        Socket s;
+        if (isSecure) {
+            s = JavaImpl.createSocket(
+                    this, remoteHost, remotePort, localHost, localPort, connectTimeout
+            );
+        } else {
+            s = JavaImpl.createPlainSocket(
+                    this, remoteHost, remotePort, localHost, localPort, connectTimeout
+            );
+        }
         return sslWrapperFactory.wrap(s);
     }
 
-    public Socket createSocket(Socket s, String remoteHost, int remotePort,
-                               boolean autoClose)
-        throws IOException {
+    public Socket createSocket(
+            Socket s, String remoteHost, int remotePort, boolean autoClose
+    ) throws IOException {
         SSLSocketFactory sf = getSSLSocketFactory();
         s = sf.createSocket(s, remoteHost, remotePort, autoClose);
-        doPreConnectSocketStuff((SSLSocket) s);
-        doPostConnectSocketStuff((SSLSocket) s, remoteHost);
-        return sslWrapperFactory.wrap((SSLSocket) s);
+        doPreConnectSocketStuff(s);
+        doPostConnectSocketStuff(s, remoteHost);
+        return sslWrapperFactory.wrap(s);
     }
 
     public ServerSocket createServerSocket() throws IOException {
@@ -610,7 +578,7 @@ public class SSL {
      */
     public ServerSocket createServerSocket(int port, int backlog,
                                            InetAddress localHost)
-        throws IOException {
+            throws IOException {
         SSLServerSocketFactory f = getSSLServerSocketFactory();
         ServerSocket ss = f.createServerSocket(port, backlog, localHost);
         SSLServerSocket s = (SSLServerSocket) ss;
@@ -619,7 +587,7 @@ public class SSL {
     }
 
     public void doPreConnectServerSocketStuff(SSLServerSocket s)
-        throws IOException {
+            throws IOException {
         if (soTimeout > 0) {
             s.setSoTimeout(soTimeout);
         }
diff --git a/src/java/org/apache/commons/ssl/SSLClient.java b/src/java/org/apache/commons/ssl/SSLClient.java
index 626c0b1..4bf0e86 100644
--- a/src/java/org/apache/commons/ssl/SSLClient.java
+++ b/src/java/org/apache/commons/ssl/SSLClient.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLClient.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLClient.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -43,8 +43,7 @@ import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.List;
+import java.util.Map;
 
 /**
  * @author Credit Union Central of British Columbia
@@ -78,11 +77,9 @@ public class SSLClient extends SSLSocketFactory {
         ssl.setKeyMaterial(keyMaterial);
     }
 
-    public void addAllowedName(String s) { ssl.addAllowedName(s); }
+    public void setIsSecure(boolean b) { ssl.setIsSecure(b); }
 
-    public void addAllowedNames(Collection c) { ssl.addAllowedNames(c); }
-
-    public void clearAllowedNames() { ssl.clearAllowedNames(); }
+    public void setDnsOverride(Map m) { ssl.setDnsOverride(m); }    
 
     public void setCheckCRL(boolean b) { ssl.setCheckCRL(b); }
 
@@ -122,7 +119,7 @@ public class SSLClient extends SSLSocketFactory {
 
     public void setUseClientMode(boolean b) { ssl.setUseClientMode(b); }
 
-    public List getAllowedNames() { return ssl.getAllowedNames(); }
+    public boolean isSecure() { return ssl.isSecure(); }
 
     public X509Certificate[] getAssociatedCertificateChain() {
         return ssl.getAssociatedCertificateChain();
diff --git a/src/java/org/apache/commons/ssl/SSLEchoServer.java b/src/java/org/apache/commons/ssl/SSLEchoServer.java
index 632606e..6ec4f0a 100644
--- a/src/java/org/apache/commons/ssl/SSLEchoServer.java
+++ b/src/java/org/apache/commons/ssl/SSLEchoServer.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLEchoServer.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLEchoServer.java $
+ * $Revision: 138 $
+ * $Date: 2008-03-03 23:50:07 -0800 (Mon, 03 Mar 2008) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,6 +31,8 @@
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.ReadLine;
+
 import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLSession;
@@ -57,9 +59,13 @@ public class SSLEchoServer {
         }
 
         SSLServer ssl = new SSLServer();
-        // ssl.setCheckExpiry( false );
-        // ssl.setNeedClientAuth( true );
-        ssl.addTrustMaterial(TrustMaterial.TRUST_ALL);
+        ssl.setTrustMaterial(TrustMaterial.TRUST_ALL);
+        ssl.setCheckExpiry(false);
+        ssl.setCheckCRL(false);
+        ssl.setCheckHostname(false);
+        ssl.setWantClientAuth(true);
+        ssl.useDefaultJavaCiphers();
+
         SSLServerSocket ss = (SSLServerSocket) ssl.createServerSocket(port, 3);
         System.out.println("SSL Echo server listening on port: " + port);
         while (true) {
@@ -100,11 +106,13 @@ public class SSLEchoServer {
                 }
                 catch (SSLPeerUnverifiedException sslpue) {
                     // oh well, no client cert for us
+                    System.out.println(sslpue);
                 }
 
                 in = s.getInputStream();
                 out = s.getOutputStream();
-                String line = Util.readLine(in);
+                ReadLine readLine = new ReadLine(in);
+                String line = readLine.next();
                 if (line != null && line.indexOf("HTTP") > 0) {
                     out.write("HTTP/1.1 200 OK\r\n\r\n".getBytes());
                     out.flush();
@@ -113,7 +121,7 @@ public class SSLEchoServer {
                     String echo = "ECHO:>" + line + "\n";
                     out.write(echo.getBytes());
                     out.flush();
-                    line = Util.readLine(in);
+                    line = readLine.next();
                 }
             }
             catch (IOException ioe) {
diff --git a/src/java/org/apache/commons/ssl/SSLProxyServer.java b/src/java/org/apache/commons/ssl/SSLProxyServer.java
index ed3d62d..0bc90b0 100644
--- a/src/java/org/apache/commons/ssl/SSLProxyServer.java
+++ b/src/java/org/apache/commons/ssl/SSLProxyServer.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLProxyServer.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLProxyServer.java $
+ * $Revision: 132 $
+ * $Date: 2008-01-11 21:20:26 -0800 (Fri, 11 Jan 2008) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,6 +31,8 @@
 
 package org.apache.commons.ssl;
 
+import org.apache.commons.ssl.util.ReadLine;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InterruptedIOException;
@@ -82,7 +84,8 @@ public class SSLProxyServer {
             try {
                 in = s.getInputStream();
                 out = s.getOutputStream();
-                String line = Util.readLine(in);
+                ReadLine readLine = new ReadLine(in);
+                String line = readLine.next();
                 line = line.trim();
                 String connect = line.substring(0, "CONNECT".length());
                 InetSocketAddress addr = null;
diff --git a/src/java/org/apache/commons/ssl/SSLServer.java b/src/java/org/apache/commons/ssl/SSLServer.java
index d110b8e..7728192 100644
--- a/src/java/org/apache/commons/ssl/SSLServer.java
+++ b/src/java/org/apache/commons/ssl/SSLServer.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLServer.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLServer.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -43,8 +43,7 @@ import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -144,6 +143,8 @@ public class SSLServer extends SSLServerSocketFactory {
         return success;
     }
 
+    public void setDnsOverride(Map m) { ssl.setDnsOverride(m); }
+
     public void addTrustMaterial(TrustChain trustChain)
         throws NoSuchAlgorithmException, KeyStoreException,
         KeyManagementException, IOException, CertificateException {
@@ -162,12 +163,6 @@ public class SSLServer extends SSLServerSocketFactory {
         ssl.setKeyMaterial(keyMaterial);
     }
 
-    public void addAllowedName(String s) { ssl.addAllowedName(s); }
-
-    public void addAllowedNames(Collection c) { ssl.addAllowedNames(c); }
-
-    public void clearAllowedNames() { ssl.clearAllowedNames(); }
-
     public void setCheckCRL(boolean b) { ssl.setCheckCRL(b); }
 
     public void setCheckExpiry(boolean b) { ssl.setCheckExpiry(b); }
@@ -206,8 +201,6 @@ public class SSLServer extends SSLServerSocketFactory {
 
     public void setUseClientMode(boolean b) { ssl.setUseClientMode(b); }
 
-    public List getAllowedNames() { return ssl.getAllowedNames(); }
-
     public X509Certificate[] getAssociatedCertificateChain() {
         return ssl.getAssociatedCertificateChain();
     }
diff --git a/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java b/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java
index f83e158..a199403 100644
--- a/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java
+++ b/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLServerSocketWrapper.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/SSLSocketWrapper.java b/src/java/org/apache/commons/ssl/SSLSocketWrapper.java
index 20726d5..b569168 100644
--- a/src/java/org/apache/commons/ssl/SSLSocketWrapper.java
+++ b/src/java/org/apache/commons/ssl/SSLSocketWrapper.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLSocketWrapper.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLSocketWrapper.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -38,6 +38,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetAddress;
+import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.channels.SocketChannel;
@@ -49,79 +50,161 @@ import java.nio.channels.SocketChannel;
  * @since 16-Aug-2006
  */
 public class SSLSocketWrapper extends SSLSocket {
-    protected SSLSocket s;
+    protected Socket s;
 
-    public SSLSocketWrapper(SSLSocket s) {
+    public SSLSocketWrapper(Socket s) {
         this.s = s;
     }
 
     /* javax.net.ssl.SSLSocket */
 
     public void addHandshakeCompletedListener(HandshakeCompletedListener hcl) {
-        s.addHandshakeCompletedListener(hcl);
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).addHandshakeCompletedListener(hcl);
+        }
     }
 
     public void removeHandshakeCompletedListener(HandshakeCompletedListener hcl) {
-        s.removeHandshakeCompletedListener(hcl);
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).removeHandshakeCompletedListener(hcl);
+        }
     }
 
     public String[] getSupportedCipherSuites() {
-        return s.getSupportedCipherSuites();
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getSupportedCipherSuites();
+        } else {
+            return null;
+        }
     }
 
     public boolean getEnableSessionCreation() {
-        return s.getEnableSessionCreation();
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getEnableSessionCreation();
+        } else {
+            return false;
+        }
     }
 
     public String[] getEnabledCipherSuites() {
-        return s.getEnabledCipherSuites();
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getEnabledCipherSuites();
+        } else {
+            return null;
+        }
     }
 
-    public String[] getSupportedProtocols() { return s.getSupportedProtocols(); }
+    public String[] getSupportedProtocols() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getSupportedProtocols();
+        } else {
+            return null;
+        }
+    }
 
-    public String[] getEnabledProtocols() { return s.getEnabledProtocols(); }
+    public String[] getEnabledProtocols() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getEnabledProtocols();
+        } else {
+            return null;
+        }
+    }
 
-    public SSLSession getSession() { return s.getSession(); }
+    public SSLSession getSession() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getSession();
+        } else {
+            return null;
+        }
+    }
 
-    public boolean getUseClientMode() { return s.getUseClientMode(); }
+    public boolean getUseClientMode() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getUseClientMode();
+        } else {
+            return false;
+        }
+    }
 
-    public boolean getNeedClientAuth() { return s.getNeedClientAuth(); }
+    public boolean getNeedClientAuth() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getNeedClientAuth();
+        } else {
+            return false;
+        }
+    }
 
-    public boolean getWantClientAuth() { return s.getWantClientAuth(); }
+    public boolean getWantClientAuth() {
+        if (s instanceof SSLSocket) {
+            return ((SSLSocket) s).getWantClientAuth();
+        } else {
+            return false;
+        }
+    }
 
     public void setEnabledCipherSuites(String[] cs) {
-        s.setEnabledCipherSuites(cs);
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setEnabledCipherSuites(cs);
+        }
     }
 
     public void setEnabledProtocols(String[] ep) {
-        s.setEnabledProtocols(ep);
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setEnabledProtocols(ep);
+        }
     }
 
-    public void startHandshake() throws IOException { s.startHandshake(); }
+    public void startHandshake() throws IOException {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).startHandshake();
+        }
+    }
 
-    public void setUseClientMode(boolean b) { s.setUseClientMode(b); }
+    public void setUseClientMode(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setUseClientMode(b);
+        }
+    }
 
-    public void setNeedClientAuth(boolean b) { s.setNeedClientAuth(b); }
+    public void setNeedClientAuth(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setNeedClientAuth(b);
+        }
+    }
 
-    public void setWantClientAuth(boolean b) { s.setWantClientAuth(b); }
+    public void setWantClientAuth(boolean b) {
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setWantClientAuth(b);
+        }
+    }
 
     public void setEnableSessionCreation(boolean b) {
-        s.setEnableSessionCreation(b);
+        if (s instanceof SSLSocket) {
+            ((SSLSocket) s).setEnableSessionCreation(b);
+        }
     }
 
     /* java.net.Socket */
 
-    public SocketChannel getChannel() { return s.getChannel(); }
+    public SocketChannel getChannel() {
+        return s.getChannel();
+    }
 
-    public InetAddress getInetAddress() { return s.getInetAddress(); }
+    public InetAddress getInetAddress() {
+        return s.getInetAddress();
+    }
 
     public boolean getKeepAlive() throws SocketException {
         return s.getKeepAlive();
     }
 
-    public InetAddress getLocalAddress() { return s.getLocalAddress(); }
+    public InetAddress getLocalAddress() {
+        return s.getLocalAddress();
+    }
 
-    public int getLocalPort() { return s.getLocalPort(); }
+    public int getLocalPort() {
+        return s.getLocalPort();
+    }
 
     public SocketAddress getLocalSocketAddress() {
         return s.getLocalSocketAddress();
@@ -131,7 +214,9 @@ public class SSLSocketWrapper extends SSLSocket {
         return s.getOOBInline();
     }
 
-    public int getPort() { return s.getPort(); }
+    public int getPort() {
+        return s.getPort();
+    }
 
     public int getReceiveBufferSize() throws SocketException {
         return s.getReceiveBufferSize();
@@ -149,9 +234,13 @@ public class SSLSocketWrapper extends SSLSocket {
         return s.getSendBufferSize();
     }
 
-    public int getSoLinger() throws SocketException { return s.getSoLinger(); }
+    public int getSoLinger() throws SocketException {
+        return s.getSoLinger();
+    }
 
-    public int getSoTimeout() throws SocketException { return s.getSoTimeout(); }
+    public int getSoTimeout() throws SocketException {
+        return s.getSoTimeout();
+    }
 
     public boolean getTcpNoDelay() throws SocketException {
         return s.getTcpNoDelay();
@@ -161,15 +250,25 @@ public class SSLSocketWrapper extends SSLSocket {
         return s.getTrafficClass();
     }
 
-    public boolean isBound() { return s.isBound(); }
+    public boolean isBound() {
+        return s.isBound();
+    }
 
-    public boolean isClosed() { return s.isClosed(); }
+    public boolean isClosed() {
+        return s.isClosed();
+    }
 
-    public boolean isConnected() { return s.isConnected(); }
+    public boolean isConnected() {
+        return s.isConnected();
+    }
 
-    public boolean isInputShutdown() { return s.isInputShutdown(); }
+    public boolean isInputShutdown() {
+        return s.isInputShutdown();
+    }
 
-    public boolean isOutputShutdown() { return s.isOutputShutdown(); }
+    public boolean isOutputShutdown() {
+        return s.isOutputShutdown();
+    }
 
     public void sendUrgentData(int data) throws IOException {
         s.sendUrgentData(data);
@@ -211,11 +310,17 @@ public class SSLSocketWrapper extends SSLSocket {
         s.setTrafficClass(tc);
     }
 
-    public void shutdownInput() throws IOException { s.shutdownInput(); }
+    public void shutdownInput() throws IOException {
+        s.shutdownInput();
+    }
 
-    public void shutdownOutput() throws IOException { s.shutdownOutput(); }
+    public void shutdownOutput() throws IOException {
+        s.shutdownOutput();
+    }
 
-    public String toString() { return s.toString(); }
+    public String toString() {
+        return s.toString();
+    }
 
     /*  Java 1.5
      public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
diff --git a/src/java/org/apache/commons/ssl/SSLWrapperFactory.java b/src/java/org/apache/commons/ssl/SSLWrapperFactory.java
index 3848259..d98255e 100644
--- a/src/java/org/apache/commons/ssl/SSLWrapperFactory.java
+++ b/src/java/org/apache/commons/ssl/SSLWrapperFactory.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/SSLWrapperFactory.java $
- * $Revision: 129 $
- * $Date: 2007-11-14 19:21:33 -0800 (Wed, 14 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/SSLWrapperFactory.java $
+ * $Revision: 155 $
+ * $Date: 2009-09-17 14:00:58 -0700 (Thu, 17 Sep 2009) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -34,6 +34,7 @@ package org.apache.commons.ssl;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLSocket;
 import java.io.IOException;
+import java.net.Socket;
 
 /**
  * @author Credit Union Central of British Columbia
@@ -50,7 +51,7 @@ public interface SSLWrapperFactory {
      * @return The new wrapped SSLSocket.
      * @throws IOException if wrapping failed
      */
-    public SSLSocket wrap(SSLSocket s) throws IOException;
+    public Socket wrap(Socket s) throws IOException;
 
     /**
      * Wraps an SSLServerSocket.
@@ -75,7 +76,7 @@ public interface SSLWrapperFactory {
      */
     public final static SSLWrapperFactory NO_WRAP = new SSLWrapperFactory() {
         // Notice!  No wrapping!
-        public SSLSocket wrap(SSLSocket s) { return s; }
+        public Socket wrap(Socket s) { return s; }
 
         // We still wrap the ServerSocket, but we don't wrap the result of the
         // the accept() call.
@@ -94,7 +95,7 @@ public interface SSLWrapperFactory {
      * implementations.
      */
     public final static SSLWrapperFactory DUMB_WRAP = new SSLWrapperFactory() {
-        public SSLSocket wrap(SSLSocket s) { return new SSLSocketWrapper(s); }
+        public Socket wrap(Socket s) { return new SSLSocketWrapper(s); }
 
         public SSLServerSocket wrap(SSLServerSocket s, SSL ssl)
             throws IOException {
diff --git a/src/java/org/apache/commons/ssl/TomcatServerXML.java b/src/java/org/apache/commons/ssl/TomcatServerXML.java
index e9ccc5c..c0b9b1e 100644
--- a/src/java/org/apache/commons/ssl/TomcatServerXML.java
+++ b/src/java/org/apache/commons/ssl/TomcatServerXML.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/TomcatServerXML.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/TomcatServerXML.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/TrustChain.java b/src/java/org/apache/commons/ssl/TrustChain.java
index 4ef8683..d1675a2 100644
--- a/src/java/org/apache/commons/ssl/TrustChain.java
+++ b/src/java/org/apache/commons/ssl/TrustChain.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/TrustChain.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/TrustChain.java $
+ * $Revision: 138 $
+ * $Date: 2008-03-03 23:50:07 -0800 (Mon, 03 Mar 2008) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -202,5 +202,18 @@ public class TrustChain {
         return getCertificates().isEmpty();
     }
 
+    protected boolean containsTrustAll() {
+        Iterator it = trustMaterial.iterator();
+        while (it.hasNext()) {
+            TrustChain tc = (TrustChain) it.next();
+            if (tc == this) {
+                continue;
+            }
+            if (tc.containsTrustAll()) {
+                return true;
+            }
+        }
+        return false;
+    }
 
 }
diff --git a/src/java/org/apache/commons/ssl/TrustMaterial.java b/src/java/org/apache/commons/ssl/TrustMaterial.java
index 79caceb..78213f8 100644
--- a/src/java/org/apache/commons/ssl/TrustMaterial.java
+++ b/src/java/org/apache/commons/ssl/TrustMaterial.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/TrustMaterial.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
@@ -39,6 +39,7 @@ 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;
@@ -56,10 +57,14 @@ 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. */
+    /**
+     * 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. */
+    /**
+     * Might be null if "$JAVA_HOME/jre/lib/security/jssecacerts" doesn't exist.
+     */
     public final static TrustMaterial JSSE_CACERTS;
 
     /**
@@ -200,20 +205,23 @@ public class TrustMaterial extends TrustChain {
         this(Util.streamToBytes(jks), password);
     }
 
-
     public TrustMaterial(byte[] jks, char[] password)
         throws GeneralSecurityException, IOException {
 
-        KeyStoreBuilder.BuildResult br = KeyStoreBuilder.parse(jks, password);
+        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("jks");
-            if (br.chain != null && br.chain.length > 0) {
-                ks.load(null, password);
-                loadCerts(ks, Arrays.asList(br.chain));
+            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;
         }
@@ -234,12 +242,6 @@ public class TrustMaterial extends TrustChain {
             throw new KeyStoreException("TrustMaterial couldn't load any certificates to trust!");
         }
 
-        // overwrite password
-        if (password != null && !(this instanceof KeyMaterial)) {
-            for (int i = 0; i < password.length; i++) {
-                password[i] = '*';
-            }
-        }
         addTrustMaterial(this);
 
         // We're not a simple trust type, so set value to 0.
@@ -268,5 +270,12 @@ public class TrustMaterial extends TrustChain {
         }
     }
 
+    protected boolean containsTrustAll() {
+        boolean yes = this.simpleTrustType == SIMPLE_TRUST_TYPE_TRUST_ALL;
+        if ( !yes ) {
+            yes = super.containsTrustAll();
+        }
+        return yes;
+    }
 
 }
diff --git a/src/java/org/apache/commons/ssl/Util.java b/src/java/org/apache/commons/ssl/Util.java
index d16cde8..94c8036 100644
--- a/src/java/org/apache/commons/ssl/Util.java
+++ b/src/java/org/apache/commons/ssl/Util.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Util.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Util.java $
+ * $Revision: 166 $
+ * $Date: 2014-04-28 11:40:25 -0700 (Mon, 28 Apr 2014) $
  *
  * ====================================================================
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,10 +31,14 @@
 
 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.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.LinkedList;
 import java.util.Map;
@@ -98,7 +102,7 @@ public class Util {
     public static void pipeStream(InputStream in, OutputStream out,
                                   boolean autoClose)
         throws IOException {
-        byte[] buf = new byte[4096];
+        byte[] buf = new byte[8192];
         IOException ioe = null;
         try {
             int bytesRead = in.read(buf);
@@ -295,40 +299,6 @@ public class Util {
         return args;
     }
 
-    public static String readLine(final InputStream in) throws IOException {
-        StringBuffer buf = new StringBuffer(64);
-        int b = in.read();
-        while (b != -1) {
-            char c = (char) b;
-            if (c == '\n' || c == '\r') {
-                if (buf.length() >= 1) {
-                    return buf.toString();
-                }
-            } else {
-                buf.append(c);
-            }
-            b = in.read();
-        }
-        return buf.length() >= 1 ? buf.toString() : null;
-    }
-
-    public static String readLine(final ByteArrayInputStream in) {
-        StringBuffer buf = new StringBuffer(64);
-        int b = in.read();
-        while (b != -1) {
-            char c = (char) b;
-            if (c == '\n' || c == '\r') {
-                if (buf.length() >= 1) {
-                    return buf.toString();
-                }
-            } else {
-                buf.append(c);
-            }
-            b = in.read();
-        }
-        return buf.length() >= 1 ? buf.toString() : null;
-    }
-
     public static HostPort toAddress(final String target,
                                      final int defaultPort)
         throws UnknownHostException {
@@ -377,24 +347,42 @@ public class Util {
         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";
-        InputStream in = new ByteArrayInputStream(s.getBytes());
-        String line = readLine(in);
+        ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
+        ByteArrayReadLine readLine = new ByteArrayReadLine(in);
+        String line = readLine.next();
         while (line != null) {
             System.out.println(line);
-            line = readLine(in);
+            line = readLine.next();
         }
 
         System.out.println("--------- test 2 ----------");
 
         s = "line1\n\rline2\n\rline3\n\r\n\r";
         in = new ByteArrayInputStream(s.getBytes());
-        line = readLine(in);
+        readLine = new ByteArrayReadLine(in);
+        line = readLine.next();
         while (line != null) {
             System.out.println(line);
-            line = readLine(in);
+            line = readLine.next();
         }
 
     }
diff --git a/src/java/org/apache/commons/ssl/Version.java b/src/java/org/apache/commons/ssl/Version.java
index 0cb3d2e..b45246b 100644
--- a/src/java/org/apache/commons/ssl/Version.java
+++ b/src/java/org/apache/commons/ssl/Version.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/Version.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Version.java $
  * $Revision: 130 $
  * $Date: 2007-11-14 19:24:15 -0800 (Wed, 14 Nov 2007) $
  *
@@ -42,7 +42,7 @@ 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.9/src/java/org/apache/commons/ssl/Version.java $ property, and prints it
+ * Extracts tagged version from a subversion $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
@@ -54,7 +54,7 @@ import java.util.jar.JarFile;
  * @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.9/src/java/org/apache/commons/ssl/Version.java $";
+    public static final String HEAD_URL = "$HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Version.java $";
     public static final String VERSION;
     public static final String COMPILE_TIME;
 
diff --git a/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java b/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java
index 204bf3a..604b9ec 100644
--- a/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java
+++ b/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java
@@ -1,7 +1,7 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/X509CertificateChainBuilder.java $
- * $Revision: 121 $
- * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/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
@@ -35,6 +35,7 @@ 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;
@@ -131,37 +132,59 @@ public class X509CertificateChainBuilder {
             // gets added, then nodeAdded will be changed to "true".
             nodeAdded = false;
             X509Certificate top = (X509Certificate) path.getLast();
-            try {
-                top.verify(top.getPublicKey());
+            if (isSelfSigned(top)) {
                 // We're self-signed, so we're done!
                 break;
             }
-            catch (SignatureException se) {
-                // 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();
-                    try {
-                        top.verify(x509.getPublicKey());
-                        // No exception thrown, so we're signed by this guy!
-                        path.add(x509);
-                        nodeAdded = true;
-                        it.remove(); // Not interested in this guy anymore!
-                        break;
-                    }
-                    catch (SignatureException se2) {
-                        // Not signed by this guy, let's try the next guy.
-                    }
+
+            // 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]");
diff --git a/src/java/org/apache/commons/ssl/rmi/DateRMI.java b/src/java/org/apache/commons/ssl/rmi/DateRMI.java
index c76bc74..cbbfd24 100644
--- a/src/java/org/apache/commons/ssl/rmi/DateRMI.java
+++ b/src/java/org/apache/commons/ssl/rmi/DateRMI.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/rmi/DateRMI.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/rmi/DateRMI.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/rmi/IntegerRMI.java b/src/java/org/apache/commons/ssl/rmi/IntegerRMI.java
index de05f0d..b4690b3 100644
--- a/src/java/org/apache/commons/ssl/rmi/IntegerRMI.java
+++ b/src/java/org/apache/commons/ssl/rmi/IntegerRMI.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/rmi/IntegerRMI.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/rmi/IntegerRMI.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/rmi/RemoteDate.java b/src/java/org/apache/commons/ssl/rmi/RemoteDate.java
index 555c13e..cb17fb1 100644
--- a/src/java/org/apache/commons/ssl/rmi/RemoteDate.java
+++ b/src/java/org/apache/commons/ssl/rmi/RemoteDate.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/rmi/RemoteDate.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/rmi/RemoteDate.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/rmi/RemoteInteger.java b/src/java/org/apache/commons/ssl/rmi/RemoteInteger.java
index 6e70e1a..b558bb8 100644
--- a/src/java/org/apache/commons/ssl/rmi/RemoteInteger.java
+++ b/src/java/org/apache/commons/ssl/rmi/RemoteInteger.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/rmi/RemoteInteger.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/rmi/RemoteInteger.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/rmi/Test.java b/src/java/org/apache/commons/ssl/rmi/Test.java
index c2531d6..1286d89 100644
--- a/src/java/org/apache/commons/ssl/rmi/Test.java
+++ b/src/java/org/apache/commons/ssl/rmi/Test.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/rmi/Test.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/rmi/Test.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/util/ByteArrayReadLine.java b/src/java/org/apache/commons/ssl/util/ByteArrayReadLine.java
new file mode 100644
index 0000000..88d0a29
--- /dev/null
+++ b/src/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);
+        }
+    }
+
+}
diff --git a/src/java/org/apache/commons/ssl/util/Hex.java b/src/java/org/apache/commons/ssl/util/Hex.java
index 52a83fa..0f15927 100644
--- a/src/java/org/apache/commons/ssl/util/Hex.java
+++ b/src/java/org/apache/commons/ssl/util/Hex.java
@@ -1,5 +1,5 @@
 /*
- * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/src/java/org/apache/commons/ssl/util/Hex.java $
+ * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/util/Hex.java $
  * $Revision: 121 $
  * $Date: 2007-11-13 21:26:57 -0800 (Tue, 13 Nov 2007) $
  *
diff --git a/src/java/org/apache/commons/ssl/util/IPAddressParser.java b/src/java/org/apache/commons/ssl/util/IPAddressParser.java
new file mode 100644
index 0000000..b0da817
--- /dev/null
+++ b/src/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;
+    }
+}
diff --git a/src/java/org/apache/commons/ssl/util/ReadLine.java b/src/java/org/apache/commons/ssl/util/ReadLine.java
new file mode 100644
index 0000000..ee68016
--- /dev/null
+++ b/src/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;
+    }
+
+}
diff --git a/src/java/org/apache/commons/ssl/util/UTF8.java b/src/java/org/apache/commons/ssl/util/UTF8.java
new file mode 100644
index 0000000..8fa771a
--- /dev/null
+++ b/src/java/org/apache/commons/ssl/util/UTF8.java
@@ -0,0 +1,22 @@
+package org.apache.commons.ssl.util;
+
+import java.io.UnsupportedEncodingException;
+
+public class UTF8 {
+
+    public static String toString(byte[] bytes) {
+        try {
+            return new String(bytes, "UTF-8");
+        } catch (UnsupportedEncodingException uee) {
+            throw new RuntimeException("UTF8 unavailable", uee);
+        }
+    }
+
+    public static byte[] toBytes(String s) {
+        try {
+            return s.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException uee) {
+            throw new RuntimeException("UTF8 unavailable", uee);
+        }
+    }
+}
diff --git a/src/test/org/apache/commons/httpclient/contrib/ssl/TestHttpclientContrib.java b/src/test/org/apache/commons/httpclient/contrib/ssl/TestHttpclientContrib.java
new file mode 100644
index 0000000..572dae6
--- /dev/null
+++ b/src/test/org/apache/commons/httpclient/contrib/ssl/TestHttpclientContrib.java
@@ -0,0 +1,42 @@
+package org.apache.commons.httpclient.contrib.ssl;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+
+import java.io.File;
+import java.net.URL;
+
+public class TestHttpclientContrib {
+
+    @Test
+    public void theTest() throws Exception {
+        registerCerts();
+    }
+
+    public static void registerCerts() throws Exception {
+        File keyFile = new File("samples/keystores/Sun.jks.ks");
+        File trustFile = new File("samples/cacerts-with-78-entries.jks");
+        URL ks = keyFile.toURI().toURL();
+        URL ts = trustFile.toURI().toURL();
+
+        AuthSSLProtocolSocketFactory sf;
+        sf = new AuthSSLProtocolSocketFactory(ks, "changeit", ts, "changeit");
+        sf.setCheckHostname(false);
+
+        // There should be 78 certs in this trust-chain.
+        assertEquals(78, sf.getTrustChain().getCertificates().size());
+
+        TrustSSLProtocolSocketFactory tf;
+        tf = new TrustSSLProtocolSocketFactory(trustFile.getAbsolutePath(), "changeit".toCharArray());
+        tf.setCheckHostname(false);
+
+        String scheme1 = "https-test1";
+        Protocol.registerProtocol(scheme1, new Protocol(scheme1, (ProtocolSocketFactory) sf, 443));
+        String scheme2 = "https-test2";
+        Protocol.registerProtocol(scheme2, new Protocol(scheme2, (ProtocolSocketFactory) tf, 443));
+    }
+
+}
diff --git a/src/test/org/apache/commons/ssl/JUnitConfig.java b/src/test/org/apache/commons/ssl/JUnitConfig.java
new file mode 100644
index 0000000..2318737
--- /dev/null
+++ b/src/test/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;
+    }
+}
diff --git a/src/test/org/apache/commons/ssl/TestBase64.java b/src/test/org/apache/commons/ssl/TestBase64.java
new file mode 100644
index 0000000..4b29554
--- /dev/null
+++ b/src/test/org/apache/commons/ssl/TestBase64.java
@@ -0,0 +1,89 @@
+package org.apache.commons.ssl;
+
+import static org.junit.Assert.assertTrue;
+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);
+        }
+
+    }
+}
diff --git a/src/test/org/apache/commons/ssl/TestCertificates.java b/src/test/org/apache/commons/ssl/TestCertificates.java
new file mode 100644
index 0000000..cc90191
--- /dev/null
+++ b/src/test/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.
+ */
+ at 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 at bob.com");
+        X500Principal bad1 = new X500Principal("CN=\"abc,CN=foo.com,\",OU=ou,O=o,C=canada,EMAILADDRESS=bob at 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
diff --git a/src/test/org/apache/commons/ssl/TestIPAddressParser.java b/src/test/org/apache/commons/ssl/TestIPAddressParser.java
new file mode 100644
index 0000000..4c3cfa0
--- /dev/null
+++ b/src/test/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"));
+    }
+}
diff --git a/src/test/org/apache/commons/ssl/TestKeyMaterial.java b/src/test/org/apache/commons/ssl/TestKeyMaterial.java
new file mode 100644
index 0000000..01932ec
--- /dev/null
+++ b/src/test/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();
+    }
+
+}
diff --git a/src/test/org/apache/commons/ssl/TestOpenSSL.java b/src/test/org/apache/commons/ssl/TestOpenSSL.java
new file mode 100644
index 0000000..d44a260
--- /dev/null
+++ b/src/test/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;
+    }
+
+}
diff --git a/src/test/org/apache/commons/ssl/TestPKCS8Key.java b/src/test/org/apache/commons/ssl/TestPKCS8Key.java
new file mode 100644
index 0000000..31da307
--- /dev/null
+++ b/src/test/org/apache/commons/ssl/TestPKCS8Key.java
@@ -0,0 +1,54 @@
+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;
+            }
+
+            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);
+            }
+        }
+
+    }
+}
diff --git a/src/test/org/apache/commons/ssl/TestTrustMaterial.java b/src/test/org/apache/commons/ssl/TestTrustMaterial.java
new file mode 100644
index 0000000..32ee725
--- /dev/null
+++ b/src/test/org/apache/commons/ssl/TestTrustMaterial.java
@@ -0,0 +1,16 @@
+package org.apache.commons.ssl;
+
+import static org.apache.commons.ssl.JUnitConfig.TEST_HOME;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestTrustMaterial {
+
+    @Test
+    public void theTest() throws Exception {
+        // TrustMaterial in 0.3.13 couldn't load cacerts if it contained any private keys.
+        TrustMaterial tm = new TrustMaterial(TEST_HOME + "samples/cacerts-with-78-entries-and-one-private-key.jks");
+        Assert.assertEquals(78, tm.getCertificates().size());
+    }
+    
+}
diff --git a/version.txt b/version.txt
index 8db9de5..2cd590e 100644
--- a/version.txt
+++ b/version.txt
@@ -1,3 +1 @@
-$URL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.9/version.txt $
-$Date: 2007-11-13 21:36:51 -0800 (Tue, 13 Nov 2007) $
-$Revision: 123 $
+$URL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/version.txt $

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/not-yet-commons-ssl.git



More information about the pkg-java-commits mailing list