aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/main/jdk1.1/java/security/cert')
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRL.java20
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLException.java16
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLSelector.java39
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPath.java283
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilder.java243
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderException.java182
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderResult.java38
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderSpi.java50
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathParameters.java18
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidator.java250
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorException.java248
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorResult.java22
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorSpi.java59
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertSelector.java39
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStore.java352
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreException.java172
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreParameters.java52
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreSpi.java104
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertUtil.java556
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/Certificate.java80
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateEncodingException.java14
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateException.java16
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateExpiredException.java14
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactory.java183
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactorySpi.java111
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateNotYetValidException.java14
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateParsingException.java14
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CollectionCertStoreParameters.java117
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/LDAPCertStoreParameters.java130
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXBuilderParameters.java179
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathBuilderResult.java93
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathChecker.java155
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathValidatorResult.java136
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXParameters.java770
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyNode.java107
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyQualifierInfo.java196
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/TrustAnchor.java293
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRL.java77
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLEntry.java56
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLSelector.java717
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java2461
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Certificate.java33
-rw-r--r--libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Extension.java12
43 files changed, 8721 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRL.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRL.java
new file mode 100644
index 000000000..2eb219e07
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRL.java
@@ -0,0 +1,20 @@
+
+package java.security.cert;
+
+public abstract class CRL
+{
+ private String type;
+
+ protected CRL(String type)
+ {
+ this.type = type;
+ }
+
+ public final String getType()
+ {
+ return type;
+ }
+
+ public abstract boolean isRevoked(Certificate cert);
+ public abstract String toString();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLException.java
new file mode 100644
index 000000000..f079b8beb
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLException.java
@@ -0,0 +1,16 @@
+
+package java.security.cert;
+
+import java.security.GeneralSecurityException;
+
+public class CRLException extends GeneralSecurityException
+{
+ public CRLException()
+ {
+ }
+
+ public CRLException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLSelector.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLSelector.java
new file mode 100644
index 000000000..2e4ff616a
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CRLSelector.java
@@ -0,0 +1,39 @@
+package java.security.cert;
+
+/**
+ * A selector that defines a set of criteria for selecting <code>CRL</code>s.
+ * Classes that implement this interface are often used to specify
+ * which <code>CRL</code>s should be retrieved from a <code>CertStore</code>.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this interface are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CRL
+ * @see CertStore
+ * @see CertStore#getCRLs
+ **/
+public interface CRLSelector extends Cloneable
+{
+ /**
+ * Decides whether a <code>CRL</code> should be selected.
+ *
+ * @param crl the <code>CRL</code> to be checked
+ *
+ * @return <code>true</code> if the <code>CRL</code> should be selected,
+ * <code>false</code> otherwise
+ */
+ public boolean match(CRL crl);
+
+ /**
+ * Makes a copy of this <code>CRLSelector</code>. Changes to the
+ * copy will not affect the original and vice versa.
+ *
+ * @return a copy of this <code>CRLSelector</code>
+ */
+ public Object clone();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPath.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPath.java
new file mode 100644
index 000000000..ceb5cd189
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPath.java
@@ -0,0 +1,283 @@
+package java.security.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.NotSerializableException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * An immutable sequence of certificates (a certification path).<br />
+ * <br />
+ * This is an abstract class that defines the methods common to all
+ * CertPaths. Subclasses can handle different kinds of certificates
+ * (X.509, PGP, etc.).<br />
+ * <br />
+ * All CertPath objects have a type, a list of Certificates, and one
+ * or more supported encodings. Because the CertPath class is
+ * immutable, a CertPath cannot change in any externally visible way
+ * after being constructed. This stipulation applies to all public
+ * fields and methods of this class and any added or overridden by
+ * subclasses.<br />
+ * <br />
+ * The type is a String that identifies the type of Certificates in
+ * the certification path. For each certificate cert in a
+ * certification path certPath,
+ * cert.getType().equals(certPath.getType()) must be true.<br />
+ * <br />
+ * The list of Certificates is an ordered List of zero or more
+ * Certificates. This List and all of the Certificates contained in it
+ * must be immutable.<br />
+ * <br />
+ * Each CertPath object must support one or more encodings so that the
+ * object can be translated into a byte array for storage or
+ * transmission to other parties. Preferably, these encodings should
+ * be well-documented standards (such as PKCS#7). One of the encodings
+ * supported by a CertPath is considered the default encoding. This
+ * encoding is used if no encoding is explicitly requested (for the
+ * {@link #getEncoded()} method, for instance).<br />
+ * <br />
+ * All CertPath objects are also Serializable. CertPath objects are
+ * resolved into an alternate {@link CertPathRep} object during
+ * serialization. This allows a CertPath object to be serialized into
+ * an equivalent representation regardless of its underlying
+ * implementation.<br />
+ * <br />
+ * CertPath objects can be created with a CertificateFactory or they
+ * can be returned by other classes, such as a CertPathBuilder.<br />
+ * <br />
+ * By convention, X.509 CertPaths (consisting of X509Certificates),
+ * are ordered starting with the target certificate and ending with a
+ * certificate issued by the trust anchor. That is, the issuer of one
+ * certificate is the subject of the following one. The certificate
+ * representing the {@link TrustAnchor TrustAnchor} should not be included in the
+ * certification path. Unvalidated X.509 CertPaths may not follow
+ * these conventions. PKIX CertPathValidators will detect any
+ * departure from these conventions that cause the certification path
+ * to be invalid and throw a CertPathValidatorException.<br />
+ * <br />
+ * <strong>Concurrent Access</strong><br />
+ * <br />
+ * All CertPath objects must be thread-safe. That is, multiple threads
+ * may concurrently invoke the methods defined in this class on a
+ * single CertPath object (or more than one) with no ill effects. This
+ * is also true for the List returned by CertPath.getCertificates.<br />
+ * <br />
+ * Requiring CertPath objects to be immutable and thread-safe allows
+ * them to be passed around to various pieces of code without worrying
+ * about coordinating access. Providing this thread-safety is
+ * generally not difficult, since the CertPath and List objects in
+ * question are immutable.
+ *
+ * @see CertificateFactory
+ * @see CertPathBuilder
+ */
+public abstract class CertPath extends Object implements Serializable
+{
+ private String type;
+
+ /**
+ * Alternate <code>CertPath</code> class for serialization.
+ **/
+ protected static class CertPathRep
+ implements Serializable
+ {
+ private String type;
+ private byte[] data;
+
+ /**
+ * Creates a <code>CertPathRep</code> with the specified
+ * type and encoded form of a certification path.
+ *
+ * @param type the standard name of a CertPath
+ * @param typedata the encoded form of the certification
+ * path
+ **/
+ protected CertPathRep(String type, byte[] data)
+ {
+ this.type = type;
+ this.data = data;
+ }
+
+ /**
+ * Returns a CertPath constructed from the type and data.
+ *
+ * @return the resolved CertPath object
+ * @exception ObjectStreamException if a CertPath could not be constructed
+ **/
+ protected Object readResolve()
+ throws ObjectStreamException
+ {
+ try {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ CertificateFactory cf = CertificateFactory.getInstance(type);
+ return cf.generateCertPath(inStream);
+ } catch ( CertificateException ce ) {
+ throw new NotSerializableException(" java.security.cert.CertPath: " + type);
+ }
+ }
+ }
+
+ /**
+ * Creates a CertPath of the specified type.
+ * This constructor is protected because most users should use
+ * a CertificateFactory to create CertPaths.
+ * @param type the standard name of the type of Certificatesin this path
+ **/
+ protected CertPath(String type)
+ {
+ this.type = type;
+ }
+
+ /**
+ * Returns the type of Certificates in this certification
+ * path. This is the same string that would be returned by
+ * {@link Certificate#getType() cert.getType()} for all
+ * Certificates in the certification path.
+ *
+ * @return the type of Certificates in this certification path (never null)
+ **/
+ public String getType()
+ {
+ return type;
+ }
+
+ /**
+ * Returns an iteration of the encodings supported by this
+ * certification path, with the default encoding
+ * first. Attempts to modify the returned Iterator via its
+ * remove method result in an UnsupportedOperationException.
+ *
+ * @return an Iterator over the names of the supported encodings (as Strings)
+ **/
+ public abstract Iterator getEncodings();
+
+ /**
+ * Compares this certification path for equality with the
+ * specified object. Two CertPaths are equal if and only if
+ * their types are equal and their certificate Lists (and by
+ * implication the Certificates in those Lists) are equal. A
+ * CertPath is never equal to an object that is not a
+ * CertPath.<br />
+ * <br />
+ * This algorithm is implemented by this method. If it is
+ * overridden, the behavior specified here must be maintained.
+ *
+ * @param other the object to test for equality with this
+ * certification path
+ *
+ * @return true if the specified object is equal to this
+ * certification path, false otherwise
+ *
+ * @see Object#hashCode() Object.hashCode()
+ **/
+ public boolean equals(Object other)
+ {
+ if (!( other instanceof CertPath ) )
+ return false;
+
+ CertPath otherCertPath = (CertPath)other;
+ if ( ! getType().equals(otherCertPath.getType()) )
+ return false;
+ return getCertificates().equals(otherCertPath.getCertificates());
+ }
+
+ /**
+ * Returns the hashcode for this certification path. The hash
+ * code of a certification path is defined to be the result of
+ * the following calculation:
+ * <pre>
+ * hashCode = path.getType().hashCode();
+ * hashCode = 31 * hashCode + path.getCertificates().hashCode();
+ * </pre>
+ * This ensures that path1.equals(path2) implies that
+ * path1.hashCode()==path2.hashCode() for any two
+ * certification paths, path1 and path2, as required by the
+ * general contract of Object.hashCode.
+ *
+ * @return The hashcode value for this certification path
+ *
+ * @see #equals(Object)
+ **/
+ public int hashCode()
+ {
+ return getType().hashCode() * 31 + getCertificates().hashCode();
+ }
+
+ /**
+ * Returns a string representation of this certification
+ * path. This calls the toString method on each of the
+ * Certificates in the path.
+ *
+ * @return a string representation of this certification path
+ **/
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ List certs = getCertificates();
+ ListIterator iter = certs.listIterator();
+ s.append('\n').append(getType()).append(" Cert Path: length = ").append(certs.size()).append("\n[\n");
+ while ( iter.hasNext() ) {
+ s.append("=========================================================Certificate ").append(iter.nextIndex()).append('\n');
+ s.append(iter.next()).append('\n');
+ s.append("========================================================Certificate end\n\n\n");
+ }
+ s.append("\n]");
+ return s.toString();
+ }
+
+ /**
+ * Returns the encoded form of this certification path, using
+ * the default encoding.
+ *
+ * @return the encoded bytes
+ *
+ * @exception CertificateEncodingException if an encoding error occurs
+ **/
+ public abstract byte[] getEncoded()
+ throws CertificateEncodingException;
+
+ /**
+ * Returns the encoded form of this certification path, using
+ * the specified encoding.
+ *
+ * @param encoding the name of the encoding to use
+ *
+ * @return the encoded bytes
+ *
+ * @exception CertificateEncodingException if an encoding error
+ * occurs or the encoding requested is not supported
+ **/
+ public abstract byte[] getEncoded(String encoding)
+ throws CertificateEncodingException;
+
+ /**
+ * Returns the list of certificates in this certification
+ * path. The List returned must be immutable and thread-safe.
+ *
+ * @return an immutable List of Certificates (may be empty, but not null)
+ **/
+ public abstract List getCertificates();
+
+ /**
+ * Replaces the CertPath to be serialized with a CertPathRep
+ * object.
+ *
+ * @return the CertPathRep to be serialized
+ *
+ * @exception ObjectStreamException if a CertPathRep object
+ * representing this certification path could not be created
+ **/
+ protected Object writeReplace()
+ throws ObjectStreamException
+ {
+ try {
+ return new CertPathRep( getType(), getEncoded() );
+ } catch ( CertificateException ce ) {
+ throw new NotSerializableException( " java.security.cert.CertPath: " + getType() );
+ }
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilder.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilder.java
new file mode 100644
index 000000000..b3adbf15f
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilder.java
@@ -0,0 +1,243 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * A class for building certification paths (also known as certificate
+ * chains).<br />
+ * <br />
+ * This class uses a provider-based architecture, as described in the
+ * Java Cryptography Architecture. To create a
+ * <code>CertPathBuilder</code>, call one of the static
+ * <code>getInstance</code> methods, passing in the algorithm name of
+ * the CertPathBuilder desired and optionally the name of the provider
+ * desired.<br />
+ * <br />
+ * Once a <code>CertPathBuilder</code> object has been created,
+ * certification paths can be constructed by calling the
+ * {@link #build build} method and passing it an algorithm-specific set
+ * of parameters. If successful, the result (including the CertPath
+ * that was built) is returned in an object that implements the
+ * <code>CertPathBuilderResult</code> interface.<br />
+ * <br />
+ * <strong>Concurrent Access</strong><br />
+ * <br />
+ * The static methods of this class are guaranteed to be
+ * thread-safe. Multiple threads may concurrently invoke the static
+ * methods defined in this class with no ill effects.<br />
+ * <br />
+ * However, this is not true for the non-static methods defined by
+ * this class. Unless otherwise documented by a specific provider,
+ * threads that need to access a single <code>CertPathBuilder</code>
+ * instance concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating a
+ * different <code>CertPathBuilder</code> instance need not
+ * synchronize.<br />
+ * <br />
+ * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes.
+ *
+ * @see CertUtil
+ **/
+public class CertPathBuilder extends Object
+{
+ private CertPathBuilderSpi builderSpi;
+ private Provider provider;
+ private String algorithm;
+
+ /**
+ * Creates a CertPathBuilder object of the given algorithm, and
+ * encapsulates the given provider implementation (SPI object)
+ * in it.
+ *
+ * @param builderSpi the provider implementation
+ * @param provider the provider
+ * @param algorithm the algorithm name
+ **/
+ protected CertPathBuilder(CertPathBuilderSpi builderSpi,
+ Provider provider,
+ String algorithm)
+ {
+ this.builderSpi = builderSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * Returns a CertPathBuilder object that implements the
+ * specified algorithm.<br />
+ * <br />
+ * If the default provider package provides an implementation
+ * of the specified CertPathBuilder algorithm, an instance of
+ * CertPathBuilder containing that implementation is
+ * returned. If the requested algorithm is not available in
+ * the default package, other packages are searched.<br />
+ * <br />
+ * @param algorithm the name of the requested CertPathBuilder algorithm
+ *
+ * @return a CertPathBuilder object that implements the
+ * specified algorithm
+ *
+ * @exception NoSuchAlgorithmException if the requested
+ * algorithm is not available in the default provider package
+ * or any of the other provider packages that were searched
+ **/
+ public static CertPathBuilder getInstance(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ try {
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation("CertPathBuilder", algorithm, (String)null);
+ if (imp != null)
+ {
+ return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(),
+ imp.getProvider(), algorithm);
+ }
+ } catch ( NoSuchProviderException ex ) {}
+ throw new NoSuchAlgorithmException("can't find type " + algorithm);
+ }
+
+ /**
+ * Returns a CertPathBuilder object that implements the
+ * specified algorithm, as supplied by the specified provider.
+ *
+ * @param algorithm the name of the requested CertPathBuilder
+ * algorithm
+ * @param provider the name of the provider
+ *
+ * @return a CertPathBuilder object that implements the
+ * specified algorithm, as supplied by the specified provider
+ *
+ * @exception NoSuchAlgorithmException if the requested algorithm
+ * is not available from the specified provider
+ * @exception NoSuchProviderException if the provider has not
+ * been configured
+ * @exception IllegalArgumentException if the provider is null
+ **/
+ public static CertPathBuilder getInstance(String algorithm,
+ String provider)
+ throws NoSuchAlgorithmException,
+ NoSuchProviderException
+ {
+ if ( provider == null )
+ throw new IllegalArgumentException("provider must be non-null");
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation("CertPathBuilder", algorithm, provider);
+
+ if (imp != null)
+ {
+ return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(),
+ imp.getProvider(), algorithm);
+ }
+ throw new NoSuchAlgorithmException("can't find type " + algorithm);
+ }
+
+ /**
+ * Returns a CertPathBuilder object that implements the
+ * specified algorithm, as supplied by the specified
+ * provider. Note: the provider doesn't have to be registered.
+ *
+ * @param algorithm the name of the requested CertPathBuilder
+ * algorithm
+ * @param provider the provider
+ * @return a CertPathBuilder object that implements the
+ * specified algorithm, as supplied by the specified provider
+ *
+ * @exception NoSuchAlgorithmException if the requested algorithm
+ * is not available from the specified provider
+ * @exception IllegalArgumentException if the provider is null.
+ **/
+ public static CertPathBuilder getInstance(String algorithm,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if ( provider == null )
+ throw new IllegalArgumentException("provider must be non-null");
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation("CertPathBuilder", algorithm, provider);
+
+ if (imp != null)
+ {
+ return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(),
+ provider, algorithm);
+ }
+ throw new NoSuchAlgorithmException("can't find type " + algorithm);
+ }
+
+ /**
+ * Returns the provider of this <code>CertPathBuilder</code>.
+ *
+ * @return the provider of this <code>CertPathBuilder</code>
+ **/
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the name of the algorithm of this
+ * <code>CertPathBuilder</code>.
+ *
+ * @return the name of the algorithm of this <code>CertPathBuilder</code>
+ **/
+ public final String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Attempts to build a certification path using the specified algorithm
+ * parameter set.
+ *
+ * @param params the algorithm parameters
+ *
+ * @return the result of the build algorithm
+ *
+ * @exception CertPathBuilderException if the builder is unable to construct
+ * a certification path that satisfies the specified parameters
+ * @exception InvalidAlgorithmParameterException if the specified parameters * are inappropriate for this <code>CertPathBuilder</code>
+ */
+ public final CertPathBuilderResult build(CertPathParameters params)
+ throws CertPathBuilderException,
+ InvalidAlgorithmParameterException
+ {
+ return builderSpi.engineBuild(params);
+ }
+
+
+ /**
+ * Returns the default <code>CertPathBuilder</code> type as specified in
+ * the Java security properties file, or the string &quot;PKIX&quot;
+ * if no such property exists. The Java security properties file is
+ * located in the file named &lt;JAVA_HOME&gt;/lib/security/java.security,
+ * where &lt;JAVA_HOME&gt; refers to the directory where the SDK was
+ * installed.<br />
+ * <br />
+ * The default <code>CertPathBuilder</code> type can be used by
+ * applications that do not want to use a hard-coded type when calling one
+ * of the <code>getInstance</code> methods, and want to provide a default
+ * type in case a user does not specify its own.<br />
+ * <br />
+ * The default <code>CertPathBuilder</code> type can be changed by
+ * setting the value of the "certpathbuilder.type" security property
+ * (in the Java security properties file) to the desired type.
+ *
+ * @return the default <code>CertPathBuilder</code> type as specified
+ * in the Java security properties file, or the string &quot;PKIX&quot;
+ * if no such property exists.
+ */
+ public static final String getDefaultType()
+ {
+ String defaulttype = null;
+ defaulttype = Security.getProperty("certpathbuilder.type");
+
+ if ( defaulttype == null || defaulttype.length() <= 0 )
+ return "PKIX";
+ else
+ return defaulttype;
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderException.java
new file mode 100644
index 000000000..13b60891e
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderException.java
@@ -0,0 +1,182 @@
+package java.security.cert;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.security.GeneralSecurityException;
+
+/**
+ * An exception indicating one of a variety of problems encountered
+ * when building a certification path with a
+ * <code>CertPathBuilder</code>.<br />
+ * <br />
+ * A <code>CertPathBuilderException</code> provides support for
+ * wrapping exceptions. The {@link #getCause() getCause} method
+ * returns the throwable, if any, that caused this exception to be
+ * thrown.<br />
+ * <br />
+ * <strong>Concurrent Access</strong><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are
+ * not thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilder
+ **/
+public class CertPathBuilderException extends GeneralSecurityException
+{
+ private Throwable cause;
+
+ /**
+ * Creates a <code>CertPathBuilderException</code> with <code>null</code>
+ * as its detail message.
+ */
+ public CertPathBuilderException()
+ {
+ }
+
+ /**
+ * Creates a <code>CertPathBuilderException</code> with the given detail
+ * message. The detail message is a <code>String</code> that describes
+ * this particular exception in more detail.
+ *
+ * @param msg
+ * the detail message
+ */
+ public CertPathBuilderException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Creates a <code>CertPathBuilderException</code> that wraps the
+ * specified throwable. This allows any exception to be converted into a
+ * <code>CertPathBuilderException</code>, while retaining information
+ * about the wrapped exception, which may be useful for debugging. The
+ * detail message is set to
+ * <code>(cause==null ? null : cause.toString())</code> (which typically
+ * contains the class and detail message of cause).
+ *
+ * @param cause
+ * the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is permitted, and
+ * indicates that the cause is nonexistent or unknown.)
+ */
+ public CertPathBuilderException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Creates a <code>CertPathBuilderException</code> with the specified
+ * detail message and cause.
+ *
+ * @param msg
+ * the detail message
+ * @param cause
+ * the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A null value is permitted, and
+ * indicates that the cause is nonexistent or unknown.)
+ */
+ public CertPathBuilderException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ /**
+ * Returns the internal (wrapped) cause, or null if the cause is nonexistent
+ * or unknown.
+ *
+ * @return the cause of this throwable or <code>null</code> if the cause
+ * is nonexistent or unknown.
+ */
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+ /**
+ * Returns the detail message for this CertPathBuilderException.
+ *
+ * @return the detail message, or <code>null</code> if neither the message
+ * nor internal cause were specified
+ */
+ public String getMessage()
+ {
+ String message = super.getMessage();
+
+ if (message == null && cause == null)
+ {
+ return null;
+ }
+
+ if (cause != null)
+ {
+ return cause.getMessage();
+ }
+
+ return message;
+ }
+
+ /**
+ * Returns a string describing this exception, including a description of
+ * the internal (wrapped) cause if there is one.
+ *
+ * @return a string representation of this
+ * <code>CertPathBuilderException</code>
+ */
+ public String toString()
+ {
+ String message = getMessage();
+ if (message == null)
+ {
+ return "";
+ }
+
+ return message;
+ }
+
+ /**
+ * Prints a stack trace to <code>System.err</code>, including the
+ * backtrace of the cause, if any.
+ */
+ public void printStackTrace()
+ {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Prints a stack trace to a <code>PrintStream</code>, including the
+ * backtrace of the cause, if any.
+ *
+ * @param ps
+ * the <code>PrintStream</code> to use for output
+ */
+ public void printStackTrace(PrintStream ps)
+ {
+ super.printStackTrace(ps);
+ if (getCause() != null)
+ {
+ getCause().printStackTrace(ps);
+ }
+ }
+
+ /**
+ * Prints a stack trace to a <code>PrintWriter</code>, including the
+ * backtrace of the cause, if any.
+ *
+ * @param ps
+ * the <code>PrintWriter</code> to use for output
+ */
+ public void printStackTrace(PrintWriter pw)
+ {
+ super.printStackTrace(pw);
+ if (getCause() != null)
+ {
+ getCause().printStackTrace(pw);
+ }
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderResult.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderResult.java
new file mode 100644
index 000000000..c0482bc4e
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderResult.java
@@ -0,0 +1,38 @@
+package java.security.cert;
+
+/**
+ * A specification of the result of a certification path builder algorithm.
+ * All results returned by the {@link CertPathBuilder#build CertPathBuilder.build} method
+ * must implement this interface.<br />
+ * <br />
+ * At a minimum, a CertPathBuilderResult contains the CertPath built by the
+ * CertPathBuilder instance. Implementations of this interface may add methods
+ * to return implementation or algorithm specific information, such as
+ * debugging information or certification path validation results.<br />
+ * <br />
+ * <strong>Concurrent Access</strong><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this interface are not
+ * thread-safe. Multiple threads that need to access a single object
+ * concurrently should synchronize amongst themselves and provide the
+ * necessary locking. Multiple threads each manipulating separate objects
+ * need not synchronize.
+ **/
+public interface CertPathBuilderResult extends Cloneable
+{
+ /**
+ * Returns the built certification path.
+ *
+ * @return the certification path (never <code>null</code>)
+ */
+ public CertPath getCertPath();
+
+ /**
+ * Makes a copy of this <code>CertPathBuilderResult</code>.
+ * Changes to the copy will not affect the original and vice
+ * versa.
+ *
+ * @return a copy of this CertPathBuilderResult
+ */
+ public Object clone();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderSpi.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderSpi.java
new file mode 100644
index 000000000..be044fa30
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathBuilderSpi.java
@@ -0,0 +1,50 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+
+/**
+ * The Service Provider Interface (SPI) for the CertPathBuilder
+ * class. All CertPathBuilder implementations must include a class
+ * (the SPI class) that extends this class (CertPathBuilderSpi) and
+ * implements all of its methods. In general, instances of this class
+ * should only be accessed through the CertPathBuilder class. For
+ * details, see the Java Cryptography Architecture.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Instances of this class need not be protected against concurrent
+ * access from multiple threads. Threads that need to access a single
+ * CertPathBuilderSpi instance concurrently should synchronize amongst
+ * themselves and provide the necessary locking before calling the
+ * wrapping CertPathBuilder object.<br />
+ * <br />
+ * However, implementations of CertPathBuilderSpi may still encounter
+ * concurrency issues, since multiple threads each manipulating a
+ * different CertPathBuilderSpi instance need not synchronize.
+ **/
+public abstract class CertPathBuilderSpi
+ extends Object
+{
+ /**
+ * The default constructor.
+ */
+ public CertPathBuilderSpi() {}
+
+ /**
+ * Attempts to build a certification path using the specified
+ * algorithm parameter set.
+ *
+ * @param params the algorithm parameters
+ *
+ * @return the result of the build algorithm
+ *
+ * @exception CertPathBuilderException if the builder is unable
+ * to construct a certification path that satisfies the
+ * specified
+ * @exception parametersInvalidAlgorithmParameterException if the
+ * specified parameters are inappropriate for this CertPathBuilder
+ */
+ public abstract CertPathBuilderResult engineBuild( CertPathParameters params )
+ throws CertPathBuilderException,
+ InvalidAlgorithmParameterException;
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathParameters.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathParameters.java
new file mode 100644
index 000000000..caff291a8
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathParameters.java
@@ -0,0 +1,18 @@
+package java.security.cert;
+
+/**
+ * A specification of certification path algorithm parameters. The purpose
+ * of this interface is to group (and provide type safety for) all CertPath
+ * parameter specifications. All <code>CertPath</code> parameter specifications must
+ * implement this interface.
+ **/
+public interface CertPathParameters extends Cloneable
+{
+ /**
+ * Makes a copy of this <code>CertPathParameters</code>. Changes to the
+ * copy will not affect the original and vice versa.
+ *
+ * @return a copy of this <code>CertPathParameters</code>
+ **/
+ public Object clone();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidator.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidator.java
new file mode 100644
index 000000000..aaddbf0e5
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidator.java
@@ -0,0 +1,250 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * A class for validating certification paths (also known as certificate
+ * chains).<br />
+ * <br />
+ * This class uses a provider-based architecture, as described in the Java
+ * Cryptography Architecture. To create a <code>CertPathValidator</code>,
+ * call one of the static <code>getInstance</code> methods, passing in the
+ * algorithm name of the <code>CertPathValidator</code> desired and
+ * optionally the name of the provider desired. <br />
+ * <br />
+ * Once a <code>CertPathValidator</code> object has been created, it can
+ * be used to validate certification paths by calling the {@link #validate
+ * validate} method and passing it the <code>CertPath</code> to be validated
+ * and an algorithm-specific set of parameters. If successful, the result is
+ * returned in an object that implements the
+ * <code>CertPathValidatorResult</code> interface.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * The static methods of this class are guaranteed to be thread-safe.
+ * Multiple threads may concurrently invoke the static methods defined in
+ * this class with no ill effects.<br />
+ * <br />
+ * However, this is not true for the non-static methods defined by this class.
+ * Unless otherwise documented by a specific provider, threads that need to
+ * access a single <code>CertPathValidator</code> instance concurrently should
+ * synchronize amongst themselves and provide the necessary locking. Multiple
+ * threads each manipulating a different <code>CertPathValidator</code>
+ * instance need not synchronize.<br />
+ * <br />
+ * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes.
+ *
+ * @see CertPath
+ * @see CertUtil
+ **/
+public class CertPathValidator extends Object
+{
+ private CertPathValidatorSpi validatorSpi;
+ private Provider provider;
+ private String algorithm;
+
+ /**
+ * Creates a <code>CertPathValidator</code> object of the given algorithm,
+ * and encapsulates the given provider implementation (SPI object) in it.
+ *
+ * @param validatorSpi the provider implementation
+ * @param provider the provider
+ * @param algorithm the algorithm name
+ */
+ protected CertPathValidator( CertPathValidatorSpi validatorSpi,
+ Provider provider,
+ String algorithm)
+ {
+ this.validatorSpi = validatorSpi;
+ this.provider = provider;
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * Returns a <code>CertPathValidator</code> object that implements the
+ * specified algorithm.<br />
+ * <br />
+ * If the default provider package provides an implementation of the
+ * specified <code>CertPathValidator</code> algorithm, an instance of
+ * <code>CertPathValidator</code> containing that implementation is
+ * returned. If the requested algorithm is not available in the default
+ * package, other packages are searched.
+ *
+ * @param algorithm the name of the requested <code>CertPathValidator</code>
+ * algorithm
+ *
+ * @return a <code>CertPathValidator</code> object that implements the
+ * specified algorithm
+ *
+ * @exception NoSuchAlgorithmException if the requested algorithm
+ * is not available in the default provider package or any of the other
+ * provider packages that were searched
+ */
+ public static CertPathValidator getInstance(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ try {
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation("CertPathValidator", algorithm, (String)null );
+ if (imp != null)
+ {
+ return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), imp.getProvider(), algorithm);
+ }
+ } catch (NoSuchProviderException ex ) {}
+ throw new NoSuchAlgorithmException("can't find algorithm " + algorithm);
+ }
+
+ /**
+ * Returns a <code>CertPathValidator</code> object that implements the
+ * specified algorithm, as supplied by the specified provider.
+ *
+ * @param algorithm the name of the requested <code>CertPathValidator</code>
+ * algorithm
+ * @param provider the name of the provider
+ *
+ * @return a <code>CertPathValidator</code> object that implements the
+ * specified algorithm, as supplied by the specified provider
+ *
+ * @exception NoSuchAlgorithmException if the requested algorithm
+ * is not available from the specified provider
+ * @exception NoSuchProviderException if the provider has not been
+ * configured
+ * @exception IllegalArgumentException if the <code>provider</code> is
+ * null
+ */
+ public static CertPathValidator getInstance(String algorithm,
+ String provider)
+ throws NoSuchAlgorithmException,
+ NoSuchProviderException
+ {
+ if ( provider == null )
+ throw new IllegalArgumentException("provider must be non-null");
+
+ CertUtil.Implementation imp = CertUtil.getImplementation("CertPathValidator", algorithm, provider );
+ if (imp != null)
+ {
+ return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), imp.getProvider(), algorithm);
+ }
+ throw new NoSuchAlgorithmException("can't find algorithm " + algorithm);
+ }
+
+ /**
+ * Returns a <code>CertPathValidator</code> object that implements the
+ * specified algorithm, as supplied by the specified provider.
+ * Note: the <code>provider</code> doesn't have to be registered.
+ *
+ * @param algorithm the name of the requested
+ * <code>CertPathValidator</code> algorithm
+ * @param provider the provider
+ *
+ * @return a <code>CertPathValidator</code> object that implements the
+ * specified algorithm, as supplied by the specified provider
+ *
+ * @exception NoSuchAlgorithmException if the requested algorithm
+ * is not available from the specified provider
+ * @exception IllegalArgumentException if the <code>provider</code> is
+ * null
+ */
+ public static CertPathValidator getInstance(String algorithm,
+ Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ if ( provider == null )
+ throw new IllegalArgumentException("provider must be non-null");
+
+ CertUtil.Implementation imp = CertUtil.getImplementation("CertPathValidator", algorithm, provider );
+ if (imp != null)
+ {
+ return new CertPathValidator((CertPathValidatorSpi)imp.getEngine(), provider, algorithm);
+ }
+ throw new NoSuchAlgorithmException("can't find algorithm " + algorithm);
+ }
+
+ /**
+ * Returns the <code>Provider</code> of this
+ * <code>CertPathValidator</code>.
+ *
+ * @return the <code>Provider</code> of this <code>CertPathValidator</code>
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the algorithm name of this <code>CertPathValidator</code>.
+ *
+ * @return the algorithm name of this <code>CertPathValidator</code>
+ */
+ public final String getAlgorithm()
+ {
+ return algorithm;
+ }
+
+ /**
+ * Validates the specified certification path using the specified
+ * algorithm parameter set.<br />
+ * <br />
+ * The <code>CertPath</code> specified must be of a type that is
+ * supported by the validation algorithm, otherwise an
+ * <code>InvalidAlgorithmParameterException</code> will be thrown. For
+ * example, a <code>CertPathValidator</code> that implements the PKIX
+ * algorithm validates <code>CertPath</code> objects of type X.509.
+ *
+ * @param certPath the <code>CertPath</code> to be validated
+ * @param params the algorithm parameters
+ *
+ * @return the result of the validation algorithm
+ *
+ * @exception CertPathValidatorException if the <code>CertPath</code>
+ * does not validate
+ * @exception InvalidAlgorithmParameterException if the specified
+ * parameters or the type of the specified <code>CertPath</code> are
+ * inappropriate for this <code>CertPathValidator</code>
+ */
+ public final CertPathValidatorResult validate( CertPath certPath,
+ CertPathParameters params)
+ throws CertPathValidatorException,
+ InvalidAlgorithmParameterException
+ {
+ return validatorSpi.engineValidate( certPath, params );
+ }
+
+
+ /**
+ * Returns the default <code>CertPathValidator</code> type as specified in
+ * the Java security properties file, or the string &quot;PKIX&quot;
+ * if no such property exists. The Java security properties file is
+ * located in the file named &lt;JAVA_HOME&gt;/lib/security/java.security,
+ * where &lt;JAVA_HOME&gt; refers to the directory where the SDK was
+ * installed.<br />
+ * <br />
+ * The default <code>CertPathValidator</code> type can be used by
+ * applications that do not want to use a hard-coded type when calling one
+ * of the <code>getInstance</code> methods, and want to provide a default
+ * type in case a user does not specify its own.<br />
+ * <br />
+ * The default <code>CertPathValidator</code> type can be changed by
+ * setting the value of the "certpathvalidator.type" security property
+ * (in the Java security properties file) to the desired type.
+ *
+ * @return the default <code>CertPathValidator</code> type as specified
+ * in the Java security properties file, or the string &quot;PKIX&quot;
+ * if no such property exists.
+ */
+ public static final String getDefaultType()
+ {
+ String defaulttype = null;
+ defaulttype = Security.getProperty("certpathvalidator.type");
+
+ if ( defaulttype == null || defaulttype.length() <= 0 )
+ return "PKIX";
+ else
+ return defaulttype;
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorException.java
new file mode 100644
index 000000000..2088ab1a4
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorException.java
@@ -0,0 +1,248 @@
+package java.security.cert;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.security.GeneralSecurityException;
+
+/**
+ * An exception indicating one of a variety of problems encountered when
+ * validating a certification path. <br />
+ * <br />
+ * A <code>CertPathValidatorException</code> provides support for wrapping
+ * exceptions. The {@link #getCause getCause} method returns the throwable,
+ * if any, that caused this exception to be thrown. <br />
+ * <br />
+ * A <code>CertPathValidatorException</code> may also include the
+ * certification path that was being validated when the exception was thrown
+ * and the index of the certificate in the certification path that caused the
+ * exception to be thrown. Use the {@link #getCertPath getCertPath} and
+ * {@link #getIndex getIndex} methods to retrieve this information.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathValidator
+ **/
+public class CertPathValidatorException extends GeneralSecurityException
+{
+ private Throwable cause;
+ private CertPath certPath;
+ private int index = -1;
+
+ /**
+ * Creates a <code>CertPathValidatorException</code> with
+ * no detail message.
+ */
+ public CertPathValidatorException()
+ {
+ super();
+ }
+
+ /**
+ * Creates a <code>CertPathValidatorException</code> with the given
+ * detail message. A detail message is a <code>String</code> that
+ * describes this particular exception.
+ *
+ * @param messag the detail message
+ */
+ public CertPathValidatorException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Creates a <code>CertPathValidatorException</code> with the specified
+ * detail message and cause.
+ *
+ * @param msg the detail message
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause getCause()} method). (A <code>null</code> value is
+ * permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public CertPathValidatorException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Creates a <code>CertPathValidatorException</code> with the specified
+ * detail message, cause, certification path, and index.
+ *
+ * @param msg the detail message (or <code>null</code> if none)
+ * @param cause the cause (or <code>null</code> if none)
+ * @param certPath the certification path that was in the process of
+ * being validated when the error was encountered
+ * @param index the index of the certificate in the certification path
+ * that caused the error (or -1 if not applicable). Note that
+ * the list of certificates in a <code>CertPath</code> is zero based.
+ *
+ * @exception IndexOutOfBoundsException if the index is out of range
+ * <code>(index < -1 || (certPath != null && index >=
+ * certPath.getCertificates().size())</code>
+ * @exception IllegalArgumentException if <code>certPath</code> is
+ * <code>null</code> and <code>index</code> is not -1
+ */
+ public CertPathValidatorException(String message, Throwable cause, CertPath certPath, int index)
+ {
+ super( message );
+
+ if ( certPath == null && index != -1 )
+ throw new IllegalArgumentException( "certPath = null and index != -1" );
+ if ( index < -1 || ( certPath != null && index >= certPath.getCertificates().size() ) )
+ throw new IndexOutOfBoundsException( " index < -1 or out of bound of certPath.getCertificates()" );
+
+ this.cause = cause;
+ this.certPath = certPath;
+ this.index = index;
+ }
+
+ /**
+ * Creates a <code>CertPathValidatorException</code> that wraps the
+ * specified throwable. This allows any exception to be converted into a
+ * <code>CertPathValidatorException</code>, while retaining information
+ * about the wrapped exception, which may be useful for debugging. The
+ * detail message is set to (<code>cause==null ? null : cause.toString()
+ * </code>) (which typically contains the class and detail message of
+ * cause).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause getCause()} method). (A <code>null</code> value is
+ * permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public CertPathValidatorException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ /**
+ * Returns the detail message for this
+ * <code>CertPathValidatorException</code>.
+ *
+ * @return the detail message, or <code>null</code> if neither the message
+ * nor cause were specified
+ */
+ public String getMessage()
+ {
+ String message = super.getMessage();
+
+ if ( message == null && cause == null )
+ return null;
+
+ StringBuffer s = new StringBuffer();
+ if ( message != null )
+ {
+ s.append(message).append('\n');
+ }
+ if ( cause != null )
+ {
+ s.append("Cause:\n").append(cause.getMessage()).append('\n');
+ }
+ return s.toString();
+ }
+
+ /**
+ * Returns the certification path that was being validated when
+ * the exception was thrown.
+ *
+ * @return the <code>CertPath</code> that was being validated when
+ * the exception was thrown (or <code>null</code> if not specified)
+ */
+ public CertPath getCertPath()
+ {
+ return certPath;
+ }
+
+ /**
+ * Returns the index of the certificate in the certification path
+ * that caused the exception to be thrown. Note that the list of
+ * certificates in a <code>CertPath</code> is zero based. If no
+ * index has been set, -1 is returned.
+ *
+ * @return the index that has been set, or -1 if none has been set
+ */
+ public int getIndex()
+ {
+ return index;
+ }
+
+ /**
+ * Returns the cause of this <code>CertPathValidatorException</code> or
+ * <code>null</code> if the cause is nonexistent or unknown.
+ *
+ * @return the cause of this throwable or <code>null</code> if the cause
+ * is nonexistent or unknown.
+ */
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+ /**
+ * Returns a string describing this exception, including a description
+ * of the internal (wrapped) cause if there is one.
+ *
+ * @return a string representation of this
+ * <code>CertPathValidatorException</code>
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ String s = getMessage();
+ if ( s != null )
+ {
+ sb.append( s );
+ }
+ if ( getIndex() >= 0 )
+ {
+ sb.append("index in certpath: ").append(getIndex()).append('\n');
+ sb.append(getCertPath());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Prints a stack trace to <code>System.err</code>, including the backtrace
+ * of the cause, if any.
+ */
+ public void printStackTrace()
+ {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Prints a stack trace to a <code>PrintStream</code>, including the
+ * backtrace of the cause, if any.
+ *
+ * @param ps the <code>PrintStream</code> to use for output
+ */
+ public void printStackTrace(PrintStream ps)
+ {
+ super.printStackTrace(ps);
+ if ( getCause() != null )
+ {
+ getCause().printStackTrace(ps);
+ }
+ }
+
+ /**
+ * Prints a stack trace to a <code>PrintWriter</code>, including the
+ * backtrace of the cause, if any.
+ *
+ * @param pw the <code>PrintWriter</code> to use for output
+ */
+ public void printStackTrace(PrintWriter pw)
+ {
+ super.printStackTrace(pw);
+ if ( getCause() != null )
+ {
+ getCause().printStackTrace(pw);
+ }
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorResult.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorResult.java
new file mode 100644
index 000000000..ec09641d5
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorResult.java
@@ -0,0 +1,22 @@
+package java.security.cert;
+
+/**
+ * A specification of the result of a certification path validator algorithm.<br />
+ * <br />
+ * The purpose of this interface is to group (and provide type safety
+ * for) all certification path validator results. All results returned
+ * by the {@link CertPathValidator#validate CertPathValidator.validate}
+ * method must implement this interface.
+ *
+ * @see CertPathValidator
+ **/
+public interface CertPathValidatorResult extends Cloneable
+{
+ /**
+ * Makes a copy of this <code>CertPathValidatorResult</code>. Changes to the
+ * copy will not affect the original and vice versa.
+ *
+ * @return a copy of this <code>CertPathValidatorResult</code>
+ */
+ public Object clone();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorSpi.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorSpi.java
new file mode 100644
index 000000000..c70bc47fc
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertPathValidatorSpi.java
@@ -0,0 +1,59 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+
+/**
+ *
+ * The <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@link CertPathValidator CertPathValidator} class. All
+ * <code>CertPathValidator</code> implementations must include a class (the
+ * SPI class) that extends this class (<code>CertPathValidatorSpi</code>)
+ * and implements all of its methods. In general, instances of this class
+ * should only be accessed through the <code>CertPathValidator</code> class.
+ * For details, see the Java Cryptography Architecture.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Instances of this class need not be protected against concurrent
+ * access from multiple threads. Threads that need to access a single
+ * <code>CertPathValidatorSpi</code> instance concurrently should synchronize
+ * amongst themselves and provide the necessary locking before calling the
+ * wrapping <code>CertPathValidator</code> object.<br />
+ * <br />
+ * However, implementations of <code>CertPathValidatorSpi</code> may still
+ * encounter concurrency issues, since multiple threads each
+ * manipulating a different <code>CertPathValidatorSpi</code> instance need not
+ * synchronize.
+ **/
+public abstract class CertPathValidatorSpi extends Object
+{
+ /**
+ * The default constructor.
+ */
+ public CertPathValidatorSpi() {}
+
+ /**
+ * Validates the specified certification path using the specified
+ * algorithm parameter set.<br />
+ * <br />
+ * The <code>CertPath</code> specified must be of a type that is
+ * supported by the validation algorithm, otherwise an
+ * <code>InvalidAlgorithmParameterException</code> will be thrown. For
+ * example, a <code>CertPathValidator</code> that implements the PKIX
+ * algorithm validates <code>CertPath</code> objects of type X.509.
+ *
+ * @param certPath the <code>CertPath</code> to be validated
+ * @param params the algorithm parameters
+ *
+ * @return the result of the validation algorithm
+ *
+ * @exception CertPathValidatorException if the <code>CertPath</code>
+ * does not validate
+ * @exception InvalidAlgorithmParameterException if the specified
+ * parameters or the type of the specified <code>CertPath</code> are
+ * inappropriate for this <code>CertPathValidator</code>
+ */
+ public abstract CertPathValidatorResult engineValidate(CertPath certPath, CertPathParameters params)
+ throws CertPathValidatorException,
+ InvalidAlgorithmParameterException;
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertSelector.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertSelector.java
new file mode 100644
index 000000000..31bf97448
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertSelector.java
@@ -0,0 +1,39 @@
+package java.security.cert;
+
+/**
+ * A selector that defines a set of criteria for selecting
+ * <code>Certificate</code>s. Classes that implement this interface
+ * are often used to specify which <code>Certificate</code>s should
+ * be retrieved from a <code>CertStore</code>.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this interface are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see Certificate
+ * @see CertStore
+ * @see CertStore#getCertificates
+ */
+public interface CertSelector extends Cloneable
+{
+ /**
+ * Decides whether a <code>Certificate</code> should be selected.
+ *
+ * @param cert the <code>Certificate</code> to be checked
+ * @return <code>true</code> if the <code>Certificate</code>
+ * should be selected, <code>false</code> otherwise
+ */
+ public boolean match(Certificate cert);
+
+ /**
+ * Makes a copy of this <code>CertSelector</code>. Changes to the
+ * copy will not affect the original and vice versa.
+ *
+ * @return a copy of this <code>CertSelector</code>
+ */
+ public Object clone();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStore.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStore.java
new file mode 100644
index 000000000..0e2c6d2f7
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStore.java
@@ -0,0 +1,352 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Collection;
+
+/**
+ * A class for retrieving <code>Certificate</code>s and <code>CRL</code>s
+ * from a repository.<br />
+ * <br />
+ * This class uses a provider-based architecture, as described in the
+ * Java Cryptography Architecture.
+ * To create a <code>CertStore</code>, call one of the static
+ * <code>getInstance</code> methods, passing in the type of
+ * <code>CertStore</code> desired, any applicable initialization parameters
+ * and optionally the name of the provider desired. <br />
+ * <br />
+ * Once the <code>CertStore</code> has been created, it can be used to
+ * retrieve <code>Certificate</code>s and <code>CRL</code>s by calling its
+ * {@link #getCertificates(CertSelector selector) getCertificates} and
+ * {@link #getCRLs(CRLSelector selector) getCRLs} methods.<br />
+ * <br />
+ * Unlike a {@link java.security.KeyStore KeyStore}, which provides access
+ * to a cache of private keys and trusted certificates, a
+ * <code>CertStore</code> is designed to provide access to a potentially
+ * vast repository of untrusted certificates and CRLs. For example, an LDAP
+ * implementation of <code>CertStore</code> provides access to certificates
+ * and CRLs stored in one or more directories using the LDAP protocol and the
+ * schema as defined in the RFC service attribute. See Appendix A in the
+ * Java Certification Path API Programmer's Guide for more information about
+ * standard <code>CertStore</code> types.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * All public methods of <code>CertStore</code> objects must be thread-safe.
+ * That is, multiple threads may concurrently invoke these methods on a
+ * single <code>CertStore</code> object (or more than one) with no
+ * ill effects. This allows a <code>CertPathBuilder</code> to search for a
+ * CRL while simultaneously searching for further certificates, for instance.<br />
+ * <br />
+ * The static methods of this class are also guaranteed to be thread-safe.
+ * Multiple threads may concurrently invoke the static methods defined in
+ * this class with no ill effects.<br />
+ * <br />
+ * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes.
+ *
+ * @see CertUtil
+ **/
+public class CertStore extends Object
+{
+ private CertStoreSpi storeSpi;
+ private Provider provider;
+ private String type;
+ private CertStoreParameters params;
+
+ /**
+ * Creates a <code>CertStore</code> object of the given type, and
+ * encapsulates the given provider implementation (SPI object) in it.
+ *
+ * @param storeSpi the provider implementation
+ * @param provider the provider
+ * @param type the type
+ * @param params the initialization parameters (may be <code>null</code>)
+ */
+ protected CertStore( CertStoreSpi storeSpi,
+ Provider provider,
+ String type,
+ CertStoreParameters params )
+ {
+ this.storeSpi = storeSpi;
+ this.provider = provider;
+ this.type = type;
+ this.params = params;
+ }
+
+ /**
+ * Returns a <code>Collection</code> of <code>Certificate</code>s that
+ * match the specified selector. If no <code>Certificate</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.<br />
+ * <br />
+ * For some <code>CertStore</code> types, the resulting
+ * <code>Collection</code> may not contain <b>all</b> of the
+ * <code>Certificate</code>s that match the selector. For instance,
+ * an LDAP <code>CertStore</code> may not search all entries in the
+ * directory. Instead, it may just search entries that are likely to
+ * contain the <code>Certificate</code>s it is looking for.<br />
+ * <br />
+ * Some <code>CertStore</code> implementations (especially LDAP
+ * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
+ * unless a non-null <code>CertSelector</code> is provided that
+ * includes specific criteria that can be used to find the certificates.
+ * Issuer and/or subject names are especially useful criteria.
+ *
+ * @param selector A <code>CertSelector</code> used to select which
+ * <code>Certificate</code>s should be returned. Specify <code>null</code>
+ * to return all <code>Certificate</code>s (if supported).
+ *
+ * @return A <code>Collection</code> of <code>Certificate</code>s that
+ * match the specified selector (never <code>null</code>)
+ * @exception CertStoreException if an exception occurs
+ */
+ public final Collection getCertificates( CertSelector selector )
+ throws CertStoreException
+ {
+ return storeSpi.engineGetCertificates( selector );
+ }
+
+ /**
+ * Returns a <code>Collection</code> of <code>CRL</code>s that
+ * match the specified selector. If no <code>CRL</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.<br />
+ * <br />
+ * For some <code>CertStore</code> types, the resulting
+ * <code>Collection</code> may not contain <b>all</b> of the
+ * <code>CRL</code>s that match the selector. For instance,
+ * an LDAP <code>CertStore</code> may not search all entries in the
+ * directory. Instead, it may just search entries that are likely to
+ * contain the <code>CRL</code>s it is looking for.<br />
+ * <br />
+ * Some <code>CertStore</code> implementations (especially LDAP
+ * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
+ * unless a non-null <code>CRLSelector</code> is provided that
+ * includes specific criteria that can be used to find the CRLs.
+ * Issuer names and/or the certificate to be checked are especially useful.
+ *
+ * @param selector A <code>CRLSelector</code> used to select which
+ * <code>CRL</code>s should be returned. Specify <code>null</code>
+ * to return all <code>CRL</code>s (if supported).
+ *
+ * @return A <code>Collection</code> of <code>CRL</code>s that
+ * match the specified selector (never <code>null</code>)
+ *
+ * @exception CertStoreException if an exception occurs
+ */
+ public final Collection getCRLs( CRLSelector selector )
+ throws CertStoreException
+ {
+ return storeSpi.engineGetCRLs( selector );
+ }
+
+ /**
+ * Returns a <code>CertStore</code> object that implements the specified
+ * <code>CertStore</code> type and is initialized with the specified
+ * parameters.<br />
+ * <br />
+ * If the default provider package provides an implementation
+ * of the specified <code>CertStore</code> type, an instance of
+ * <code>CertStore</code> containing that implementation is returned.
+ * If the requested type is not available in the default package, other
+ * packages are searched.<br />
+ * <br />
+ * The <code>CertStore</code> that is returned is initialized with the
+ * specified <code>CertStoreParameters</code>. The type of parameters
+ * needed may vary between different types of <code>CertStore</code>s.
+ * Note that the specified <code>CertStoreParameters</code> object is
+ * cloned.
+ *
+ * @param type the name of the requested <code>CertStore</code> type
+ * @param params the initialization parameters (may be <code>null</code>)
+ *
+ * @return a <code>CertStore</code> object that implements the specified
+ * <code>CertStore</code> type
+ *
+ * @exception NoSuchAlgorithmException if the requested type is not
+ * available in the default provider package or any of the other provider
+ * packages that were searched
+ * @exception InvalidAlgorithmParameterException if the specified
+ * initialization parameters are inappropriate for this
+ * <code>CertStore</code>
+ */
+ public static CertStore getInstance( String type,
+ CertStoreParameters params)
+ throws InvalidAlgorithmParameterException,
+ NoSuchAlgorithmException
+ {
+ try {
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation( "CertStore", type, (String)null,
+ new Class[] { CertStoreParameters.class },
+ new Object[] { params } );
+ if (imp != null)
+ {
+ return new CertStore((CertStoreSpi)imp.getEngine(), imp.getProvider(), type, params );
+ }
+ } catch ( NoSuchProviderException ex ) {}
+ throw new NoSuchAlgorithmException("can't find type " + type);
+ }
+
+ /**
+ * Returns a <code>CertStore</code> object that implements the specified
+ * <code>CertStore</code> type, as supplied by the specified provider
+ * and initialized with the specified parameters.<br />
+ * <br />
+ * The <code>CertStore</code> that is returned is initialized with the
+ * specified <code>CertStoreParameters</code>. The type of parameters
+ * needed may vary between different types of <code>CertStore</code>s.
+ * Note that the specified <code>CertStoreParameters</code> object is
+ * cloned.
+ *
+ * @param type the requested <code>CertStore</code> type
+ * @param params the initialization parameters (may be <code>null</code>)
+ * @param provider the name of the provider
+ *
+ * @return a <code>CertStore</code> object that implements the
+ * specified type, as supplied by the specified provider
+ *
+ * @exception NoSuchAlgorithmException if the requested type is not
+ * available from the specified provider
+ * @exception InvalidAlgorithmParameterException if the specified
+ * initialization parameters are inappropriate for this
+ * <code>CertStore</code>
+ * @exception NoSuchProviderException if the provider has not been configured
+ * @exception IllegalArgumentException if the <code>provider</code> is
+ * null
+ */
+ public static CertStore getInstance( String type,
+ CertStoreParameters params,
+ String provider)
+ throws InvalidAlgorithmParameterException,
+ NoSuchAlgorithmException,
+ NoSuchProviderException,
+ IllegalArgumentException
+ {
+ if ( provider == null )
+ throw new IllegalArgumentException( "provider must be non-null" );
+
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation( "CertStore", type, provider,
+ new Class[] { CertStoreParameters.class },
+ new Object[] { params } );
+ if (imp != null)
+ {
+ return new CertStore((CertStoreSpi)imp.getEngine(), imp.getProvider(), type, params );
+ }
+ throw new NoSuchAlgorithmException("can't find type " + type);
+ }
+
+ /**
+ * Returns a <code>CertStore</code> object that implements the specified
+ * <code>CertStore</code> type, as supplied by the specified provider and
+ * initialized with the specified parameters.
+ * Note: the <code>provider</code> doesn't have to be registered.<br />
+ * <br />
+ * The <code>CertStore</code> that is returned is initialized with the
+ * specified <code>CertStoreParameters</code>. The type of parameters
+ * needed may vary between different types of <code>CertStore</code>s.
+ * Note that the specified <code>CertStoreParameters</code> object is
+ * cloned.
+ *
+ * @param type the requested <code>CertStore</code> type
+ * @param params the initialization parameters (may be <code>null</code>)
+ * @param provider the provider
+ *
+ * @return a <code>CertStore</code> object that implements the
+ * specified type, as supplied by the specified provider
+ *
+ * @exception NoSuchAlgorithmException if the requested type is not
+ * available from the specified provider
+ * @exception InvalidAlgorithmParameterException if the specified
+ * initialization parameters are inappropriate for this
+ * <code>CertStore</code>
+ * @exception IllegalArgumentException if the <code>provider</code> is
+ * null
+ */
+ public static CertStore getInstance( String type,
+ CertStoreParameters params,
+ Provider provider )
+ throws NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException,
+ IllegalArgumentException
+ {
+ if ( provider == null )
+ throw new IllegalArgumentException( "provider must be non-null" );
+ CertUtil.Implementation imp =
+ CertUtil.getImplementation( "CertStore", type, provider,
+ new Class[] { CertStoreParameters.class },
+ new Object[] { params } );
+ if (imp != null)
+ {
+ return new CertStore((CertStoreSpi)imp.getEngine(), provider, type, params );
+ }
+ throw new NoSuchAlgorithmException("can't find type " + type);
+ }
+
+ /**
+ * Returns the parameters used to initialize this <code>CertStore</code>.
+ * Note that the <code>CertStoreParameters</code> object is cloned before
+ * it is returned.
+ *
+ * @return the parameters used to initialize this <code>CertStore</code>
+ * (may be <code>null</code>)
+ */
+ public final CertStoreParameters getCertStoreParameters()
+ {
+ return params;
+ }
+
+ /**
+ * Returns the type of this <code>CertStore</code>.
+ *
+ * @return the type of this <code>CertStore</code>
+ */
+ public final String getType()
+ {
+ return type;
+ }
+
+ /**
+ * Returns the provider of this <code>CertStore</code>.
+ *
+ * @return the provider of this <code>CertStore</code>
+ */
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the default <code>CertStore</code> type as specified in the
+ * Java security properties file, or the string &quot;LDAP&quot; if no
+ * such property exists. The Java security properties file is located in
+ * the file named &lt;JAVA_HOME&gt;/lib/security/java.security, where
+ * &lt;JAVA_HOME&gt; refers to the directory where the SDK was installed.<br />
+ * <br />
+ * The default <code>CertStore</code> type can be used by applications
+ * that do not want to use a hard-coded type when calling one of the
+ * <code>getInstance</code> methods, and want to provide a default
+ * <code>CertStore</code> type in case a user does not specify its own.<br />
+ * <br />
+ * The default <code>CertStore</code> type can be changed by setting
+ * the value of the "certstore.type" security property (in the Java
+ * security properties file) to the desired type.
+ *
+ * @return the default <code>CertStore</code> type as specified in the
+ * Java security properties file, or the string &quot;LDAP&quot;
+ * if no such property exists.
+ */
+ public static final String getDefaultType()
+ {
+ String defaulttype = null;
+ defaulttype = Security.getProperty("certstore.type");
+
+ if ( defaulttype == null || defaulttype.length() <= 0 )
+ return "LDAP";
+ else
+ return defaulttype;
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreException.java
new file mode 100644
index 000000000..a15bc3df6
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreException.java
@@ -0,0 +1,172 @@
+package java.security.cert;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.security.GeneralSecurityException;
+
+/**
+ * An exception indicating one of a variety of problems retrieving
+ * certificates and CRLs from a <code>CertStore</code>.<br />
+ * <br />
+ * A <code>CertStoreException</code> provides support for wrapping
+ * exceptions. The {@link #getCause getCause} method returns the throwable,
+ * if any, that caused this exception to be thrown.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertStore
+ **/
+public class CertStoreException extends GeneralSecurityException
+{
+ private Throwable cause;
+
+ /**
+ * Creates a <code>CertStoreException</code> with <code>null</code> as
+ * its detail message.
+ */
+ public CertStoreException()
+ {
+ super();
+ }
+
+ /**
+ * Creates a <code>CertStoreException</code> with the given detail
+ * message. A detail message is a <code>String</code> that describes this
+ * particular exception.
+ *
+ * @param messag the detail message
+ */
+ public CertStoreException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Creates a <code>CertStoreException</code> with the specified detail
+ * message and cause.
+ *
+ * @param messag the detail message
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause getCause()} method). (A <code>null</code> value is
+ * permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public CertStoreException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ /**
+ * Creates a <code>CertStoreException</code> that wraps the specified
+ * throwable. This allows any exception to be converted into a
+ * <code>CertStoreException</code>, while retaining information about the
+ * cause, which may be useful for debugging. The detail message is
+ * set to (<code>cause==null ? null : cause.toString()</code>) (which
+ * typically contains the class and detail message of cause).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause getCause()} method). (A <code>null</code> value is
+ * permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public CertStoreException(Throwable cause)
+ {
+ this.cause = cause;
+ }
+
+ /**
+ * Returns the detail message for this <code>CertStoreException</code>.
+ *
+ * @return the detail message, or <code>null</code> if neither the message
+ * nor cause were specified
+ */
+ public String getMessage()
+ {
+ String message = super.getMessage();
+
+ if ( message == null && cause == null )
+ return null;
+
+ StringBuffer s = new StringBuffer();
+ if ( message != null )
+ {
+ s.append(message).append('\n');
+ }
+ if ( cause != null )
+ {
+ s.append("Cause:\n").append(cause.getMessage());
+ }
+ return s.toString();
+ }
+
+ /**
+ * Returns the cause of this <code>CertStoreException</code> or
+ * <code>null</code> if the cause is nonexistent or unknown.
+ *
+ * @return the cause of this throwable or <code>null</code> if the cause
+ * is nonexistent or unknown.
+ */
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+ /**
+ * Returns a string describing this exception, including a description
+ * of the internal (wrapped) cause if there is one.
+ *
+ * @return a string representation of this
+ * <code>CertStoreException</code>
+ */
+ public String toString()
+ {
+ String message = getMessage();
+ if ( message == null )
+ return "";
+
+ return message;
+ }
+
+ /**
+ * Prints a stack trace to <code>System.err</code>, including the backtrace
+ * of the cause, if any.
+ */
+ public void printStackTrace() {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Prints a stack trace to a <code>PrintStream</code>, including the
+ * backtrace of the cause, if any.
+ *
+ * @param ps the <code>PrintStream</code> to use for output
+ */
+ public void printStackTrace(PrintStream ps) {
+ super.printStackTrace(ps);
+ if ( cause != null ) {
+ cause.printStackTrace(ps);
+ }
+ }
+
+ /**
+ * Prints a stack trace to a <code>PrintWriter</code>, including the
+ * backtrace of the cause, if any.
+ *
+ * @param pw the <code>PrintWriter</code> to use for output
+ */
+ public void printStackTrace(PrintWriter pw) {
+ if ( cause != null ) {
+ cause.printStackTrace(pw);
+ }
+ super.printStackTrace(pw);
+ if ( cause != null ) {
+ cause.printStackTrace(pw);
+ }
+ }
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreParameters.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreParameters.java
new file mode 100644
index 000000000..58a70b372
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreParameters.java
@@ -0,0 +1,52 @@
+package java.security.cert;
+
+/**
+ * A specification of <code>CertStore</code> parameters.<br />
+ * <br />
+ * The purpose of this interface is to group (and provide type safety for)
+ * all <code>CertStore</code> parameter specifications. All
+ * <code>CertStore</code> parameter specifications must implement this
+ * interface. <br />
+ * <br />
+ * Typically, a <code>CertStoreParameters</code> object is passed as a parameter
+ * to one of the {@link CertStore#getInstance CertStore.getInstance} methods.
+ * The <code>getInstance</code> method returns a <code>CertStore</code> that
+ * is used for retrieving <code>Certificate</code>s and <code>CRL</code>s. The
+ * <code>CertStore</code> that is returned is initialized with the specified
+ * parameters. The type of parameters needed may vary between different types
+ * of <code>CertStore</code>s.
+ *
+ * @see CertStore#getInstance
+ **/
+public interface CertStoreParameters extends Cloneable
+{
+ /**
+ * Makes a copy of this <code>CertStoreParameters</code>.<br />
+ * <br />
+ * The precise meaning of "copy" may depend on the class of
+ * the <code>CertStoreParameters</code> object. A typical implementation
+ * performs a "deep copy" of this object, but this is not an absolute
+ * requirement. Some implementations may perform a "shallow copy" of some
+ * or all of the fields of this object.<br />
+ * <br />
+ * Note that the <code>CertStore.getInstance</code> methods make a copy
+ * of the specified <code>CertStoreParameters</code>. A deep copy
+ * implementation of <code>clone</code> is safer and more robust, as it
+ * prevents the caller from corrupting a shared <code>CertStore</code> by
+ * subsequently modifying the contents of its initialization parameters.
+ * However, a shallow copy implementation of <code>clone</code> is more
+ * appropriate for applications that need to hold a reference to a
+ * parameter contained in the <code>CertStoreParameters</code>. For example,
+ * a shallow copy clone allows an application to release the resources of
+ * a particular <code>CertStore</code> initialization parameter immediately,
+ * rather than waiting for the garbage collection mechanism. This should
+ * be done with the utmost care, since the <code>CertStore</code> may still
+ * be in use by other threads.<br />
+ * <br />
+ * Each subclass should state the precise behavior of this method so
+ * that users and developers know what to expect.
+ *
+ * @return a copy of this <code>CertStoreParameters</code>
+ */
+ public Object clone();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreSpi.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreSpi.java
new file mode 100644
index 000000000..b92cf4aa5
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertStoreSpi.java
@@ -0,0 +1,104 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.util.Collection;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the {@link CertStore CertStore} class. All <code>CertStore</code>
+ * implementations must include a class (the SPI class) that extends
+ * this class (<code>CertStoreSpi</code>), provides a constructor with
+ * a single argument of type <code>CertStoreParameters</code>, and implements
+ * all of its methods. In general, instances of this class should only be
+ * accessed through the <code>CertStore</code> class.
+ * For details, see the Java Cryptography Architecture.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * The public methods of all <code>CertStoreSpi</code> objects must be
+ * thread-safe. That is, multiple threads may concurrently invoke these
+ * methods on a single <code>CertStoreSpi</code> object (or more than one)
+ * with no ill effects. This allows a <code>CertPathBuilder</code> to search
+ * for a CRL while simultaneously searching for further certificates, for
+ * instance.<br />
+ * <br />
+ * Simple <code>CertStoreSpi</code> implementations will probably ensure
+ * thread safety by adding a <code>synchronized</code> keyword to their
+ * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods.
+ * More sophisticated ones may allow truly concurrent access.
+ **/
+public abstract class CertStoreSpi
+ extends Object
+{
+
+ /**
+ * The sole constructor.
+ *
+ * @param params the initialization parameters (may be <code>null</code>)
+ * @exception InvalidAlgorithmParameterException if the initialization
+ * parameters are inappropriate for this <code>CertStoreSpi</code>
+ */
+ public CertStoreSpi( CertStoreParameters params )
+ throws InvalidAlgorithmParameterException {}
+
+ /**
+ * Returns a <code>Collection</code> of <code>Certificate</code>s that
+ * match the specified selector. If no <code>Certificate</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.<br />
+ * <br />
+ * For some <code>CertStore</code> types, the resulting
+ * <code>Collection</code> may not contain <b>all</b> of the
+ * <code>Certificate</code>s that match the selector. For instance,
+ * an LDAP <code>CertStore</code> may not search all entries in the
+ * directory. Instead, it may just search entries that are likely to
+ * contain the <code>Certificate</code>s it is looking for.<br />
+ * <br />
+ * Some <code>CertStore</code> implementations (especially LDAP
+ * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
+ * unless a non-null <code>CertSelector</code> is provided that includes
+ * specific criteria that can be used to find the certificates. Issuer
+ * and/or subject names are especially useful criteria.
+ *
+ * @param selector A <code>CertSelector</code> used to select which
+ * <code>Certificate</code>s should be returned. Specify <code>null</code>
+ * to return all <code>Certificate</code>s (if supported).
+ *
+ * @return A <code>Collection</code> of <code>Certificate</code>s that
+ * match the specified selector (never <code>null</code>)
+ *
+ * @exception CertStoreException if an exception occurs
+ */
+ public abstract Collection engineGetCertificates( CertSelector selector )
+ throws CertStoreException;
+
+ /**
+ * Returns a <code>Collection</code> of <code>CRL</code>s that
+ * match the specified selector. If no <code>CRL</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.<br />
+ * <br />
+ * For some <code>CertStore</code> types, the resulting
+ * <code>Collection</code> may not contain <b>all</b> of the
+ * <code>CRL</code>s that match the selector. For instance,
+ * an LDAP <code>CertStore</code> may not search all entries in the
+ * directory. Instead, it may just search entries that are likely to
+ * contain the <code>CRL</code>s it is looking for. <br />
+ * <br />
+ * Some <code>CertStore</code> implementations (especially LDAP
+ * <code>CertStore</code>s) may throw a <code>CertStoreException</code>
+ * unless a non-null <code>CRLSelector</code> is provided that includes
+ * specific criteria that can be used to find the CRLs. Issuer names
+ * and/or the certificate to be checked are especially useful.
+ *
+ * @param selector A <code>CRLSelector</code> used to select which
+ * <code>CRL</code>s should be returned. Specify <code>null</code>
+ * to return all <code>CRL</code>s (if supported).
+ *
+ * @return A <code>Collection</code> of <code>CRL</code>s that
+ * match the specified selector (never <code>null</code>)
+ *
+ * @exception CertStoreException if an exception occurs
+ */
+ public abstract Collection engineGetCRLs( CRLSelector selector )
+ throws CertStoreException;
+}
+
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertUtil.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertUtil.java
new file mode 100644
index 000000000..216a8d8e4
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertUtil.java
@@ -0,0 +1,556 @@
+package java.security.cert;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.OIDTokenizer;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.util.Strings;
+
+class CertUtil
+{
+ static class Implementation
+ {
+ Object engine;
+ Provider provider;
+
+ Implementation(
+ Object engine,
+ Provider provider)
+ {
+ this.engine = engine;
+ this.provider = provider;
+ }
+
+ Object getEngine()
+ {
+ return engine;
+ }
+
+ Provider getProvider()
+ {
+ return provider;
+ }
+ }
+
+ /**
+ * see if we can find an algorithm (or its alias and what it represents) in
+ * the property table for the given provider.
+ *
+ * @return null if no algorithm found, an Implementation if it is.
+ */
+ static Implementation getImplementation(
+ String baseName,
+ String algorithm,
+ Provider prov)
+ {
+ if (prov == null)
+ {
+ Provider[] provider = Security.getProviders();
+
+ //
+ // search every provider looking for the algorithm we want.
+ //
+ for (int i = 0; i != provider.length; i++)
+ {
+ Implementation imp = getImplementation(baseName, algorithm, provider[i]);
+ if (imp != null)
+ {
+ return imp;
+ }
+ }
+
+ return null;
+ }
+
+ String alias;
+
+ while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null)
+ {
+ algorithm = alias;
+ }
+
+ String className = prov.getProperty(baseName + "." + algorithm);
+
+ if (className != null)
+ {
+ try
+ {
+ return new Implementation(Class.forName(className).newInstance(), prov);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new IllegalStateException(
+ "algorithm " + algorithm + " in provider " + prov.getName() + " but no class found!");
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException(
+ "algorithm " + algorithm + " in provider " + prov.getName() + " but class inaccessible: " + e.toString());
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * return an implementation for a given algorithm/provider.
+ * If the provider is null, we grab the first avalaible who has the required algorithm.
+ *
+ * @return null if no algorithm found, an Implementation if it is.
+ * @exception NoSuchProviderException if a provider is specified and not found.
+ */
+ static Implementation getImplementation(
+ String baseName,
+ String algorithm,
+ String provider)
+ throws NoSuchProviderException
+ {
+ if (provider == null)
+ {
+ Provider[] prov = Security.getProviders();
+
+ //
+ // search every provider looking for the algorithm we want.
+ //
+ for (int i = 0; i != prov.length; i++)
+ {
+ Implementation imp = getImplementation(baseName, algorithm, prov[i]);
+ if (imp != null)
+ {
+ return imp;
+ }
+ }
+ }
+ else
+ {
+ Provider prov = Security.getProvider(provider);
+
+ if (prov == null)
+ {
+ throw new NoSuchProviderException("Provider " + provider + " not found");
+ }
+
+ return getImplementation(baseName, algorithm, prov);
+ }
+
+ return null;
+ }
+
+ /**
+ * see if we can find an algorithm (or its alias and what it represents) in
+ * the property table for the given provider.
+ *
+ * @return null if no algorithm found, an Implementation if it is.
+ */
+ static Implementation getImplementation(String baseName, String algorithm,
+ Provider prov, Class[] ctorparamtype, Object[] ctorparam)
+ throws InvalidAlgorithmParameterException
+ {
+ String alias;
+
+ while ((alias = prov.getProperty("Alg.Alias." + baseName + "."
+ + algorithm)) != null)
+ {
+ algorithm = alias;
+ }
+
+ String className = prov.getProperty(baseName + "." + algorithm);
+
+ if (className != null)
+ {
+ try
+ {
+ return new Implementation(Class.forName(className)
+ .getConstructor(ctorparamtype).newInstance(ctorparam),
+ prov);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new IllegalStateException("algorithm " + algorithm
+ + " in provider " + prov.getName()
+ + " but no class found!");
+ }
+ catch (Exception e)
+ {
+ if (e instanceof InvalidAlgorithmParameterException)
+ {
+ throw (InvalidAlgorithmParameterException)e;
+ }
+
+ throw new IllegalStateException("algorithm " + algorithm
+ + " in provider " + prov.getName()
+ + " but class inaccessible!");
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * return an implementation for a given algorithm/provider. If the provider
+ * is null, we grab the first avalaible who has the required algorithm.
+ *
+ * @return null if no algorithm found, an Implementation if it is.
+ *
+ * @exception NoSuchProviderException
+ * if a provider is specified and not found.
+ */
+ static Implementation getImplementation(String baseName, String algorithm,
+ String provider, Class[] ctorparamtype, Object[] ctorparam)
+ throws NoSuchProviderException, InvalidAlgorithmParameterException
+ {
+ if (provider == null)
+ {
+ Provider[] prov = Security.getProviders();
+
+ //
+ // search every provider looking for the algorithm we want.
+ //
+ for (int i = 0; i != prov.length; i++)
+ {
+ Implementation imp = getImplementation(baseName, algorithm,
+ prov[i], ctorparamtype, ctorparam);
+ if (imp != null)
+ {
+ return imp;
+ }
+ }
+ }
+ else
+ {
+ Provider prov = Security.getProvider(provider);
+
+ if (prov == null)
+ {
+ throw new NoSuchProviderException("Provider " + provider
+ + " not found");
+ }
+
+ return getImplementation(baseName, algorithm, prov, ctorparamtype,
+ ctorparam);
+ }
+
+ return null;
+ }
+
+ static byte[] parseGeneralName(int type, String data) throws IOException
+ {
+ byte[] encoded = null;
+
+ switch (type)
+ {
+ case 0:
+ throw new IOException(
+ "unable to parse OtherName String representation");
+ case 1:
+ encoded = parseRfc822(data.trim());
+ break;
+ case 2:
+ encoded = parseDNSName(data.trim());
+ break;
+ case 3:
+ throw new IOException(
+ "unable to parse ORAddress String representation");
+ case 4:
+ encoded = parseX509Name(data.trim());
+ break;
+ case 5:
+ throw new IOException(
+ "unable to parse EDIPartyName String representation");
+ case 6:
+ encoded = parseURI(data.trim());
+ break;
+ case 7:
+ encoded = parseIP(data.trim());
+ break;
+ case 8:
+ encoded = parseOID(data.trim());
+ break;
+ default:
+ throw new IOException(
+ "unable to parse unkown type String representation");
+ }
+ return encoded;
+ }
+
+ /**
+ * Check the format of an OID.<br />
+ * Throw an IOException if the first component is not 0, 1 or 2 or the
+ * second component is greater than 39.<br />
+ * <br />
+ * User {@link org.spongycastle.asn1.OIDTokenizer OIDTokenizer}
+ *
+ * @param the
+ * OID to be checked.
+ *
+ * @exception IOException
+ * if the first component is not 0, 1 or 2 or the second
+ * component is greater than 39.
+ */
+ static byte[] parseOID(String oid) throws IOException
+ {
+ OIDTokenizer tokenizer = new OIDTokenizer(oid);
+ String token;
+ if (!tokenizer.hasMoreTokens())
+ {
+ throw new IOException("OID contains no tokens");
+ }
+ token = tokenizer.nextToken();
+ if (token == null)
+ {
+ throw new IOException("OID contains no tokens");
+ }
+ try
+ {
+ int test = (Integer.valueOf(token)).intValue();
+ if (test < 0 || test > 2)
+ {
+ throw new IOException("first token is not >= 0 and <=2");
+ }
+ if (!tokenizer.hasMoreTokens())
+ {
+ throw new IOException("OID contains only one token");
+ }
+ token = tokenizer.nextToken();
+ if (token == null)
+ {
+ throw new IOException("OID contains only one token");
+ }
+ test = (Integer.valueOf(token)).intValue();
+ if (test < 0 || test > 39)
+ {
+ throw new IOException("secon token is not >= 0 and <=39");
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new IOException("token: " + token + ": " + ex.toString());
+ }
+ ASN1Object derData = new ASN1ObjectIdentifier(oid);
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+ derOutStream.writeObject(derData);
+ derOutStream.close();
+ return outStream.toByteArray();
+ }
+
+ /**
+ * Parse the given IPv4 or IPv6 into DER encoded byte array representation.
+ *
+ * @param the
+ * IP in well known String format
+ *
+ * @return the IP as byte array
+ *
+ * @exception IOException
+ * if the String could not be parsed
+ */
+ private static byte[] parseIP(String data) throws IOException
+ {
+ byte[] encoded = parseIPv4(data);
+
+ if (encoded == null)
+ {
+ encoded = parseIPv6(data);
+ }
+
+ if (encoded == null)
+ {
+ throw new IOException(
+ "unable to parse IP to DER encoded byte array");
+ }
+
+ return encoded;
+ }
+
+ /**
+ * Parse the given IPv4 into DER encoded byte array representation.
+ *
+ * @param the
+ * IP in well known String format
+ *
+ * @return the IP as byte array or <code>null</code> if not parseable
+ */
+ private static byte[] parseIPv4(String data)
+ {
+ if (data.length() == 0)
+ {
+ return null;
+ }
+
+ int octet;
+ int octets = 0;
+ byte[] dst = new byte[4];
+
+ int pos = 0;
+ int start = 0;
+ while (start < data.length()
+ && (pos = data.indexOf('.', start)) > start && pos - start > 3)
+ {
+ try
+ {
+ octet = (Integer.valueOf(data.substring(start, pos - start)))
+ .intValue();
+ }
+ catch (NumberFormatException ex)
+ {
+ return null;
+ }
+ if (octet < 0 || octet > 255)
+ {
+ return null;
+ }
+ dst[octets++] = (byte)(octet & 0xff);
+
+ start = pos + 1;
+ }
+
+ if (octets < 4)
+ {
+ return null;
+ }
+
+ return dst;
+ }
+
+ /**
+ * Parse the given IPv6 into DER encoded byte array representation.<br />
+ * <br />
+ * <b>TODO: implement this</b>
+ *
+ * @param the
+ * IP in well known String format
+ *
+ * @return the IP as byte array or <code>null</code> if not parseable
+ */
+ private static byte[] parseIPv6(String data)
+ {
+ return null;
+ }
+
+ /**
+ * Parse the given URI into DER encoded byte array representation.
+ *
+ * @param the
+ * URI in well known String format
+ *
+ * @return the URI as byte array
+ *
+ * @exception IOException
+ * if the String could not be parsed
+ */
+ private static byte[] parseURI(String data) throws IOException
+ {
+ // TODO do parsing test
+ ASN1Object derData = new DERIA5String(data);
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+ derOutStream.writeObject(derData);
+ derOutStream.close();
+ return outStream.toByteArray();
+ }
+
+ /**
+ * Parse the given rfc822 addr-spec into DER encoded byte array
+ * representation.
+ *
+ * @param the
+ * rfc822 addr-spec in well known String format
+ *
+ * @return the rfc822 addr-spec as byte array
+ *
+ * @exception IOException
+ * if the String could not be parsed
+ */
+ private static byte[] parseRfc822(String data) throws IOException
+ {
+ int tmpInt = data.indexOf('@');
+ if (tmpInt < 0 || tmpInt >= data.length() - 1)
+ {
+ throw new IOException("wrong format of rfc822Name:" + data);
+ }
+ // TODO more test for illegal charateers
+ ASN1Object derData = new DERIA5String(data);
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+ derOutStream.writeObject(derData);
+ derOutStream.close();
+ return outStream.toByteArray();
+ }
+
+ /**
+ * Parse the given DNS name into DER encoded byte array representation. The
+ * String must be in den preffered name syntax as defined in RFC 1034.
+ *
+ * @param the
+ * DNS name in well known String format
+ *
+ * @return the DNS name as byte array
+ *
+ * @exception IOException
+ * if the String could not be parsed
+ */
+ private static byte[] parseDNSName(String data) throws IOException
+ {
+ // TODO more test for illegal charateers
+ ASN1Object derData = new DERIA5String(data);
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+ derOutStream.writeObject(derData);
+ derOutStream.close();
+ return outStream.toByteArray();
+ }
+
+ /**
+ * Parse the given X.509 name into DER encoded byte array representation.
+ *
+ * @param the
+ * X.509 name in well known String format
+ *
+ * @return the X.509 name as byte array
+ *
+ * @exception IOException
+ * if the String could not be parsed
+ */
+ private static byte[] parseX509Name(String data) throws IOException
+ {
+ // TODO more test for illegal charateers
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+ derOutStream.writeObject(new X509Name(trimX509Name(data)));
+ derOutStream.close();
+ return outStream.toByteArray();
+ }
+
+ /**
+ * Returns the given name converted to upper case and all multi spaces squezed
+ * to one space.
+ **/
+ static String trimX509Name(String name)
+ {
+ String data = Strings.toUpperCase(name.trim());
+ int pos;
+ while ((pos = data.indexOf(" ")) >= 0)
+ {
+ data = data.substring(0, pos) + data.substring(pos + 1);
+ }
+ while ((pos = data.indexOf(" =")) >= 0)
+ {
+ data = data.substring(0, pos) + data.substring(pos + 1);
+ }
+ while ((pos = data.indexOf("= ")) >= 0)
+ {
+ data = data.substring(0, pos + 1) + data.substring(pos + 2);
+ }
+ return data;
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/Certificate.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/Certificate.java
new file mode 100644
index 000000000..201e209a3
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/Certificate.java
@@ -0,0 +1,80 @@
+
+package java.security.cert;
+
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.SignatureException;
+
+public abstract class Certificate extends Object
+{
+ private String type;
+
+ protected Certificate(String type)
+ {
+ this.type = type;
+ }
+
+ public boolean equals(Object other)
+ {
+ if ( !(other instanceof Certificate) )
+ return false;
+
+ if ( other == this )
+ return true;
+
+ try
+ {
+ byte[] enc1 = getEncoded();
+ byte[] enc2 = ((Certificate)other).getEncoded();
+
+ return MessageDigest.isEqual(enc1, enc2);
+ }
+ catch (CertificateEncodingException e)
+ {
+ return false;
+ }
+ }
+
+ public final String getType()
+ {
+ return type;
+ }
+
+ // XXX
+ public int hashCode()
+ {
+ try
+ {
+ byte[] enc1 = getEncoded();
+ int hc = 0;
+ for (int i = 0; i < enc1.length; i++)
+ {
+ hc += enc1[i];
+ }
+
+ return hc;
+ }
+ catch (CertificateEncodingException e)
+ {
+ return 0;
+ }
+ }
+
+ public abstract byte[] getEncoded()
+ throws CertificateEncodingException;
+
+ public abstract PublicKey getPublicKey();
+
+ public abstract String toString();
+
+ public abstract void verify(PublicKey key)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException;
+
+ public abstract void verify(PublicKey key, String sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException;
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateEncodingException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateEncodingException.java
new file mode 100644
index 000000000..47545a5c0
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateEncodingException.java
@@ -0,0 +1,14 @@
+
+package java.security.cert;
+
+public class CertificateEncodingException extends CertificateException
+{
+ public CertificateEncodingException()
+ {
+ }
+
+ public CertificateEncodingException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateException.java
new file mode 100644
index 000000000..644c6249f
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateException.java
@@ -0,0 +1,16 @@
+
+package java.security.cert;
+
+import java.security.GeneralSecurityException;
+
+public class CertificateException extends GeneralSecurityException
+{
+ public CertificateException()
+ {
+ }
+
+ public CertificateException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateExpiredException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateExpiredException.java
new file mode 100644
index 000000000..1a9062aa2
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateExpiredException.java
@@ -0,0 +1,14 @@
+
+package java.security.cert;
+
+public class CertificateExpiredException extends CertificateException
+{
+ public CertificateExpiredException()
+ {
+ }
+
+ public CertificateExpiredException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactory.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactory.java
new file mode 100644
index 000000000..e86cd3a03
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactory.java
@@ -0,0 +1,183 @@
+
+package java.security.cert;
+
+import java.io.InputStream;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Uses {@link CertUtil CertUtil} to actualiy load the SPI classes.
+ *
+ * @see CertUtil
+ **/
+public class CertificateFactory
+{
+ private CertificateFactorySpi certFacSpi;
+ private Provider provider;
+ private String type;
+
+ protected CertificateFactory(
+ CertificateFactorySpi certFacSpi,
+ Provider provider,
+ String type)
+ {
+ this.certFacSpi = certFacSpi;
+ this.provider = provider;
+ this.type = type;
+ }
+
+ public final CRL generateCRL(InputStream inStream)
+ throws CRLException
+ {
+ return certFacSpi.engineGenerateCRL(inStream);
+ }
+
+ public final Collection generateCRLs(InputStream inStream)
+ throws CRLException
+ {
+ return certFacSpi.engineGenerateCRLs(inStream);
+ }
+
+ public final Certificate generateCertificate(InputStream inStream)
+ throws CertificateException
+ {
+ return certFacSpi.engineGenerateCertificate(inStream);
+ }
+
+ public final /*Sk13 Vector*/ Collection generateCertificates(InputStream inStream)
+ throws CertificateException
+ {
+ return certFacSpi.engineGenerateCertificates(inStream);
+ }
+
+ /**
+ * Returns an iteration of the <code>CertPath</code> encodings supported
+ * by this certificate factory, with the default encoding first. See
+ * Appendix A in the
+ * Java Certification Path API Programmer's Guide for information about
+ * standard encoding names and their formats.<br />
+ * <br />
+ * Attempts to modify the returned <code>Iterator</code> via its
+ * <code>remove</code> method result in an
+ * <code>UnsupportedOperationException</code>.
+ *
+ * @return an <code>Iterator</code> over the names of the supported
+ * <code>CertPath</code> encodings (as <code>String</code>s)
+ */
+ public final Iterator getCertPathEncodings()
+ {
+ return certFacSpi.engineGetCertPathEncodings();
+ }
+
+ /**
+ * Generates a <code>CertPath</code> object and initializes it with
+ * the data read from the <code>InputStream</code> inStream. The data
+ * is assumed to be in the default encoding. The name of the default
+ * encoding is the first element of the <code>Iterator</code> returned by
+ * the {@link #getCertPathEncodings getCertPathEncodings} method.
+ *
+ * @param inStream an <code>InputStream</code> containing the data
+ *
+ * @return a <code>CertPath</code> initialized with the data from the
+ * <code>InputStream</code>
+ *
+ * @exception CertificateException if an exception occurs while decoding
+ */
+ public final CertPath generateCertPath(InputStream inStream)
+ throws CertificateException
+ {
+ return certFacSpi.engineGenerateCertPath(inStream);
+ }
+
+ /**
+ * Generates a <code>CertPath</code> object and initializes it with
+ * the data read from the <code>InputStream</code> inStream. The data
+ * is assumed to be in the specified encoding. See Appendix A in the
+ * <a href="../../../../guide/security/certpath/CertPathProgGuide.html#AppA">
+ * Java Certification Path API Programmer's Guide</a>
+ * for information about standard encoding names and their formats.
+ *
+ * @param inStream an <code>InputStream</code> containing the data
+ * @param encoding the encoding used for the data
+ *
+ * @return a <code>CertPath</code> initialized with the data from the
+ * <code>InputStream</code>
+ *
+ * @exception CertificateException if an exception occurs while decoding or
+ * the encoding requested is not supported
+ */
+ public final CertPath generateCertPath(InputStream inStream, String encoding)
+ throws CertificateException
+ {
+ return certFacSpi.engineGenerateCertPath(inStream, encoding);
+ }
+
+ /**
+ * Generates a <code>CertPath</code> object and initializes it with
+ * a <code>List</code> of <code>Certificate</code>s.<br />
+ * <br />
+ * The certificates supplied must be of a type supported by the
+ * <code>CertificateFactory</code>. They will be copied out of the supplied
+ * <code>List</code> object.
+ *
+ * @param certificates a <code>List</code> of <code>Certificate</code>s
+ *
+ * @return a <code>CertPath</code> initialized with the supplied list of
+ * certificates
+ *
+ * @exception CertificateException if an exception occurs
+ */
+ public final CertPath generateCertPath(List certificates)
+ throws CertificateException
+ {
+ return certFacSpi.engineGenerateCertPath( certificates );
+ }
+
+ public static final CertificateFactory getInstance(String type)
+ throws CertificateException
+ {
+ try
+ {
+ CertUtil.Implementation imp = CertUtil.getImplementation("CertificateFactory", type, (String)null);
+
+ if (imp != null)
+ {
+ return new CertificateFactory((CertificateFactorySpi)imp.getEngine(), imp.getProvider(), type);
+ }
+
+ throw new CertificateException("can't find type " + type);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new CertificateException(type + " not found");
+ }
+ }
+
+ public static final CertificateFactory getInstance(
+ String type,
+ String provider)
+ throws CertificateException, NoSuchProviderException
+ {
+ CertUtil.Implementation imp = CertUtil.getImplementation("CertificateFactory", type, provider);
+
+ if (imp != null)
+ {
+ return new CertificateFactory((CertificateFactorySpi)imp.getEngine(), imp.getProvider(), type);
+ }
+
+ throw new CertificateException("can't find type " + type);
+ }
+
+ public final Provider getProvider()
+ {
+ return provider;
+ }
+
+ public final String getType()
+ {
+ return type;
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactorySpi.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactorySpi.java
new file mode 100644
index 000000000..8cc06fc2e
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateFactorySpi.java
@@ -0,0 +1,111 @@
+
+package java.security.cert;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+public abstract class CertificateFactorySpi
+{
+ public CertificateFactorySpi()
+ {
+ }
+
+ public abstract CRL engineGenerateCRL(InputStream inStream)
+ throws CRLException;
+
+ public abstract Collection engineGenerateCRLs(InputStream inStream)
+ throws CRLException;
+
+ public abstract Certificate engineGenerateCertificate(InputStream inStream)
+ throws CertificateException;
+
+ public abstract /*SK13 Vector*/ Collection engineGenerateCertificates(InputStream inStream)
+ throws CertificateException;
+
+ /**
+ * Returns an iteration of the <code>CertPath</code> encodings supported
+ * by this certificate factory, with the default encoding first. See
+ * Appendix A in the
+ * Java Certification Path API Programmer's Guide
+ * for information about standard encoding names.<br />
+ * <br />
+ * Attempts to modify the returned <code>Iterator</code> via its
+ * <code>remove</code> method result in an
+ * <code>UnsupportedOperationException</code>.<br />
+ * <br />
+ * This method was added to version 1.4 of the Java 2 Platform
+ * Standard Edition. In order to maintain backwards compatibility with
+ * existing service providers, this method cannot be <code>abstract</code>
+ * and by default throws an <code>UnsupportedOperationException</code>.
+ *
+ * @return an <code>Iterator</code> over the names of the supported
+ * <code>CertPath</code> encodings (as <code>String</code>s)
+ *
+ * @exception UnsupportedOperationException if the method is not supported
+ */
+ public abstract Iterator engineGetCertPathEncodings();
+
+ /**
+ * Generates a <code>CertPath</code> object and initializes it with
+ * the data read from the <code>InputStream</code> inStream. The data
+ * is assumed to be in the default encoding.
+ *
+ * @param inStream an <code>InputStream</code> containing the data
+ *
+ * @return a <code>CertPath</code> initialized with the data from the
+ * <code>InputStream</code>
+ *
+ * @exception CertificateException if an exception occurs while decoding
+ */
+ public abstract CertPath engineGenerateCertPath(InputStream inStream)
+ throws CertificateException;
+
+ /**
+ * Generates a <code>CertPath</code> object and initializes it with
+ * the data read from the <code>InputStream</code> inStream. The data
+ * is assumed to be in the specified encoding.<br />
+ * <br />
+ * This method was added to version 1.4 of the Java 2 Platform
+ * Standard Edition. In order to maintain backwards compatibility with
+ * existing service providers, this method cannot be <code>abstract</code>
+ * and by default throws an <code>UnsupportedOperationException</code>.
+ *
+ * @param inStream an <code>InputStream</code> containing the data
+ * @param encoding the encoding used for the data
+ *
+ * @return a <code>CertPath</code> initialized with the data from the
+ * <code>InputStream</code>
+ *
+ * @exception CertificateException if an exception occurs while decoding or
+ * the encoding requested is not supported
+ * @exception UnsupportedOperationException if the method is not supported
+ */
+ public abstract CertPath engineGenerateCertPath(InputStream inStream, String encoding)
+ throws CertificateException;
+
+ /**
+ * Generates a <code>CertPath</code> object and initializes it with
+ * a <code>List</code> of <code>Certificate</code>s.<br />
+ * <br />
+ * The certificates supplied must be of a type supported by the
+ * <code>CertificateFactory</code>. They will be copied out of the supplied
+ * <code>List</code> object.<br />
+ * <br />
+ * This method was added to version 1.4 of the Java 2 Platform
+ * Standard Edition. In order to maintain backwards compatibility with
+ * existing service providers, this method cannot be <code>abstract</code>
+ * and by default throws an <code>UnsupportedOperationException</code>.
+ *
+ * @param certificates a <code>List</code> of <code>Certificate</code>s
+ *
+ * @return a <code>CertPath</code> initialized with the supplied list of
+ * certificates
+ *
+ * @exception CertificateException if an exception occurs
+ * @exception UnsupportedOperationException if the method is not supported
+ */
+ public abstract CertPath engineGenerateCertPath(List certificates)
+ throws CertificateException;
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateNotYetValidException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateNotYetValidException.java
new file mode 100644
index 000000000..ec8d46a3e
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateNotYetValidException.java
@@ -0,0 +1,14 @@
+
+package java.security.cert;
+
+public class CertificateNotYetValidException extends CertificateException
+{
+ public CertificateNotYetValidException()
+ {
+ }
+
+ public CertificateNotYetValidException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateParsingException.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateParsingException.java
new file mode 100644
index 000000000..a9f18aae0
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CertificateParsingException.java
@@ -0,0 +1,14 @@
+
+package java.security.cert;
+
+public class CertificateParsingException extends CertificateException
+{
+ public CertificateParsingException()
+ {
+ }
+
+ public CertificateParsingException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CollectionCertStoreParameters.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CollectionCertStoreParameters.java
new file mode 100644
index 000000000..7c31e7b51
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/CollectionCertStoreParameters.java
@@ -0,0 +1,117 @@
+package java.security.cert;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Parameters used as input for the Collection <code>CertStore</code>
+ * algorithm.<br />
+ * <br />
+ * This class is used to provide necessary configuration parameters
+ * to implementations of the Collection <code>CertStore</code>
+ * algorithm. The only parameter included in this class is the
+ * <code>Collection</code> from which the <code>CertStore</code> will
+ * retrieve certificates and CRLs.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see java.util.Collection
+ * @see CertStore
+ **/
+public class CollectionCertStoreParameters implements CertStoreParameters
+{
+ private Collection collection;
+
+ /**
+ * Creates an instance of <code>CollectionCertStoreParameters</code>
+ * which will allow certificates and CRLs to be retrieved from the
+ * specified <code>Collection</code>. If the specified
+ * <code>Collection</code> contains an object that is not a
+ * <code>Certificate</code> or <code>CRL</code>, that object will be
+ * ignored by the Collection <code>CertStore</code>.<br />
+ * <br />
+ * The <code>Collection</code> is <b>not</b> copied. Instead, a
+ * reference is used. This allows the caller to subsequently add or
+ * remove <code>Certificates</code> or <code>CRL</code>s from the
+ * <code>Collection</code>, thus changing the set of
+ * <code>Certificates</code> or <code>CRL</code>s available to the
+ * Collection <code>CertStore</code>. The Collection <code>CertStore</code>
+ * will not modify the contents of the <code>Collection</code>.<br />
+ * <br />
+ * If the <code>Collection</code> will be modified by one thread while
+ * another thread is calling a method of a Collection <code>CertStore</code>
+ * that has been initialized with this <code>Collection</code>, the
+ * <code>Collection</code> must have fail-fast iterators.
+ *
+ * @param collection a <code>Collection</code> of
+ * <code>Certificate</code>s and <code>CRL</code>s
+ *
+ * @exception NullPointerException if <code>collection</code> is
+ * <code>null</code>
+ */
+ public CollectionCertStoreParameters(Collection collection)
+ {
+ if ( collection == null )
+ throw new NullPointerException("collection must be non-null");
+ this.collection = collection;
+ }
+
+ /**
+ * Creates an instance of <code>CollectionCertStoreParameters</code> with
+ * the an empty Collection.
+ */
+ public CollectionCertStoreParameters()
+ {
+ collection = new ArrayList();
+ }
+
+ /**
+ * Returns the <code>Collection</code> from which <code>Certificate</code>s
+ * and <code>CRL</code>s are retrieved. This is <b>not</b> a copy of the
+ * <code>Collection</code>, it is a reference. This allows the caller to
+ * subsequently add or remove <code>Certificates</code> or
+ * <code>CRL</code>s from the <code>Collection</code>.
+ *
+ * @return the <code>Collection</code> (never null)
+ */
+ public Collection getCollection()
+ {
+ return collection;
+ }
+
+ /**
+ * Returns a copy of this object. Note that only a reference to the
+ * <code>Collection</code> is copied, and not the contents.
+ *
+ * @return the copy
+ */
+ public Object clone()
+ {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ /* Cannot happen */
+ throw new InternalError(e.toString());
+ }
+ }
+
+ /**
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append("CollectionCertStoreParameters: [\n collections:\n");
+ s.append( getCollection());
+ s.append("\n]" );
+ return s.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/LDAPCertStoreParameters.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/LDAPCertStoreParameters.java
new file mode 100644
index 000000000..2e4669975
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/LDAPCertStoreParameters.java
@@ -0,0 +1,130 @@
+package java.security.cert;
+
+/**
+ * Parameters used as input for the LDAP <code>CertStore</code> algorithm.<br />
+ * <br />
+ * This class is used to provide necessary configuration parameters (server
+ * name and port number) to implementations of the LDAP <code>CertStore</code>
+ * algorithm.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertStore
+ **/
+public class LDAPCertStoreParameters implements CertStoreParameters
+{
+ private static final int LDAP_DEFAULT_PORT = 389;
+
+ /**
+ * the port number of the LDAP server
+ */
+ private String serverName;
+
+ /**
+ * the DNS name of the LDAP server
+ */
+ private int port;
+
+ /**
+ * Creates an instance of <code>LDAPCertStoreParameters</code> with the
+ * default parameter values (server name "localhost", port 389).
+ */
+ public LDAPCertStoreParameters()
+ {
+ this("localhost", LDAP_DEFAULT_PORT);
+ }
+
+ /**
+ * Creates an instance of <code>LDAPCertStoreParameters</code> with the
+ * specified server name and a default port of 389.
+ *
+ * @param serverName the DNS name of the LDAP server
+ *
+ * @exception NullPointerException if <code>serverName</code> is
+ * <code>null</code>
+ */
+ public LDAPCertStoreParameters(String serverName)
+ {
+ this(serverName, LDAP_DEFAULT_PORT);
+ }
+
+ /**
+ * Creates an instance of <code>LDAPCertStoreParameters</code> with the
+ * specified parameter values.
+ *
+ * @param serverName the DNS name of the LDAP server
+ * @param port the port number of the LDAP server
+ *
+ * @exception NullPointerException if <code>serverName</code> is
+ * <code>null</code>
+ */
+ public LDAPCertStoreParameters(String serverName, int port)
+ {
+ if (serverName == null)
+ throw new NullPointerException("serverName must be non-null");
+ this.serverName = serverName;
+ this.port = port;
+ }
+
+ /**
+ * Returns the DNS name of the LDAP server.
+ *
+ * @return the name (not <code>null</code>)
+ */
+ public String getServerName()
+ {
+ return serverName;
+ }
+
+ /**
+ * Returns the port number of the LDAP server.
+ *
+ * @return the port number
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns a copy of this object. Changes to the copy will not affect
+ * the original and vice versa.<br />
+ * <br />
+ * Note: this method currently performs a shallow copy of the object
+ * (simply calls <code>Object.clone()</code>). This may be changed in a
+ * future revision to perform a deep copy if new parameters are added
+ * that should not be shared.
+ *
+ * @return the copy
+ */
+ public Object clone()
+ {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ /* Cannot happen */
+ throw new InternalError(e.toString());
+ }
+ }
+
+ /**
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("LDAPCertStoreParameters: [\n");
+ sb.append(" serverName: ").append(serverName).append('\n');
+ sb.append(" port: ").append(port).append('\n');
+ sb.append(']');
+ return sb.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXBuilderParameters.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXBuilderParameters.java
new file mode 100644
index 000000000..b4f7aceb9
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXBuilderParameters.java
@@ -0,0 +1,179 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.util.Set;
+
+/**
+ * Parameters used as input for the PKIX <code>CertPathBuilder</code>
+ * algorithm.<br />
+ * <br />
+ * A PKIX <code>CertPathBuilder</code> uses these parameters to {@link
+ * CertPathBuilder#build build} a <code>CertPath</code> which has been
+ * validated according to the PKIX certification path validation algorithm.<br />
+ * <br />
+ * To instantiate a <code>PKIXBuilderParameters</code> object, an
+ * application must specify one or more <i>most-trusted CAs</i> as defined by
+ * the PKIX certification path validation algorithm. The most-trusted CA
+ * can be specified using one of two constructors. An application
+ * can call {@link #PKIXBuilderParameters(Set, CertSelector)
+ * PKIXBuilderParameters(Set, CertSelector)}, specifying a
+ * <code>Set</code> of <code>TrustAnchor</code> objects, each of which
+ * identifies a most-trusted CA. Alternatively, an application can call
+ * {@link #PKIXBuilderParameters(KeyStore, CertSelector)
+ * PKIXBuilderParameters(KeyStore, CertSelector)}, specifying a
+ * <code>KeyStore</code> instance containing trusted certificate entries, each
+ * of which will be considered as a most-trusted CA.<br />
+ * <br />
+ * In addition, an application must specify constraints on the target
+ * certificate that the <code>CertPathBuilder</code> will attempt
+ * to build a path to. The constraints are specified as a
+ * <code>CertSelector</code> object. These constraints should provide the
+ * <code>CertPathBuilder</code> with enough search criteria to find the target
+ * certificate. Minimal criteria for an <code>X509Certificate</code> usually
+ * include the subject name and/or one or more subject alternative names.
+ * If enough criteria is not specified, the <code>CertPathBuilder</code>
+ * may throw a <code>CertPathBuilderException</code>.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilder
+ **/
+public class PKIXBuilderParameters extends PKIXParameters
+{
+ private int maxPathLength = 5;
+
+ /**
+ * Creates an instance of <code>PKIXBuilderParameters</code> with
+ * the specified <code>Set</code> of most-trusted CAs.
+ * Each element of the set is a {@link TrustAnchor TrustAnchor}.<br />
+ * <br />
+ * Note that the <code>Set</code> is copied to protect against
+ * subsequent modifications.
+ *
+ * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
+ * @param targetConstraints a <code>CertSelector</code> specifying the
+ * constraints on the target certificate
+ *
+ * @exception InvalidAlgorithmParameterException if <code>trustAnchors</code>
+ * is empty <code>(trustAnchors.isEmpty() == true)</code>
+ * @exception NullPointerException if <code>trustAnchors</code> is
+ * <code>null</code>
+ * @exception ClassCastException if any of the elements of
+ * <code>trustAnchors</code> are not of type
+ * <code>java.security.cert.TrustAnchor</code>
+ */
+ public PKIXBuilderParameters(
+ Set trustAnchors,
+ CertSelector targetConstraints)
+ throws InvalidAlgorithmParameterException
+ {
+ super( trustAnchors );
+ setTargetCertConstraints( targetConstraints );
+ }
+
+ /**
+ * Creates an instance of <code>PKIXBuilderParameters</code> that
+ * populates the set of most-trusted CAs from the trusted
+ * certificate entries contained in the specified <code>KeyStore</code>.
+ * Only keystore entries that contain trusted <code>X509Certificate</code>s
+ * are considered; all other certificate types are ignored.
+ *
+ * @param keystore a <code>KeyStore</code> from which the set of
+ * most-trusted CAs will be populated
+ * @param targetConstraints a <code>CertSelector</code> specifying the
+ * constraints on the target certificate
+ *
+ * @exception KeyStoreException if <code>keystore</code> has not been
+ * initialized
+ * @exception InvalidAlgorithmParameterException if <code>keystore</code> does
+ * not contain at least one trusted certificate entry
+ * @exception NullPointerException if <code>keystore</code> is
+ * <code>null</code>
+ */
+ public PKIXBuilderParameters(KeyStore keystore,
+ CertSelector targetConstraints)
+ throws KeyStoreException,
+ InvalidAlgorithmParameterException
+ {
+ super( keystore );
+ setTargetCertConstraints( targetConstraints );
+ }
+
+ /**
+ * Sets the value of the maximum number of non-self-issued intermediate
+ * certificates that may exist in a certification path. A certificate
+ * is self-issued if the DNs that appear in the subject and issuer
+ * fields are identical and are not empty. Note that the last certificate
+ * in a certification path is not an intermediate certificate, and is not
+ * included in this limit. Usually the last certificate is an end entity
+ * certificate, but it can be a CA certificate. A PKIX
+ * <code>CertPathBuilder</code> instance must not build
+ * paths longer than the length specified.<br />
+ * <br />
+ * A value of 0 implies that the path can only contain
+ * a single certificate. A value of -1 implies that the
+ * path length is unconstrained (i.e. there is no maximum).
+ * The default maximum path length, if not specified, is 5.
+ * Setting a value less than -1 will cause an exception to be thrown.<br />
+ * <br />
+ * If any of the CA certificates contain the
+ * <code>BasicConstraintsExtension</code>, the value of the
+ * <code>pathLenConstraint</code> field of the extension overrides
+ * the maximum path length parameter whenever the result is a
+ * certification path of smaller length.
+ *
+ * @param maxPathLength the maximum number of non-self-issued intermediate
+ * certificates that may exist in a certification path
+ *
+ * @exception InvalidParameterException if <code>maxPathLength</code> is set
+ * to a value less than -1
+ *
+ * @see #getMaxPathLength
+ */
+ public void setMaxPathLength(int maxPathLength)
+ {
+ if ( maxPathLength < -1 )
+ throw new InvalidParameterException("the maximum path length parameter can not be less than -1");
+ this.maxPathLength = maxPathLength;
+ }
+
+ /**
+ * Returns the value of the maximum number of intermediate non-self-issued
+ * certificates that may exist in a certification path. See
+ * the {@link #setMaxPathLength} method for more details.
+ *
+ * @return the maximum number of non-self-issued intermediate certificates
+ * that may exist in a certification path, or -1 if there is no limit
+ *
+ * @see #setMaxPathLength
+ */
+ public int getMaxPathLength()
+ {
+ return maxPathLength;
+ }
+
+ /**
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append( "PKIXBuilderParameters [\n" );
+ s.append( super.toString() );
+ s.append( " Maximum Path Length: " );
+ s.append( getMaxPathLength() );
+ s.append( "\n]\n" );
+ return s.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathBuilderResult.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathBuilderResult.java
new file mode 100644
index 000000000..2ac791826
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathBuilderResult.java
@@ -0,0 +1,93 @@
+package java.security.cert;
+
+import java.security.PublicKey;
+
+/**
+ * This class represents the successful result of the PKIX certification
+ * path builder algorithm. All certification paths that are built and
+ * returned using this algorithm are also validated according to the PKIX
+ * certification path validation algorithm.<br />
+ * <br />
+ * Instances of <code>PKIXCertPathBuilderResult</code> are returned by
+ * the <code>build</code> method of <code>CertPathBuilder</code>
+ * objects implementing the PKIX algorithm.<br />
+ * <br />
+ * All <code>PKIXCertPathBuilderResult</code> objects contain the
+ * certification path constructed by the build algorithm, the
+ * valid policy tree and subject public key resulting from the build
+ * algorithm, and a <code>TrustAnchor</code> describing the certification
+ * authority (CA) that served as a trust anchor for the certification path.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathBuilderResult
+ *
+ **/
+public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult
+ implements CertPathBuilderResult
+{
+ private CertPath certPath;
+
+ /**
+ * Creates an instance of <code>PKIXCertPathBuilderResult</code>
+ * containing the specified parameters.
+ *
+ * @param certPath the validated <code>CertPath</code>
+ * @param trustAnchor a <code>TrustAnchor</code> describing the CA that
+ * served as a trust anchor for the certification path
+ * @param policyTree the immutable valid policy tree, or <code>null</code>
+ * if there are no valid policies
+ * @param subjectPublicKey the public key of the subject
+ *
+ * @exception NullPointerException if the <code>certPath</code>,
+ * <code>trustAnchor</code> or <code>subjectPublicKey</code> parameters
+ * are <code>null</code>
+ */
+ public PKIXCertPathBuilderResult(CertPath certPath, TrustAnchor trustAnchor,
+ PolicyNode policyTree, PublicKey subjectPublicKey)
+ {
+ super(trustAnchor, policyTree, subjectPublicKey);
+ if ( certPath == null )
+ throw new NullPointerException( "certPath must be non-null" );
+ this.certPath = certPath;
+ }
+
+ /**
+ * Returns the built and validated certification path. The
+ * <code>CertPath</code> object does not include the trust anchor.
+ * Instead, use the {@link #getTrustAnchor() getTrustAnchor()} method to
+ * obtain the <code>TrustAnchor</code> that served as the trust anchor
+ * for the certification path.
+ *
+ * @return the built and validated <code>CertPath</code> (never
+ * <code>null</code>)
+ */
+ public CertPath getCertPath()
+ {
+ return certPath;
+ }
+
+ /**
+ * Return a printable representation of this
+ * <code>PKIXCertPathBuilderResult</code>.
+ *
+ * @return a <code>String</code> describing the contents of this
+ * <code>PKIXCertPathBuilderResult</code>
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append( "PKIXCertPathBuilderResult: [\n" );
+ s.append( " Certification Path: ").append(getCertPath()).append('\n' );
+ s.append( " Trust Anchor: ").append(getTrustAnchor()).append('\n' );
+ s.append( " Policy Tree: ").append(getPolicyTree()).append('\n' );
+ s.append( " Subject Public Key: ").append(getPublicKey()).append("\n]");
+ return s.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathChecker.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathChecker.java
new file mode 100644
index 000000000..14dec8060
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathChecker.java
@@ -0,0 +1,155 @@
+package java.security.cert;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * An abstract class that performs one or more checks on an
+ * <code>X509Certificate</code>. <br />
+ * <br />
+ * A concrete implementation of the <code>PKIXCertPathChecker</code> class
+ * can be created to extend the PKIX certification path validation algorithm.
+ * For example, an implementation may check for and process a critical private
+ * extension of each certificate in a certification path.<br />
+ * <br />
+ * Instances of <code>PKIXCertPathChecker</code> are passed as parameters
+ * using the {@link PKIXParameters#setCertPathCheckers setCertPathCheckers}
+ * or {@link PKIXParameters#addCertPathChecker addCertPathChecker} methods
+ * of the <code>PKIXParameters</code> and <code>PKIXBuilderParameters</code>
+ * class. Each of the <code>PKIXCertPathChecker</code>s {@link #check check}
+ * methods will be called, in turn, for each certificate processed by a PKIX
+ * <code>CertPathValidator</code> or <code>CertPathBuilder</code>
+ * implementation.<br />
+ * <br />
+ * A <code>PKIXCertPathChecker</code> may be called multiple times on
+ * successive certificates in a certification path. Concrete subclasses
+ * are expected to maintain any internal state that may be necessary to
+ * check successive certificates. The {@link #init init} method is used
+ * to initialize the internal state of the checker so that the certificates
+ * of a new certification path may be checked. A stateful implementation
+ * <b>must</b> override the {@link #clone clone} method if necessary in
+ * order to allow a PKIX <code>CertPathBuilder</code> to efficiently
+ * backtrack and try other paths. In these situations, the
+ * <code>CertPathBuilder</code> is able to restore prior path validation
+ * states by restoring the cloned <code>PKIXCertPathChecker</code>s.<br />
+ * <br />
+ * The order in which the certificates are presented to the
+ * <code>PKIXCertPathChecker</code> may be either in the forward direction
+ * (from target to most-trusted CA) or in the reverse direction (from
+ * most-trusted CA to target). A <code>PKIXCertPathChecker</code> implementation
+ * <b>must</b> support reverse checking (the ability to perform its checks when
+ * it is presented with certificates in the reverse direction) and <b>may</b>
+ * support forward checking (the ability to perform its checks when it is
+ * presented with certificates in the forward direction). The
+ * {@link #isForwardCheckingSupported isForwardCheckingSupported} method
+ * indicates whether forward checking is supported.<br />
+ * <br />
+ * Additional input parameters required for executing the check may be
+ * specified through constructors of concrete implementations of this class.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see PKIXParameters
+ * @see PKIXBuilderParameters
+ **/
+public abstract class PKIXCertPathChecker implements Cloneable
+{
+
+ /**
+ * Default constructor.
+ */
+ protected PKIXCertPathChecker() {}
+
+ /**
+ * Initializes the internal state of this <code>PKIXCertPathChecker</code>.
+ * <p>
+ * The <code>forward</code> flag specifies the order that
+ * certificates will be passed to the {@link #check check} method
+ * (forward or reverse). A <code>PKIXCertPathChecker</code> <b>must</b>
+ * support reverse checking and <b>may</b> support forward checking.
+ *
+ * @param forward the order that certificates are presented to
+ * the <code>check</code> method. If <code>true</code>, certificates
+ * are presented from target to most-trusted CA (forward); if
+ * <code>false</code>, from most-trusted CA to target (reverse).
+ * @exception CertPathValidatorException if this
+ * <code>PKIXCertPathChecker</code> is unable to check certificates in
+ * the specified order; it should never be thrown if the forward flag
+ * is false since reverse checking must be supported
+ */
+ public abstract void init(boolean forward)
+ throws CertPathValidatorException;
+
+ /**
+ * Indicates if forward checking is supported. Forward checking refers
+ * to the ability of the <code>PKIXCertPathChecker</code> to perform
+ * its checks when certificates are presented to the <code>check</code>
+ * method in the forward direction (from target to most-trusted CA).
+ *
+ * @return <code>true</code> if forward checking is supported,
+ * <code>false</code> otherwise
+ */
+ public abstract boolean isForwardCheckingSupported();
+
+ /**
+ * Returns an immutable <code>Set</code> of X.509 certificate extensions
+ * that this <code>PKIXCertPathChecker</code> supports (i.e. recognizes, is
+ * able to process), or <code>null</code> if no extensions are supported.
+ * <p>
+ * Each element of the set is a <code>String</code> representing the
+ * Object Identifier (OID) of the X.509 extension that is supported.
+ * The OID is represented by a set of nonnegative integers separated by
+ * periods.
+ * <p>
+ * All X.509 certificate extensions that a <code>PKIXCertPathChecker</code>
+ * might possibly be able to process should be included in the set.
+ *
+ * @return an immutable <code>Set</code> of X.509 extension OIDs (in
+ * <code>String</code> format) supported by this
+ * <code>PKIXCertPathChecker</code>, or <code>null</code> if no
+ * extensions are supported
+ */
+ public abstract Set getSupportedExtensions();
+
+ /**
+ * Performs the check(s) on the specified certificate using its internal
+ * state and removes any critical extensions that it processes from the
+ * specified collection of OID strings that represent the unresolved
+ * critical extensions. The certificates are presented in the order
+ * specified by the <code>init</code> method.
+ *
+ * @param cert the <code>Certificate</code> to be checked
+ * @param unresolvedCritExts a <code>Collection</code> of OID strings
+ * representing the current set of unresolved critical extensions
+ * @exception CertPathValidatorException if the specified certificate does
+ * not pass the check
+ */
+ public abstract void check(
+ Certificate cert,
+ Collection unresolvedCritExts)
+ throws CertPathValidatorException;
+
+ /**
+ * Returns a clone of this object. Calls the <code>Object.clone()</code>
+ * method.
+ * All subclasses which maintain state must support and
+ * override this method, if necessary.
+ *
+ * @return a copy of this <code>PKIXCertPathChecker</code>
+ */
+ public Object clone()
+ {
+ try {
+ return super.clone();
+ } catch ( CloneNotSupportedException ex ) {
+ /* Cannot happen */
+ throw new InternalError( ex.toString() );
+ }
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathValidatorResult.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathValidatorResult.java
new file mode 100644
index 000000000..8ffa25555
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXCertPathValidatorResult.java
@@ -0,0 +1,136 @@
+package java.security.cert;
+
+import java.security.PublicKey;
+
+/**
+ * This class represents the successful result of the PKIX certification
+ * path validation algorithm. <br />
+ * <br />
+ * Instances of <code>PKIXCertPathValidatorResult</code> are returned by the
+ * {@link CertPathValidator#validate validate} method of
+ * <code>CertPathValidator</code> objects implementing the PKIX algorithm.<br />
+ * <br />
+ * All <code>PKIXCertPathValidatorResult</code> objects contain the
+ * valid policy tree and subject public key resulting from the
+ * validation algorithm, as well as a <code>TrustAnchor</code> describing
+ * the certification authority (CA) that served as a trust anchor for the
+ * certification path.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathValidatorResult
+ **/
+public class PKIXCertPathValidatorResult implements CertPathValidatorResult
+{
+ private TrustAnchor trustAnchor;
+ private PolicyNode policyTree;
+ private PublicKey subjectPublicKey;
+
+ /**
+ * Creates an instance of <code>PKIXCertPathValidatorResult</code>
+ * containing the specified parameters.
+ *
+ * @param trustAnchor a <code>TrustAnchor</code> describing the CA that
+ * served as a trust anchor for the certification path
+ * @param policyTree the immutable valid policy tree, or <code>null</code>
+ * if there are no valid policies
+ * @param subjectPublicKey the public key of the subject
+ *
+ * @exception NullPointerException if the <code>subjectPublicKey</code> or
+ * <code>trustAnchor</code> parameters are <code>null</code>
+ */
+ public PKIXCertPathValidatorResult(TrustAnchor trustAnchor,
+ PolicyNode policyTree,
+ PublicKey subjectPublicKey)
+ {
+ if ( subjectPublicKey == null )
+ throw new NullPointerException( "subjectPublicKey must be non-null" );
+ if ( trustAnchor == null )
+ throw new NullPointerException( "trustAnchor must be non-null" );
+
+ this.trustAnchor = trustAnchor;
+ this.policyTree = policyTree;
+ this.subjectPublicKey = subjectPublicKey;
+ }
+
+ /**
+ * Returns the <code>TrustAnchor</code> describing the CA that served
+ * as a trust anchor for the certification path.
+ *
+ * @return the <code>TrustAnchor</code> (never <code>null</code>)
+ */
+ public TrustAnchor getTrustAnchor()
+ {
+ return trustAnchor;
+ }
+
+ /**
+ * Returns the root node of the valid policy tree resulting from the
+ * PKIX certification path validation algorithm. The
+ * <code>PolicyNode</code> object that is returned and any objects that
+ * it returns through public methods are immutable.<br />
+ * <br />
+ * Most applications will not need to examine the valid policy tree.
+ * They can achieve their policy processing goals by setting the
+ * policy-related parameters in <code>PKIXParameters</code>. However, more
+ * sophisticated applications, especially those that process policy
+ * qualifiers, may need to traverse the valid policy tree using the
+ * {@link PolicyNode#getParent PolicyNode.getParent} and
+ * {@link PolicyNode#getChildren PolicyNode.getChildren} methods.
+ *
+ * @return the root node of the valid policy tree, or <code>null</code>
+ * if there are no valid policies
+ */
+ public PolicyNode getPolicyTree()
+ {
+ return policyTree;
+ }
+
+ /**
+ * Returns the public key of the subject (target) of the certification
+ * path, including any inherited public key parameters if applicable.
+ *
+ * @return the public key of the subject (never <code>null</code>)
+ */
+ public PublicKey getPublicKey()
+ {
+ return subjectPublicKey;
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return the copy
+ */
+ public Object clone()
+ {
+ try {
+ return super.clone();
+ } catch ( CloneNotSupportedException ex ) {
+ throw new InternalError( ex.toString() );
+ }
+ }
+
+ /**
+ * Return a printable representation of this
+ * <code>PKIXCertPathValidatorResult</code>.
+ *
+ * @return a <code>String</code> describing the contents of this
+ * <code>PKIXCertPathValidatorResult</code>
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append( "PKIXCertPathValidatorResult: [ \n" );
+ s.append( " Trust Anchor: ").append(getTrustAnchor()).append('\n' );
+ s.append( " Policy Tree: ").append(getPolicyTree()).append('\n' );
+ s.append( " Subject Public Key: ").append(getPublicKey()).append("\n]" );
+ return s.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXParameters.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXParameters.java
new file mode 100644
index 000000000..3c55d7e49
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PKIXParameters.java
@@ -0,0 +1,770 @@
+package java.security.cert;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Parameters used as input for the PKIX CertPathValidator algorithm.<br />
+ * <br />
+ * A PKIX <code>CertPathValidator</code> uses these parameters to validate a
+ * <code>CertPath</code> according to the PKIX certification path validation
+ * algorithm.<br />
+ * <br />
+ * To instantiate a <code>PKIXParameters</code> object, an application must specify
+ * one or more <i>most-trusted CAs</i> as defined by the PKIX certification
+ * path validation algorithm. The most-trusted CAs can be specified
+ * using one of two constructors. An application can call
+ * {@link #PKIXParameters(Set)}, specifying a Set of <code>TrustAnchor</code> objects, each
+ * of which identify a most-trusted CA. Alternatively, an application
+ * can call {@link #PKIXParameters(KeyStore)}, specifying a <code>KeyStore</code> instance
+ * containing trusted certificate entries, each of which will be
+ * considered as a most-trusted CA.<br />
+ * <br />
+ * Once a <code>PKIXParameters</code> object has been created, other parameters can
+ * be specified (by calling {@link #setInitialPolicies} or {@link #setDate}, for
+ * instance) and then the <code>PKIXParameters</code> is passed along with the
+ * <code>CertPath</code> to be validated to {@link CertPathValidator#validate}.<br />
+ * <br />
+ * Any parameter that is not set (or is set to null) will be set to the
+ * default value for that parameter. The default value for the date
+ * parameter is null, which indicates the current time when the path is
+ * validated. The default for the remaining parameters is the least
+ * constrained.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are
+ * not thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.
+ *
+ * @see CertPathValidator
+ **/
+public class PKIXParameters implements CertPathParameters {
+ private Set trustAnchors;
+ private Set initialPolicies = new HashSet();
+ private List certStores = new ArrayList();
+ private CertSelector certSelector;
+ private List certPathCheckers = new ArrayList();
+ private boolean revocationEnabled = true;
+ private boolean explicitPolicyRequired = false;
+ private boolean policyMappingInhibited = false;
+ private boolean anyPolicyInhibited = false;
+ private boolean policyQualifiersRejected = true;
+ private Date date;
+ private String sigProvider;
+
+ /**
+ * Creates an instance of PKIXParameters with the specified
+ * Set of most-trusted CAs. Each element of the set is a
+ * TrustAnchor.<br />
+ * <br />
+ * Note that the Set is copied to protect against subsequent
+ * modifications.
+ *
+ * @param trustAnchors a Set of TrustAnchors
+ *
+ * @exception InvalidAlgorithmParameterException if the
+ * specified Set is empty <code>(trustAnchors.isEmpty() == true)</code>
+ * @exception NullPointerException if the specified Set is <code>null</code>
+ * @exception ClassCastException if any of the elements in the
+ * Set are not of type
+ * <code>java.security.cert.TrustAnchor</code>
+ **/
+ public PKIXParameters(Set trustAnchors)
+ throws InvalidAlgorithmParameterException
+ {
+ setTrustAnchors( trustAnchors );
+ }
+
+ /**
+ * Creates an instance of PKIXParameters that populates the
+ * set of most-trusted CAs from the trusted certificate
+ * entries contained in the specified KeyStore. Only keystore
+ * entries that contain trusted X509Certificates are
+ * considered; all other certificate types are ignored.
+ *
+ * @param keystore a KeyStore from which the set of
+ * most-trusted CAs will be populated
+ *
+ * @exception KeyStoreException if the keystore has not been
+ * initialized
+ * @exception InvalidAlgorithmParameterException if the keystore
+ * does not contain at least one trusted certificate entry
+ * @exception NullPointerException if the keystore is null
+ **/
+ public PKIXParameters(KeyStore keystore)
+ throws KeyStoreException,
+ InvalidAlgorithmParameterException
+ {
+ if ( keystore == null )
+ throw new NullPointerException( "the keystore parameter must be non-null" );
+
+ Set trustAnchors = new HashSet();
+ String alias;
+ Certificate cert;
+ Enumeration enum = keystore.aliases();
+ while ( enum.hasMoreElements() ) {
+ alias = (String)enum.nextElement();
+ if ( keystore.isCertificateEntry( alias ) ) {
+ cert = keystore.getCertificate( alias );
+ if ( cert instanceof X509Certificate )
+ trustAnchors.add( new TrustAnchor( (X509Certificate)cert, null ) );
+ }
+ }
+ setTrustAnchors( trustAnchors );
+ }
+
+ /**
+ * Returns an immutable Set of the most-trusted CAs.
+ *
+ * @return an immutable <code>Set</code> of
+ * <code>TrustAnchors</code> (never <code>null</code>)
+ *
+ * @see #setTrustAnchors
+ **/
+ public Set getTrustAnchors()
+ {
+ return Collections.unmodifiableSet(trustAnchors);
+ }
+
+ /**
+ * Sets the Set of most-trusted CAs.<br />
+ * <br />
+ * Note that the Set is copied to protect against subsequent
+ * modifications.<br />
+ * <br />
+ * @param trustAnchors a Set of TrustAnchors
+ *
+ * @exception InvalidAlgorithmParameterException if the specified Set is empty <code>(trustAnchors.isEmpty() == true)</code>
+ * @exception NullPointerException if the specified Set is <code>null</code>
+ * @exception ClassCastException if any of the elements in
+ * the set are not of type java.security.cert.TrustAnchor
+ *
+ * @see #getTrustAnchors
+ **/
+ public void setTrustAnchors(Set trustAnchors)
+ throws InvalidAlgorithmParameterException
+ {
+ if ( trustAnchors == null )
+ throw new NullPointerException("the trustAnchors parameter must be non-null");
+ if ( trustAnchors.isEmpty() )
+ throw new InvalidAlgorithmParameterException("the trustAnchors parameter must be non-empty");
+
+ Iterator iter = trustAnchors.iterator();
+ TrustAnchor obj;
+ this.trustAnchors = new HashSet();
+ while( iter.hasNext() ) {
+ obj = (TrustAnchor)iter.next();
+ if ( obj != null ) {
+ this .trustAnchors.add( obj );
+ }
+ }
+ }
+
+ /**
+ * Returns an immutable Set of initial policy identifiers (OID
+ * strings), indicating that any one of these policies would
+ * be acceptable to the certificate user for the purposes of
+ * certification path processing. The default return value is
+ * an empty <code>Set</code>, which is interpreted as meaning that any
+ * policy would be acceptable.
+ *
+ * @return an immutable <code>Set</code> of initial policy
+ * OIDs in String format, or an empty <code>Set</code> (implying any policy
+ * is acceptable). Never returns <code>null</code>.
+ *
+ * @see #setInitialPolicies(java.util.Set)
+ **/
+ public Set getInitialPolicies()
+ {
+ Set returnSet = initialPolicies;
+ if ( initialPolicies == null )
+ returnSet = new HashSet();
+
+ return Collections.unmodifiableSet( returnSet );
+ }
+
+ /**
+ * Sets the <code>Set</code> of initial policy identifiers (OID strings),
+ * indicating that any one of these policies would be
+ * acceptable to the certificate user for the purposes of
+ * certification path processing. By default, any policy is
+ * acceptable (i.e. all policies), so a user that wants to
+ * allow any policy as acceptable does not need to call this
+ * method, or can call it with an empty <code>Set</code> (or <code>null</code>).<br />
+ * <br />
+ * Note that the Set is copied to protect against subsequent
+ * modifications.<br />
+ * <br />
+ * @param initialPolicies a Set of initial policy OIDs in String format (or <code>null</code>)
+ *
+ * @exception ClassCastException if any of the elements in the
+ * set are not of type String
+ *
+ * @see #getInitialPolicies()
+ **/
+ public void setInitialPolicies(Set initialPolicies)
+ {
+ if ( initialPolicies == null || initialPolicies.isEmpty() )
+ {
+ this.initialPolicies = null;
+ }
+ else
+ {
+ Iterator iter = initialPolicies.iterator();
+ this.initialPolicies = new HashSet();
+ String obj;
+ while ( iter.hasNext() )
+ {
+ obj = (String)iter.next();
+ if ( obj != null ) {
+ this.initialPolicies.add( obj );
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the list of CertStores to be used in finding
+ * certificates and CRLs. May be null, in which case no
+ * CertStores will be used. The first CertStores in the list
+ * may be preferred to those that appear later.<br />
+ * <br />
+ * Note that the List is copied to protect against subsequent
+ * modifications.<br />
+ * <br />
+ * @param stores a List of CertStores (or <code>null</code>)
+ *
+ * @exception ClassCastException if any of the elements in the
+ * list are not of type <code>java.security.cert.CertStore</code>
+ *
+ * @see #getCertStores()
+ **/
+ public void setCertStores(List stores)
+ {
+ certStores = new ArrayList();
+ if ( stores != null && ! stores.isEmpty() )
+ {
+ Iterator iter = stores.iterator();
+ CertStore obj;
+ while ( iter.hasNext() )
+ {
+ obj = (CertStore)iter.next();
+ if ( obj != null )
+ {
+ certStores.add( obj );
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds a CertStore to the end of the list of CertStores used
+ * in finding certificates and CRLs.
+ *
+ * @param store the <code>CertStore</code> to add. If
+ * <code>null</code<, the store is ignored (not added to
+ * list).
+ **/
+ public void addCertStore(CertStore store)
+ {
+ if ( store != null )
+ certStores.add( store );
+ }
+
+ /**
+ * Returns an immutable List of CertStores that are used to
+ * find certificates and CRLs.
+ *
+ * @return an immutable List of CertStores (may be empty, but never <code>null</code>)
+ *
+ * @see #setCertStores(java.util.List)
+ **/
+ public List getCertStores()
+ {
+ return Collections.unmodifiableList(certStores);
+ }
+
+ /**
+ * Sets the RevocationEnabled flag. If this flag is true, the default
+ * revocation checking mechanism of the underlying PKIX service provider
+ * will be used. If this flag is false, the default revocation checking
+ * mechanism will be disabled (not used).<br />
+ * <br />
+ * When a <code>PKIXParameters</code> object is created, this flag is set
+ * to true. This setting reflects the most common strategy for checking
+ * revocation, since each service provider must support revocation
+ * checking to be PKIX compliant. Sophisticated applications should set
+ * this flag to false when it is not practical to use a PKIX service
+ * provider's default revocation checking mechanism or when an alternative
+ * revocation checking mechanism is to be substituted (by also calling the
+ * {@link #addCertPathChecker addCertPathChecker} or {@link
+ * #setCertPathCheckers setCertPathCheckers} methods).
+ *
+ * @param val the new value of the RevocationEnabled flag
+ **/
+ public void setRevocationEnabled(boolean val)
+ {
+ revocationEnabled = val;
+ }
+
+ /**
+ * Checks the RevocationEnabled flag. If this flag is true,
+ * the default revocation checking mechanism of the underlying
+ * PKIX service provider will be used. If this flag is false,
+ * the default revocation checking mechanism will be disabled
+ * (not used). See the setRevocationEnabled method for more
+ * details on setting the value of this flag.
+ *
+ * @return the current value of the RevocationEnabled flag
+ **/
+ public boolean isRevocationEnabled()
+ {
+ return revocationEnabled;
+ }
+
+ /**
+ * Sets the ExplicitPolicyRequired flag. If this flag is true,
+ * an acceptable policy needs to be explicitly identified in
+ * every certificate. By default, the ExplicitPolicyRequired
+ * flag is false.
+ *
+ * @param val true if explicit policy is to be required, false
+ * otherwise
+ **/
+ public void setExplicitPolicyRequired(boolean val)
+ {
+ explicitPolicyRequired = val;
+ }
+
+ /**
+ * Checks if explicit policy is required. If this flag is
+ * true, an acceptable policy needs to be explicitly
+ * identified in every certificate. By default, the
+ * ExplicitPolicyRequired flag is false.
+ *
+ * @return true if explicit policy is required, false otherwise
+ **/
+ public boolean isExplicitPolicyRequired()
+ {
+ return explicitPolicyRequired;
+ }
+
+ /**
+ * Sets the PolicyMappingInhibited flag. If this flag is true,
+ * policy mapping is inhibited. By default, policy mapping is
+ * not inhibited (the flag is false).
+ *
+ * @param val true if policy mapping is to be inhibited, false otherwise
+ **/
+ public void setPolicyMappingInhibited(boolean val)
+ {
+ policyMappingInhibited = val;
+ }
+
+ /**
+ * Checks if policy mapping is inhibited. If this flag is
+ * true, policy mapping is inhibited. By default, policy
+ * mapping is not inhibited (the flag is false).
+ *
+ * @return true if policy mapping is inhibited, false otherwise
+ **/
+ public boolean isPolicyMappingInhibited()
+ {
+ return policyMappingInhibited;
+ }
+
+ /**
+ * Sets state to determine if the any policy OID should be
+ * processed if it is included in a certificate. By default,
+ * the any policy OID is not inhibited ({@link #isAnyPolicyInhibited()}
+ * returns false).
+ *
+ * @return val - <code>true</code> if the any policy OID is to be inhibited, <code>false</code> otherwise
+ **/
+ public void setAnyPolicyInhibited(boolean val)
+ {
+ anyPolicyInhibited = val;
+ }
+
+ /**
+ * Checks whether the any policy OID should be processed if it
+ * is included in a certificate.
+ *
+ * @return <code>true</code> if the any policy OID is inhibited, <code>false</code> otherwise
+ **/
+ public boolean isAnyPolicyInhibited()
+ {
+ return anyPolicyInhibited;
+ }
+
+ /**
+ * Sets the PolicyQualifiersRejected flag. If this flag is
+ * true, certificates that include policy qualifiers in a
+ * certificate policies extension that is marked critical are
+ * rejected. If the flag is false, certificates are not
+ * rejected on this basis.<br />
+ * <br />
+ * When a <code>PKIXParameters</code> object is created, this flag is set
+ * to true. This setting reflects the most common (and
+ * simplest) strategy for processing policy
+ * qualifiers. Applications that want to use a more
+ * sophisticated policy must set this flag to false.<br />
+ * <br />
+ * Note that the PKIX certification path validation algorithm
+ * specifies that any policy qualifier in a certificate
+ * policies extension that is marked critical must be
+ * processed and validated. Otherwise the certification path
+ * must be rejected. If the policyQualifiersRejected flag is
+ * set to false, it is up to the application to validate all
+ * policy qualifiers in this manner in order to be PKIX
+ * compliant.
+ *
+ * @param qualifiersRejected the new value of the PolicyQualifiersRejected flag
+ *
+ * @see #getPolicyQualifiersRejected()
+ * @see PolicyQualifierInfo
+ **/
+ public void setPolicyQualifiersRejected(boolean qualifiersRejected)
+ {
+ policyQualifiersRejected = qualifiersRejected;
+ }
+
+ /**
+ * Gets the PolicyQualifiersRejected flag. If this flag is
+ * true, certificates that include policy qualifiers in a
+ * certificate policies extension that is marked critical are
+ * rejected. If the flag is false, certificates are not
+ * rejected on this basis.<br />
+ * <br />
+ * When a PKIXParameters object is created, this flag is set to
+ * true. This setting reflects the most common (and simplest)
+ * strategy for processing policy qualifiers. Applications that
+ * want to use a more sophisticated policy must set this flag
+ * to false.
+ *
+ * @return the current value of the PolicyQualifiersRejected flag
+ *
+ * @see #setPolicyQualifiersRejected(boolean)
+ **/
+ public boolean getPolicyQualifiersRejected()
+ {
+ return policyQualifiersRejected;
+ }
+
+ /**
+ * Returns the time for which the validity of the
+ * certification path should be determined. If null, the
+ * current time is used.<br />
+ * <br />
+ * Note that the Date returned is copied to protect against
+ * subsequent modifications.
+ *
+ * @return the Date, or <code>null</code> if not set
+ *
+ * @see #setDate(java.util.Date)
+ **/
+ public Date getDate()
+ {
+ if ( date == null )
+ return null;
+
+ return new Date( date.getTime() );
+ }
+
+ /**
+ * Sets the time for which the validity of the certification
+ * path should be determined. If null, the current time is
+ * used.<br />
+ * <br />
+ * Note that the Date supplied here is copied to protect
+ * against subsequent modifications.
+ *
+ * @param date the Date, or <code>null</code> for the current time
+ *
+ * @see #getDate()
+ **/
+ public void setDate(Date date)
+ {
+ if ( date == null )
+ this.date = null;
+ else
+ this.date = new Date( date.getTime() );
+ }
+
+ /**
+ * Sets a <code>List</code> of additional certification path checkers. If
+ * the specified List contains an object that is not a
+ * PKIXCertPathChecker, it is ignored.<br />
+ * <br />
+ * Each <code>PKIXCertPathChecker</code> specified implements additional
+ * checks on a certificate. Typically, these are checks to
+ * process and verify private extensions contained in
+ * certificates. Each <code>PKIXCertPathChecker</code> should be
+ * instantiated with any initialization parameters needed to
+ * execute the check.<br />
+ * <br />
+ * This method allows sophisticated applications to extend a
+ * PKIX <code>CertPathValidator</code> or <code>CertPathBuilder</code>. Each of the
+ * specified PKIXCertPathCheckers will be called, in turn, by
+ * a PKIX <code>CertPathValidator</code> or <code>CertPathBuilder</code> for each
+ * certificate processed or validated.<br />
+ * <br />
+ * Regardless of whether these additional PKIXCertPathCheckers
+ * are set, a PKIX <code>CertPathValidator</code> or <code>CertPathBuilder</code> must
+ * perform all of the required PKIX checks on each
+ * certificate. The one exception to this rule is if the
+ * RevocationEnabled flag is set to false (see the
+ * {@link #setRevocationEnabled(boolean) setRevocationEnabled} method).<br />
+ * <br />
+ * Note that the List supplied here is copied and each
+ * PKIXCertPathChecker in the list is cloned to protect against
+ * subsequent modifications.
+ *
+ * @param checkers a List of PKIXCertPathCheckers. May be
+ * null, in which case no additional checkers will be used.
+ * @exception ClassCastException if any of the elements in the
+ * list are not of type
+ * <code>java.security.cert.PKIXCertPathChecker</code>
+ * @see #getCertPathCheckers()
+ **/
+ public void setCertPathCheckers(List checkers)
+ {
+ certPathCheckers = new ArrayList();
+ if ( checkers == null )
+ return;
+ Iterator iter = checkers.iterator();
+ while ( iter.hasNext() )
+ certPathCheckers.add( (PKIXCertPathChecker)((PKIXCertPathChecker)iter.next()).clone() );
+ }
+
+ /**
+ * Returns the List of certification path checkers. The
+ * returned List is immutable, and each PKIXCertPathChecker in
+ * the List is cloned to protect against subsequent
+ * modifications.
+ *
+ * @return an immutable List of PKIXCertPathCheckers (may be empty, but not <code>null</code>)
+ *
+ * @see #setCertPathCheckers(java.util.List)
+ **/
+ public List getCertPathCheckers()
+ {
+ List checkers = new ArrayList();
+ Iterator iter = certPathCheckers.iterator();
+ while ( iter.hasNext() )
+ {
+ checkers.add( (PKIXCertPathChecker)((PKIXCertPathChecker)iter.next()).clone() );
+ }
+ return Collections.unmodifiableList(checkers);
+ }
+
+ /**
+ * Adds a PKIXCertPathChecker to the list of certification
+ * path checkers. See the {@link #setCertPathCheckers} method for more
+ * details.<br />
+ * <br />
+ * Note that the <code>PKIXCertPathChecker</code> is cloned to protect
+ * against subsequent modifications.
+ *
+ * @param checker a <code>PKIXCertPathChecker</code> to add
+ * to the list of checks. If <code>null</code>, the checker is
+ * ignored (not added to list).
+ **/
+ public void addCertPathChecker( PKIXCertPathChecker checker )
+ {
+ if ( checker != null )
+ {
+ certPathCheckers.add( checker.clone() );
+ }
+ }
+
+ /**
+ * Returns the signature provider's name, or <code>null</code> if not set.
+ *
+ * @return the signature provider's name (or <code>null</code>)
+ *
+ * @see #setSigProvider(java.lang.String)
+ **/
+ public String getSigProvider()
+ {
+ return sigProvider;
+ }
+
+ /**
+ * Sets the signature provider's name. The specified provider
+ * will be preferred when creating Signature objects. If null
+ * or not set, the first provider found supporting the
+ * algorithm will be used.
+ *
+ * @param sigProvider the signature provider's name (or <code>null</code>)
+ *
+ * @see #getSigProvider()
+ **/
+ public void setSigProvider(String sigProvider)
+ {
+ this.sigProvider = sigProvider;
+ }
+
+ /**
+ * Returns the required constraints on the target
+ * certificate. The constraints are returned as an instance of
+ * CertSelector. If <code>null</code>, no constraints are defined.<br />
+ * <br />
+ * Note that the CertSelector returned is cloned to protect
+ * against subsequent modifications.
+ *
+ * @return a CertSelector specifying the constraints on the target certificate (or <code>null</code>)
+ *
+ * @see #setTargetCertConstraints(java.security.cert.CertSelector)
+ **/
+ public CertSelector getTargetCertConstraints()
+ {
+ if ( certSelector == null )
+ return null;
+
+ return (CertSelector)certSelector.clone();
+ }
+
+ /**
+ * Sets the required constraints on the target
+ * certificate. The constraints are specified as an instance
+ * of CertSelector. If null, no constraints are defined.<br />
+ * <br />
+ * Note that the CertSelector specified is cloned to protect
+ * against subsequent modifications.
+ *
+ * @param selector a CertSelector specifying the constraints
+ * on the target certificate (or <code>null</code>)
+ *
+ * @see #getTargetCertConstraints()
+ **/
+ public void setTargetCertConstraints(CertSelector selector)
+ {
+ if ( selector == null )
+ certSelector = null;
+ else
+ certSelector = (CertSelector)selector.clone();
+ }
+
+ /**
+ * Makes a copy of this PKIXParameters object. Changes to the
+ * copy will not affect the original and vice versa.
+ *
+ * @return a copy of this <code>PKIXParameters</code> object
+ **/
+ public Object clone()
+ {
+ try {
+ PKIXParameters obj = (PKIXParameters)super.clone();
+ obj.certStores = new ArrayList( certStores );
+ Iterator iter = certPathCheckers.iterator();
+ obj.certPathCheckers = new ArrayList();
+ while ( iter.hasNext() )
+ {
+ obj.certPathCheckers.add( ((PKIXCertPathChecker)iter.next()).clone() );
+ }
+ if ( initialPolicies != null )
+ {
+ obj.initialPolicies = new HashSet( initialPolicies );
+ }
+ if ( trustAnchors != null )
+ {
+ obj.trustAnchors = new HashSet( trustAnchors );
+ }
+ if ( certSelector != null )
+ {
+ obj.certSelector = (CertSelector)certSelector.clone();
+ }
+ return obj;
+ } catch ( CloneNotSupportedException ex ) {
+ throw new InternalError();
+ }
+ }
+
+ /**
+ * Returns a formatted string describing the parameters.
+ *
+ * @return a formatted string describing the parameters.
+ **/
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append("[\n");
+ if ( trustAnchors != null )
+ {
+ s.append(" Trust Anchors: ").append(trustAnchors).append('\n');
+ }
+ if ( initialPolicies != null )
+ {
+ if ( initialPolicies.isEmpty() )
+ {
+ s.append(" Initial Policy OIDs: any\n" );
+ }
+ else
+ {
+ s.append(" Initial Policy OIDs: [").append(initialPolicies).append("]\n");
+ }
+ }
+ s.append(" Validity Date: ");
+ if ( date != null )
+ s.append(date);
+ else
+ s.append("null");
+ s.append('\n');
+
+ s.append(" Signature Provider: ");
+ if ( sigProvider != null )
+ s.append(sigProvider);
+ else
+ s.append("null");
+ s.append('\n');
+
+ s.append(" Default Revocation Enabled: ");
+ s.append(revocationEnabled);
+ s.append('\n' );
+
+ s.append(" Explicit Policy Required: ");
+ s.append(explicitPolicyRequired);
+ s.append('\n');
+
+ s.append(" Policy Mapping Inhibited: ");
+ s.append(policyMappingInhibited);
+ s.append('\n');
+
+ s.append(" Any Policy Inhibited: ");
+ s.append(anyPolicyInhibited);
+ s.append('\n');
+
+ s.append(" Policy Qualifiers Rejected: ");
+ s.append(policyQualifiersRejected);
+ s.append('\n');
+
+ s.append(" Target Cert Constraints: ");
+ s.append(certSelector);
+ s.append('\n');
+
+ s.append(" Certification Path Checkers: [");
+ s.append(certPathCheckers);
+ s.append( "}\n");
+
+ s.append(" CertStores: [");
+ s.append(certStores);
+ s.append("}\n");
+
+ s.append("]\n");
+
+ return s.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyNode.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyNode.java
new file mode 100644
index 000000000..cdae45205
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyNode.java
@@ -0,0 +1,107 @@
+package java.security.cert;
+
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * An immutable valid policy tree node as defined by the PKIX certification
+ * path validation algorithm.<br />
+ * <br />
+ * One of the outputs of the PKIX certification path validation
+ * algorithm is a valid policy tree, which includes the policies that
+ * were determined to be valid, how this determination was reached,
+ * and any policy qualifiers encountered. This tree is of depth
+ * <i>n</i>, where <i>n</i> is the length of the certification
+ * path that has been validated.<br />
+ * <br />
+ * Most applications will not need to examine the valid policy tree.
+ * They can achieve their policy processing goals by setting the
+ * policy-related parameters in <code>PKIXParameters</code>. However,
+ * the valid policy tree is available for more sophisticated applications,
+ * especially those that process policy qualifiers.<br />
+ * <br />
+ * {@link PKIXCertPathValidatorResult#getPolicyTree()
+ * PKIXCertPathValidatorResult.getPolicyTree} returns the root node of the
+ * valid policy tree. The tree can be traversed using the
+ * {@link #getChildren getChildren} and {@link #getParent getParent} methods.
+ * Data about a particular node can be retrieved using other methods of
+ * <code>PolicyNode</code>.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * All <code>PolicyNode</code> objects must be immutable and
+ * thread-safe. Multiple threads may concurrently invoke the methods defined
+ * in this class on a single <code>PolicyNode</code> object (or more than one)
+ * with no ill effects. This stipulation applies to all public fields and
+ * methods of this class and any added or overridden by subclasses.
+ **/
+public interface PolicyNode
+{
+
+ /**
+ * Returns the parent of this node, or <code>null</code> if this is the
+ * root node.
+ *
+ * @return the parent of this node, or <code>null</code> if this is the
+ * root node
+ */
+ public PolicyNode getParent();
+
+ /**
+ * Returns an iterator over the children of this node. Any attempts to
+ * modify the children of this node through the
+ * <code>Iterator</code>'s remove method must throw an
+ * <code>UnsupportedOperationException</code>.
+ *
+ * @return an iterator over the children of this node
+ */
+ public Iterator getChildren();
+
+ /**
+ * Returns the depth of this node in the valid policy tree.
+ *
+ * @return the depth of this node (0 for the root node, 1 for its
+ * children, and so on)
+ */
+ public int getDepth();
+
+ /**
+ * Returns the valid policy represented by this node.
+ *
+ * @return the <code>String</code> OID of the valid policy
+ * represented by this node, or the special value "any-policy". For
+ * the root node, this method always returns the special value "any-policy".
+ */
+ public String getValidPolicy();
+
+ /**
+ * Returns the set of policy qualifiers associated with the
+ * valid policy represented by this node.
+ *
+ * @return an immutable <code>Set</code> of
+ * <code>PolicyQualifierInfo</code>s. For the root node, this
+ * is always an empty <code>Set</code>.
+ */
+ public Set getPolicyQualifiers();
+
+ /**
+ * Returns the set of expected policies that would satisfy this
+ * node's valid policy in the next certificate to be processed.
+ *
+ * @return an immutable <code>Set</code> of expected policy
+ * <code>String</code> OIDs, or an immutable <code>Set</code> with
+ * the single special value "any-policy". For the root node, this method
+ * always returns a <code>Set</code> with the single value "any-policy".
+ */
+ public Set getExpectedPolicies();
+
+ /**
+ * Returns the criticality indicator of the certificate policy extension
+ * in the most recently processed certificate.
+ *
+ * @return <code>true</code> if extension marked critical,
+ * <code>false</code> otherwise. For the root node, <code>false</code>
+ * is always returned.
+ */
+ public boolean isCritical();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyQualifierInfo.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyQualifierInfo.java
new file mode 100644
index 000000000..a17f49bf4
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/PolicyQualifierInfo.java
@@ -0,0 +1,196 @@
+package java.security.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.util.ASN1Dump;
+
+/**
+ * An immutable policy qualifier represented by the ASN.1 PolicyQualifierInfo
+ * structure.<br />
+ * <br />
+ * The ASN.1 definition is as follows:<br />
+ * <br />
+ *
+ * <pre>
+ * PolicyQualifierInfo ::= SEQUENCE {
+ * policyQualifierId PolicyQualifierId,
+ * qualifier ANY DEFINED BY policyQualifierId }
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * A certificate policies extension, if present in an X.509 version 3
+ * certificate, contains a sequence of one or more policy information terms,
+ * each of which consists of an object identifier (OID) and optional qualifiers.
+ * In an end-entity certificate, these policy information terms indicate the
+ * policy under which the certificate has been issued and the purposes for which
+ * the certificate may be used. In a CA certificate, these policy information
+ * terms limit the set of policies for certification paths which include this
+ * certificate.<br />
+ * <br />
+ * A <code>Set</code> of <code>PolicyQualifierInfo</code> objects are
+ * returned by the
+ * {@link PolicyNode#getPolicyQualifiers PolicyNode.getPolicyQualifiers} method.
+ * This allows applications with specific policy requirements to process and
+ * validate each policy qualifier. Applications that need to process policy
+ * qualifiers should explicitly set the <code>policyQualifiersRejected</code>
+ * flag to false (by calling the
+ * {@link PKIXParameters#setPolicyQualifiersRejected
+ * PKIXParameters.setPolicyQualifiersRejected} method) before validating a
+ * certification path.<br />
+ * <br />
+ * Note that the PKIX certification path validation algorithm specifies that any
+ * policy qualifier in a certificate policies extension that is marked critical
+ * must be processed and validated. Otherwise the certification path must be
+ * rejected. If the <code>policyQualifiersRejected</code> flag is set to
+ * false, it is up to the application to validate all policy qualifiers in this
+ * manner in order to be PKIX compliant.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * All <code>PolicyQualifierInfo</code> objects must be immutable and
+ * thread-safe. That is, multiple threads may concurrently invoke the methods
+ * defined in this class on a single <code>PolicyQualifierInfo</code> object
+ * (or more than one) with no ill effects. Requiring
+ * <code>PolicyQualifierInfo</code> objects to be immutable and thread-safe
+ * allows them to be passed around to various pieces of code without worrying
+ * about coordinating access.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier},
+ * {@link org.spongycastle.asn1.DEROutputStream DEROutputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object}
+ */
+public final class PolicyQualifierInfo
+{
+ private String id;
+
+ private byte[] encoded;
+
+ private byte[] qualifier;
+
+ /**
+ * Creates an instance of <code>PolicyQualifierInfo</code> from the
+ * encoded bytes. The encoded byte array is copied on construction.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier} and
+ * {@link org.spongycastle.asn1.DEROutputStream DEROutputStream}
+ *
+ * @param encoded
+ * a byte array containing the qualifier in DER encoding
+ *
+ * @exception IOException
+ * thrown if the byte array does not represent a valid and
+ * parsable policy qualifier
+ */
+ public PolicyQualifierInfo(byte[] encoded) throws IOException
+ {
+ this.encoded = (byte[])encoded.clone();
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ this.encoded);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Sequence obj = (ASN1Sequence)derInStream.readObject();
+ id = ((ASN1ObjectIdentifier)obj.getObjectAt(0)).getId();
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+
+ derOutStream.writeObject(obj.getObjectAt(1));
+ derOutStream.close();
+
+ qualifier = outStream.toByteArray();
+ }
+ catch (Exception ex)
+ {
+ throw new IOException("parsing exception : " + ex.toString());
+ }
+ }
+
+ /**
+ * Returns the <code>policyQualifierId</code> field of this
+ * <code>PolicyQualifierInfo</code>. The <code>policyQualifierId</code>
+ * is an Object Identifier (OID) represented by a set of nonnegative
+ * integers separated by periods.
+ *
+ * @return the OID (never <code>null</code>)
+ */
+ public String getPolicyQualifierId()
+ {
+ return id;
+ }
+
+ /**
+ * Returns the ASN.1 DER encoded form of this
+ * <code>PolicyQualifierInfo</code>.
+ *
+ * @return the ASN.1 DER encoded bytes (never <code>null</code>). Note
+ * that a copy is returned, so the data is cloned each time this
+ * method is called.
+ */
+ public byte[] getEncoded()
+ {
+ return (byte[])encoded.clone();
+ }
+
+ /**
+ * Returns the ASN.1 DER encoded form of the <code>qualifier</code> field
+ * of this <code>PolicyQualifierInfo</code>.
+ *
+ * @return the ASN.1 DER encoded bytes of the <code>qualifier</code>
+ * field. Note that a copy is returned, so the data is cloned each
+ * time this method is called.
+ */
+ public byte[] getPolicyQualifier()
+ {
+ if (qualifier == null)
+ {
+ return null;
+ }
+
+ return (byte[])qualifier.clone();
+ }
+
+ /**
+ * Return a printable representation of this
+ * <code>PolicyQualifierInfo</code>.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object}
+ *
+ * @return a <code>String</code> describing the contents of this
+ * <code>PolicyQualifierInfo</code>
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append("PolicyQualifierInfo: [\n");
+ s.append("qualifierID: ").append(id).append('\n');
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(qualifier);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object derObject = derInStream.readObject();
+ s
+ .append(" qualifier:\n").append(ASN1Dump.dumpAsString(derObject))
+ .append('\n');
+ }
+ catch (IOException ex)
+ {
+ s.append(ex.getMessage());
+ }
+ s.append("qualifier: ").append(id).append('\n');
+ s.append(']');
+ return s.toString();
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/TrustAnchor.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/TrustAnchor.java
new file mode 100644
index 000000000..f139a742c
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/TrustAnchor.java
@@ -0,0 +1,293 @@
+package java.security.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Sequence;
+
+/**
+ * A trust anchor or most-trusted Certification Authority (CA). <br />
+ * <br />
+ * This class represents a "most-trusted CA", which is used as a trust anchor
+ * for validating X.509 certification paths. A most-trusted CA includes the
+ * public key of the CA, the CA's name, and any constraints upon the set of
+ * paths which may be validated using this key. These parameters can be
+ * specified in the form of a trusted X509Certificate or as individual
+ * parameters. <br />
+ * <br />
+ * <strong>Concurrent Access</strong><br />
+ * <br />
+ * All TrustAnchor objects must be immutable and thread-safe. That is, multiple
+ * threads may concurrently invoke the methods defined in this class on a
+ * single TrustAnchor object (or more than one) with no ill effects. Requiring
+ * TrustAnchor objects to be immutable and thread-safe allows them to be passed
+ * around to various pieces of code without worrying about coordinating access.
+ * This stipulation applies to all public fields and methods of this class and
+ * any added or overridden by subclasses.<br />
+ * <br />
+ * <b>TODO: implement better nameConstraints testing.</b>
+ **/
+public class TrustAnchor
+{
+ private X509Certificate trustCert = null;
+
+ private PublicKey trustPublicKey = null;
+
+ private String trustName = null;
+
+ private byte[] nameConstraints = null;
+
+ /**
+ * Creates an instance of TrustAnchor with the specified X509Certificate and
+ * optional name constraints, which are intended to be used as additional
+ * constraints when validating an X.509 certification path.<br />
+ * <br />
+ * The name constraints are specified as a byte array. This byte array
+ * should contain the DER encoded form of the name constraints, as they
+ * would appear in the NameConstraints structure defined in RFC 2459 and
+ * X.509. The ASN.1 definition of this structure appears below.<br />
+ * <br />
+ *
+ * <pre>
+ * NameConstraints ::= SEQUENCE {
+ * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+ *
+ * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+ *
+ * GeneralSubtree ::= SEQUENCE {
+ * base GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL }
+ *
+ * BaseDistance ::= INTEGER (0..MAX)
+ *
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Note that the name constraints byte array supplied is cloned to protect
+ * against subsequent modifications.
+ *
+ * @param trustedCert
+ * a trusted X509Certificate
+ * @param nameConstraints
+ * a byte array containing the ASN.1 DER encoding of a
+ * NameConstraints extension to be used for checking name
+ * constraints. Only the value of the extension is included, not
+ * the OID or criticality flag. Specify null to omit the
+ * parameter.
+ *
+ * @exception IllegalArgumentException
+ * if the name constraints cannot be decoded
+ * @exception NullPointerException
+ * if the specified X509Certificate is null
+ */
+ public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints)
+ {
+ if (trustedCert == null)
+ {
+ throw new NullPointerException("trustedCert must be non-null");
+ }
+
+ this.trustCert = trustedCert;
+ if (nameConstraints != null)
+ {
+ this.nameConstraints = (byte[])nameConstraints.clone();
+ checkNameConstraints(this.nameConstraints);
+ }
+ }
+
+ /**
+ * Creates an instance of <code>TrustAnchor</code> where the most-trusted
+ * CA is specified as a distinguished name and public key. Name constraints
+ * are an optional parameter, and are intended to be used as additional
+ * constraints when validating an X.509 certification path.
+ *
+ * The name constraints are specified as a byte array. This byte array
+ * contains the DER encoded form of the name constraints, as they would
+ * appear in the NameConstraints structure defined in RFC 2459 and X.509.
+ * The ASN.1 notation for this structure is supplied in the documentation
+ * for {@link #TrustAnchor(X509Certificate trustedCert, byte[]
+ * nameConstraints) TrustAnchor(X509Certificate trustedCert, byte[]
+ * nameConstraints) }.
+ *
+ * Note that the name constraints byte array supplied here is cloned to
+ * protect against subsequent modifications.
+ *
+ * @param caName
+ * the X.500 distinguished name of the most-trusted CA in RFC
+ * 2253 String format
+ * @param pubKey
+ * the public key of the most-trusted CA
+ * @param nameConstraints
+ * a byte array containing the ASN.1 DER encoding of a
+ * NameConstraints extension to be used for checking name
+ * constraints. Only the value of the extension is included, not
+ * the OID or criticality flag. Specify null to omit the
+ * parameter.
+ *
+ * @exception IllegalArgumentException
+ * if the specified caName parameter is empty (<code>caName.length() == 0</code>)
+ * or incorrectly formatted or the name constraints cannot be
+ * decoded
+ * @exception NullPointerException
+ * if the specified caName or pubKey parameter is null
+ */
+ public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints)
+ {
+ if (caName == null)
+ {
+ throw new NullPointerException("caName must be non-null");
+ }
+ if (pubKey == null)
+ {
+ throw new NullPointerException("pubKey must be non-null");
+ }
+ if (caName.length() == 0)
+ {
+ throw new IllegalArgumentException(
+ "caName can not be an empty string");
+ }
+
+ this.trustName = caName;
+ this.trustPublicKey = pubKey;
+ if (nameConstraints != null)
+ {
+ this.nameConstraints = (byte[])nameConstraints.clone();
+ checkNameConstraints(this.nameConstraints);
+ }
+ }
+
+ /**
+ * Returns the most-trusted CA certificate.
+ *
+ * @return a trusted <code>X509Certificate</code> or <code>null</code>
+ * if the trust anchor was not specified as a trusted certificate
+ */
+ public final X509Certificate getTrustedCert()
+ {
+ return trustCert;
+ }
+
+ /**
+ * Returns the name of the most-trusted CA in RFC 2253 String format.
+ *
+ * @return the X.500 distinguished name of the most-trusted CA, or
+ * <code>null</code> if the trust anchor was not specified as a
+ * trusted public key and name pair
+ */
+ public final String getCAName()
+ {
+ return trustName;
+ }
+
+ /**
+ * Returns the public key of the most-trusted CA.
+ *
+ * @return the public key of the most-trusted CA, or null if the trust
+ * anchor was not specified as a trusted public key and name pair
+ */
+ public final PublicKey getCAPublicKey()
+ {
+ return trustPublicKey;
+ }
+
+ /**
+ * Returns the name constraints parameter. The specified name constraints
+ * are associated with this trust anchor and are intended to be used as
+ * additional constraints when validating an X.509 certification path.<br />
+ * <br />
+ * The name constraints are returned as a byte array. This byte array
+ * contains the DER encoded form of the name constraints, as they would
+ * appear in the NameConstraints structure defined in RFC 2459 and X.509.
+ * The ASN.1 notation for this structure is supplied in the documentation
+ * for <code>TrustAnchor(X509Certificate trustedCert, byte[]
+ * nameConstraints)</code>.<br />
+ * <br />
+ * Note that the byte array returned is cloned to protect against subsequent
+ * modifications.
+ *
+ * @return a byte array containing the ASN.1 DER encoding of a
+ * NameConstraints extension used for checking name constraints, or
+ * <code>null</code> if not set.
+ */
+ public final byte[] getNameConstraints()
+ {
+ return (byte[])nameConstraints.clone();
+ }
+
+ /**
+ * Returns a formatted string describing the <code>TrustAnchor</code>.
+ *
+ * @return a formatted string describing the <code>TrustAnchor</code>
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[\n");
+ if (getCAPublicKey() != null)
+ {
+ sb.append(" Trusted CA Public Key: ").append(getCAPublicKey()).append('\n');
+ sb.append(" Trusted CA Issuer Name: ").append(getCAName()).append('\n');
+ }
+ else
+ {
+ sb.append(" Trusted CA cert: ").append(getTrustedCert()).append('\n');
+ }
+ if (nameConstraints != null)
+ {
+ sb.append(" Name Constraints: ").append(nameConstraints).append('\n');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Check given DER encoded nameConstraints for correct decoding. Currently
+ * only basic DER decoding test.<br />
+ * <br />
+ * <b>TODO: implement more testing.</b>
+ *
+ * @param data
+ * the DER encoded nameConstrains to be checked or
+ * <code>null</code>
+ * @exception IllegalArgumentException
+ * if the check failed.
+ */
+ private void checkNameConstraints(byte[] data)
+ {
+ if (data != null)
+ {
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object derObject = derInStream.readObject();
+ if (!(derObject instanceof ASN1Sequence))
+ {
+ throw new IllegalArgumentException(
+ "nameConstraints parameter decoding error");
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new IllegalArgumentException(
+ "nameConstraints parameter decoding error: " + ex);
+ }
+ }
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRL.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRL.java
new file mode 100644
index 000000000..cf65ed0b6
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRL.java
@@ -0,0 +1,77 @@
+
+package java.security.cert;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.util.Date;
+import java.util.Set;
+
+public abstract class X509CRL extends CRL implements X509Extension
+{
+ protected X509CRL()
+ {
+ super("X.509");
+ }
+
+ public boolean equals(Object other)
+ {
+ if ( this == other )
+ return true;
+
+ if ( !(other instanceof X509CRL) )
+ return false;
+
+ try
+ {
+ byte[] enc1 = getEncoded();
+ byte[] enc2 = ((X509CRL)other).getEncoded();
+
+ return MessageDigest.isEqual(enc1, enc2);
+ }
+ catch (CRLException e)
+ {
+ return false;
+ }
+ }
+
+ public int hashCode()
+ {
+ int hashcode = 0;
+
+ try
+ {
+ byte[] encoded = getEncoded();
+ for (int i = 1; i < encoded.length; i++)
+ {
+ hashcode += encoded[i] * i;
+ }
+ }
+ catch (CRLException ce)
+ {
+ return(hashcode);
+ }
+
+ return(hashcode);
+ }
+
+ public abstract byte[] getEncoded() throws CRLException;
+ public abstract Principal getIssuerDN();
+ public abstract Date getNextUpdate();
+ public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber);
+ public abstract Set getRevokedCertificates();
+ public abstract String getSigAlgName();
+ public abstract String getSigAlgOID();
+ public abstract byte[] getSigAlgParams();
+ public abstract byte[] getSignature();
+ public abstract byte[] getTBSCertList() throws CRLException;
+ public abstract Date getThisUpdate();
+ public abstract int getVersion();
+ public abstract void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException;
+ public abstract void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException;
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLEntry.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLEntry.java
new file mode 100644
index 000000000..bb0d78074
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLEntry.java
@@ -0,0 +1,56 @@
+
+package java.security.cert;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.util.Date;
+
+public abstract class X509CRLEntry implements X509Extension
+{
+ public boolean equals(Object other)
+ {
+ if ( this == other )
+ return true;
+
+ if ( !(other instanceof X509CRLEntry) )
+ return false;
+
+ try
+ {
+ byte[] enc1 = getEncoded();
+ byte[] enc2 = ((X509CRLEntry)other).getEncoded();
+
+ return MessageDigest.isEqual(enc1, enc2);
+ }
+ catch (CRLException e)
+ {
+ return false;
+ }
+ }
+
+ public int hashCode()
+ {
+ int hashcode = 0;
+
+ try
+ {
+ byte[] encoded = getEncoded();
+ for (int i = 1; i < encoded.length; i++)
+ {
+ hashcode += encoded[i] * i;
+ }
+ }
+ catch (CRLException ce)
+ {
+ return(hashcode);
+ }
+
+ return(hashcode);
+ }
+
+ public abstract byte[] getEncoded() throws CRLException;
+ public abstract Date getRevocationDate();
+ public abstract BigInteger getSerialNumber();
+ public abstract boolean hasExtensions();
+ public abstract String toString();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLSelector.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLSelector.java
new file mode 100644
index 000000000..7971e7b61
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CRLSelector.java
@@ -0,0 +1,717 @@
+package java.security.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRL;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERInteger;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.jce.PrincipalUtil;
+
+/**
+ * A <code>CRLSelector</code> that selects <code>X509CRLs</code> that match
+ * all specified criteria. This class is particularly useful when selecting CRLs
+ * from a <code>CertStore</code> to check revocation status of a particular
+ * certificate.<br />
+ * <br />
+ * When first constructed, an <code>X509CRLSelector</code> has no criteria
+ * enabled and each of the <code>get</code> methods return a default value (<code>null</code>).
+ * Therefore, the {@link #match match} method would return <code>true</code>
+ * for any <code>X509CRL</code>. Typically, several criteria are enabled (by
+ * calling {@link #setIssuerNames setIssuerNames} or
+ * {@link #setDateAndTime setDateAndTime}, for instance) and then the
+ * <code>X509CRLSelector</code> is passed to
+ * {@link CertStore#getCRLs CertStore.getCRLs} or some similar method.<br />
+ * <br />
+ * Please refer to RFC 2459 for definitions of the X.509 CRL fields and
+ * extensions mentioned below.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are not
+ * thread-safe. Multiple threads that need to access a single object
+ * concurrently should synchronize amongst themselves and provide the necessary
+ * locking. Multiple threads each manipulating separate objects need not
+ * synchronize.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier},
+ * {@link org.spongycastle.asn1.DEROutputStream DEROutputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name}
+ *
+ * @see CRLSelector
+ * @see X509CRL
+ */
+public class X509CRLSelector implements CRLSelector
+{
+ private Set issuerNames = null;
+
+ private Set issuerNamesX509 = null;
+
+ private BigInteger minCRL = null;
+
+ private BigInteger maxCRL = null;
+
+ private Date dateAndTime = null;
+
+ private X509Certificate certChecking = null;
+
+ /**
+ * Creates an <code>X509CRLSelector</code>. Initially, no criteria are
+ * set so any <code>X509CRL</code> will match.
+ */
+ public X509CRLSelector()
+ {
+ }
+
+ /**
+ * Sets the issuerNames criterion. The issuer distinguished name in the
+ * <code>X509CRL</code> must match at least one of the specified
+ * distinguished names. If <code>null</code>, any issuer distinguished
+ * name will do.<br />
+ * <br />
+ * This method allows the caller to specify, with a single method call, the
+ * complete set of issuer names which <code>X509CRLs</code> may contain.
+ * The specified value replaces the previous value for the issuerNames
+ * criterion.<br />
+ * <br />
+ * The <code>names</code> parameter (if not <code>null</code>) is a
+ * <code>Collection</code> of names. Each name is a <code>String</code>
+ * or a byte array representing a distinguished name (in RFC 2253 or ASN.1
+ * DER encoded form, respectively). If <code>null</code> is supplied as
+ * the value for this argument, no issuerNames check will be performed.<br />
+ * <br />
+ * Note that the <code>names</code> parameter can contain duplicate
+ * distinguished names, but they may be removed from the
+ * <code>Collection</code> of names returned by the
+ * {@link #getIssuerNames getIssuerNames} method.<br />
+ * <br />
+ * If a name is specified as a byte array, it should contain a single DER
+ * encoded distinguished name, as defined in X.501. The ASN.1 notation for
+ * this structure is as follows.
+ *
+ * <pre><code>
+ * Name ::= CHOICE {
+ * RDNSequence }
+ *
+ * RDNSequence ::= SEQUENCE OF RDN
+ *
+ * RDN ::=
+ * SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ * ....
+ * DirectoryString ::= CHOICE {
+ * teletexString TeletexString (SIZE (1..MAX)),
+ * printableString PrintableString (SIZE (1..MAX)),
+ * universalString UniversalString (SIZE (1..MAX)),
+ * utf8String UTF8String (SIZE (1.. MAX)),
+ * bmpString BMPString (SIZE (1..MAX)) }
+ * </code></pre>
+ *
+ * <br />
+ * <br />
+ * Note that a deep copy is performed on the <code>Collection</code> to
+ * protect against subsequent modifications.
+ *
+ * @param names
+ * a <code>Collection</code> of names (or <code>null</code>)
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ *
+ * @see #getIssuerNames
+ */
+ public void setIssuerNames(Collection names) throws IOException
+ {
+ if (names == null || names.isEmpty())
+ {
+ issuerNames = null;
+ issuerNamesX509 = null;
+ }
+ else
+ {
+ Object item;
+ Iterator iter = names.iterator();
+ while (iter.hasNext())
+ {
+ item = iter.next();
+ if (item instanceof String)
+ {
+ addIssuerName((String)item);
+ }
+ else if (item instanceof byte[])
+ {
+ addIssuerName((byte[])item);
+ }
+ else
+ {
+ throw new IOException("name not byte[]or String: "
+ + item.toString());
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds a name to the issuerNames criterion. The issuer distinguished name
+ * in the <code>X509CRL</code> must match at least one of the specified
+ * distinguished names.<br />
+ * <br />
+ * This method allows the caller to add a name to the set of issuer names
+ * which <code>X509CRLs</code> may contain. The specified name is added to
+ * any previous value for the issuerNames criterion. If the specified name
+ * is a duplicate, it may be ignored.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for parsing the
+ * name
+ *
+ * @param name
+ * the name in RFC 2253 form
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ */
+ public void addIssuerName(String name) throws IOException
+ {
+ if (issuerNames == null)
+ {
+ issuerNames = new HashSet();
+ issuerNamesX509 = new HashSet();
+ }
+ X509Name nameX509;
+ try
+ {
+ nameX509 = new X509Name(name);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IOException(ex.getMessage());
+ }
+ issuerNamesX509.add(nameX509);
+ issuerNames.add(name);
+ }
+
+ /**
+ * Adds a name to the issuerNames criterion. The issuer distinguished name
+ * in the <code>X509CRL</code> must match at least one of the specified
+ * distinguished names.<br />
+ * <br />
+ * This method allows the caller to add a name to the set of issuer names
+ * which <code>X509CRLs</code> may contain. The specified name is added to
+ * any previous value for the issuerNames criterion. If the specified name
+ * is a duplicate, it may be ignored. If a name is specified as a byte
+ * array, it should contain a single DER encoded distinguished name, as
+ * defined in X.501. The ASN.1 notation for this structure is as follows.<br />
+ * <br />
+ * The name is provided as a byte array. This byte array should contain a
+ * single DER encoded distinguished name, as defined in X.501. The ASN.1
+ * notation for this structure appears in the documentation for
+ * {@link #setIssuerNames setIssuerNames(Collection names)}.<br />
+ * <br />
+ * Note that the byte array supplied here is cloned to protect against
+ * subsequent modifications.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for parsing the
+ * name, {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object} and
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence}
+ *
+ * @param name
+ * a byte array containing the name in ASN.1 DER encoded form
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ */
+ public void addIssuerName(byte[] name) throws IOException
+ {
+ if (issuerNames == null)
+ {
+ issuerNames = new HashSet();
+ issuerNamesX509 = new HashSet();
+ }
+
+ ByteArrayInputStream inStream = new ByteArrayInputStream(name);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object obj = derInStream.readObject();
+ if (obj instanceof ASN1Sequence)
+ {
+ issuerNamesX509.add(new X509Name((ASN1Sequence)obj));
+ }
+ else
+ {
+ throw new IOException("parsing error");
+ }
+ issuerNames.add(name.clone());
+ }
+
+ /**
+ * Sets the minCRLNumber criterion. The <code>X509CRL</code> must have a
+ * CRL number extension whose value is greater than or equal to the
+ * specified value. If <code>null</code>, no minCRLNumber check will be
+ * done.
+ *
+ * @param minCRL
+ * the minimum CRL number accepted (or <code>null</code>)
+ */
+ public void setMinCRLNumber(BigInteger minCRL)
+ {
+ this.minCRL = minCRL;
+ }
+
+ /**
+ * Sets the maxCRLNumber criterion. The <code>X509CRL</code> must have a
+ * CRL number extension whose value is less than or equal to the specified
+ * value. If <code>null</code>, no maxCRLNumber check will be done.
+ *
+ * @param maxCRL
+ * the maximum CRL number accepted (or <code>null</code>)
+ */
+ public void setMaxCRLNumber(BigInteger maxCRL)
+ {
+ this.maxCRL = maxCRL;
+ }
+
+ /**
+ * Sets the dateAndTime criterion. The specified date must be equal to or
+ * later than the value of the thisUpdate component of the
+ * <code>X509CRL</code> and earlier than the value of the nextUpdate
+ * component. There is no match if the <code>X509CRL</code> does not
+ * contain a nextUpdate component. If <code>null</code>, no dateAndTime
+ * check will be done.<br />
+ * <br />
+ * Note that the <code>Date</code> supplied here is cloned to protect
+ * against subsequent modifications.
+ *
+ * @param dateAndTime
+ * the <code>Date</code> to match against (or <code>null</code>)
+ *
+ * @see #getDateAndTime
+ */
+ public void setDateAndTime(Date dateAndTime)
+ {
+ if (dateAndTime == null)
+ {
+ this.dateAndTime = null;
+ }
+ else
+ {
+ this.dateAndTime = new Date(dateAndTime.getTime());
+ }
+ }
+
+ /**
+ * Sets the certificate being checked. This is not a criterion. Rather, it
+ * is optional information that may help a <code>CertStore</code> find
+ * CRLs that would be relevant when checking revocation for the specified
+ * certificate. If <code>null</code> is specified, then no such optional
+ * information is provided.
+ *
+ * @param cert
+ * the <code>X509Certificate</code> being checked (or
+ * <code>null</code>)
+ *
+ * @see #getCertificateChecking
+ */
+ public void setCertificateChecking(X509Certificate cert)
+ {
+ certChecking = cert;
+ }
+
+ /**
+ * Returns a copy of the issuerNames criterion. The issuer distinguished
+ * name in the <code>X509CRL</code> must match at least one of the
+ * specified distinguished names. If the value returned is <code>null</code>,
+ * any issuer distinguished name will do.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a
+ * <code>Collection</code> of names. Each name is a <code>String</code>
+ * or a byte array representing a distinguished name (in RFC 2253 or ASN.1
+ * DER encoded form, respectively). Note that the <code>Collection</code>
+ * returned may contain duplicate names.<br />
+ * <br />
+ * If a name is specified as a byte array, it should contain a single DER
+ * encoded distinguished name, as defined in X.501. The ASN.1 notation for
+ * this structure is given in the documentation for
+ * {@link #setIssuerNames setIssuerNames(Collection names)}.<br />
+ * <br />
+ * Note that a deep copy is performed on the <code>Collection</code> to
+ * protect against subsequent modifications.
+ *
+ * @return a <code>Collection</code> of names (or <code>null</code>)
+ * @see #setIssuerNames
+ */
+ public Collection getIssuerNames()
+ {
+ if (issuerNames == null)
+ {
+ return null;
+ }
+
+ Collection set = new HashSet();
+ Iterator iter = issuerNames.iterator();
+ Object item;
+ while (iter.hasNext())
+ {
+ item = iter.next();
+ if (item instanceof String)
+ {
+ set.add(new String((String)item));
+ }
+ else if (item instanceof byte[])
+ {
+ set.add(((byte[])item).clone());
+ }
+ }
+ return set;
+ }
+
+ /**
+ * Returns the minCRLNumber criterion. The <code>X509CRL</code> must have
+ * a CRL number extension whose value is greater than or equal to the
+ * specified value. If <code>null</code>, no minCRLNumber check will be
+ * done.
+ *
+ * @return the minimum CRL number accepted (or <code>null</code>)
+ */
+ public BigInteger getMinCRL()
+ {
+ return minCRL;
+ }
+
+ /**
+ * Returns the maxCRLNumber criterion. The <code>X509CRL</code> must have
+ * a CRL number extension whose value is less than or equal to the specified
+ * value. If <code>null</code>, no maxCRLNumber check will be done.
+ *
+ * @return the maximum CRL number accepted (or <code>null</code>)
+ */
+ public BigInteger getMaxCRL()
+ {
+ return maxCRL;
+ }
+
+ /**
+ * Returns the dateAndTime criterion. The specified date must be equal to or
+ * later than the value of the thisUpdate component of the
+ * <code>X509CRL</code> and earlier than the value of the nextUpdate
+ * component. There is no match if the <code>X509CRL</code> does not
+ * contain a nextUpdate component. If <code>null</code>, no dateAndTime
+ * check will be done.<br />
+ * <br />
+ * Note that the <code>Date</code> returned is cloned to protect against
+ * subsequent modifications.
+ *
+ * @return the <code>Date</code> to match against (or <code>null</code>)
+ *
+ * @see #setDateAndTime
+ */
+ public Date getDateAndTime()
+ {
+ if (dateAndTime == null)
+ {
+ return null;
+ }
+
+ return new Date(dateAndTime.getTime());
+ }
+
+ /**
+ * Returns the certificate being checked. This is not a criterion. Rather,
+ * it is optional information that may help a <code>CertStore</code> find
+ * CRLs that would be relevant when checking revocation for the specified
+ * certificate. If the value returned is <code>null</code>, then no such
+ * optional information is provided.
+ *
+ * @return the certificate being checked (or <code>null</code>)
+ *
+ * @see #setCertificateChecking
+ */
+ public X509Certificate getCertificateChecking()
+ {
+ return certChecking;
+ }
+
+ /**
+ * Returns a printable representation of the <code>X509CRLSelector</code>.<br />
+ * <br />
+ * Uses
+ * {@link org.spongycastle.asn1.x509.X509Name#toString X509Name.toString} to
+ * format the output
+ *
+ * @return a <code>String</code> describing the contents of the
+ * <code>X509CRLSelector</code>.
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ s.append("X509CRLSelector: [\n");
+ if (issuerNamesX509 != null)
+ {
+ s.append(" IssuerNames:\n");
+ Iterator iter = issuerNamesX509.iterator();
+ while (iter.hasNext())
+ {
+ s.append(" ").append(iter.next()).append('\n');
+ }
+ }
+ if (minCRL != null)
+ {
+ s.append(" minCRLNumber: ").append(minCRL).append('\n');
+ }
+ if (maxCRL != null)
+ {
+ s.append(" maxCRLNumber: ").append(maxCRL).append('\n');
+ }
+ if (dateAndTime != null)
+ {
+ s.append(" dateAndTime: ").append(dateAndTime).append('\n');
+ }
+ if (certChecking != null)
+ {
+ s.append(" Certificate being checked: ").append(certChecking).append('\n');
+ }
+ s.append(']');
+ return s.toString();
+ }
+
+ /**
+ * Decides whether a <code>CRL</code> should be selected.<br />
+ * <br />
+ * Uses
+ * {@link org.spongycastle.asn1.x509.X509Name#toString X509Name.toString} to
+ * parse and to compare the crl parameter issuer and
+ * {@link org.spongycastle.asn1.x509.X509Extensions#CRLNumber CRLNumber} to
+ * access the CRL number extension.
+ *
+ * @param crl
+ * the <code>CRL</code> to be checked
+ *
+ * @return <code>true</code> if the <code>CRL</code> should be selected,
+ * <code>false</code> otherwise
+ */
+ public boolean match(CRL crl)
+ {
+ if (!(crl instanceof X509CRL))
+ {
+ return false;
+ }
+
+ X509CRL crlX509 = (X509CRL)crl;
+ boolean test;
+
+ if (issuerNamesX509 != null)
+ {
+ Iterator iter = issuerNamesX509.iterator();
+ test = false;
+ X509Name crlIssuer = null;
+ try
+ {
+ crlIssuer = PrincipalUtil.getIssuerX509Principal(crlX509);
+ }
+ catch (Exception ex)
+ {
+
+ return false;
+ }
+
+ while (iter.hasNext())
+ {
+ if (crlIssuer.equals(iter.next(), true))
+ {
+ test = true;
+ break;
+ }
+ }
+ if (!test)
+ {
+ return false;
+ }
+ }
+
+ byte[] data = crlX509.getExtensionValue(X509Extensions.CRLNumber
+ .getId());
+ if (data != null)
+ {
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ inStream = new ByteArrayInputStream(
+ ((ASN1OctetString)derInputStream.readObject())
+ .getOctets());
+ derInputStream = new ASN1InputStream(inStream);
+ BigInteger crlNumber = ((DERInteger)derInputStream.readObject())
+ .getPositiveValue();
+ if (minCRL != null && minCRL.compareTo(crlNumber) > 0)
+ {
+ return false;
+ }
+ if (maxCRL != null && maxCRL.compareTo(crlNumber) < 0)
+ {
+ return false;
+ }
+ }
+ catch (IOException ex)
+ {
+ return false;
+ }
+ }
+ else if (minCRL != null || maxCRL != null)
+ {
+ return false;
+ }
+
+ if (dateAndTime != null)
+ {
+ Date check = crlX509.getThisUpdate();
+ if (check == null)
+ {
+ return false;
+ }
+ else if (dateAndTime.before(check))
+ {
+ return false;
+ }
+
+ check = crlX509.getNextUpdate();
+ if (check == null)
+ {
+ return false;
+ }
+ else if (!dateAndTime.before(check))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return the copy
+ */
+ public Object clone()
+ {
+ try
+ {
+ X509CRLSelector copy = (X509CRLSelector)super.clone();
+ if (issuerNames != null)
+ {
+ copy.issuerNames = new HashSet();
+ Iterator iter = issuerNames.iterator();
+ Object obj;
+ while (iter.hasNext())
+ {
+ obj = iter.next();
+ if (obj instanceof byte[])
+ {
+ copy.issuerNames.add(((byte[])obj).clone());
+ }
+ else
+ {
+ copy.issuerNames.add(obj);
+ }
+ }
+ copy.issuerNamesX509 = new HashSet(issuerNamesX509);
+ }
+ return copy;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ /* Cannot happen */
+ throw new InternalError(e.toString());
+ }
+ }
+
+ /**
+ * Decides whether a <code>CRL</code> should be selected.
+ *
+ * @param crl
+ * the <code>CRL</code> to be checked
+ *
+ * @return <code>true</code> if the <code>CRL</code> should be selected,
+ * <code>false</code> otherwise
+ */
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof X509CRLSelector))
+ {
+ return false;
+ }
+
+ X509CRLSelector equalsCRL = (X509CRLSelector)obj;
+
+ if (!equals(dateAndTime, equalsCRL.dateAndTime))
+ {
+ return false;
+ }
+
+ if (!equals(minCRL, equalsCRL.minCRL))
+ {
+ return false;
+ }
+
+ if (!equals(maxCRL, equalsCRL.maxCRL))
+ {
+ return false;
+ }
+
+ if (!equals(issuerNamesX509, equalsCRL.issuerNamesX509))
+ {
+ return false;
+ }
+
+ if (!equals(certChecking, equalsCRL.certChecking))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return <code>true</code> if two Objects are unequal.
+ * This means that one is <code>null</code> and the other is
+ * not or <code>obj1.equals(obj2)</code> returns
+ * <code>false</code>.
+ **/
+ private boolean equals(Object obj1, Object obj2)
+ {
+ if (obj1 == null)
+ {
+ if (obj2 != null)
+ {
+ return true;
+ }
+ }
+ else if (!obj1.equals(obj2))
+ {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java
new file mode 100644
index 000000000..89767cde5
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509CertSelector.java
@@ -0,0 +1,2461 @@
+package java.security.cert;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERGeneralizedTime;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.util.ASN1Dump;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.ExtendedKeyUsage;
+import org.spongycastle.asn1.x509.KeyPurposeId;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.util.Integers;
+
+/**
+ * A <code>CertSelector</code> that selects
+ * <code>X509Certificates that match all
+ * specified criteria. This class is particularly useful when
+ * selecting certificates from a CertStore to build a PKIX-compliant
+ * certification path.<br />
+ * <br />
+ * When first constructed, an <code>X509CertSelector</code> has no criteria enabled
+ * and each of the get methods return a default value (<code>null</code>, or -1 for
+ * the {@link #getBasicConstraints} method). Therefore, the {@link #match} method would
+ * return true for any <code>X509Certificate</code>. Typically, several criteria
+ * are enabled (by calling {@link #setIssuer} or {@link #setKeyUsage}, for instance) and
+ * then the <code>X509CertSelector</code> is passed to {@link CertStore#getCertificates} or
+ * some similar method.<br />
+ * <br />
+ * Several criteria can be enabled (by calling {@link #setIssuer} and
+ * {@link #setSerialNumber}, for example) such that the match method usually
+ * uniquely matches a single <code>X509Certificate</code>. We say usually, since it
+ * is possible for two issuing CAs to have the same distinguished name
+ * and each issue a certificate with the same serial number. Other
+ * unique combinations include the issuer, subject,
+ * subjectKeyIdentifier and/or the subjectPublicKey criteria.<br />
+ * <br />
+ * Please refer to RFC 2459 for definitions of the X.509 certificate
+ * extensions mentioned below.<br />
+ * <br />
+ * <b>Concurrent Access</b><br />
+ * <br />
+ * Unless otherwise specified, the methods defined in this class are
+ * not thread-safe. Multiple threads that need to access a single
+ * object concurrently should synchronize amongst themselves and
+ * provide the necessary locking. Multiple threads each manipulating
+ * separate objects need not synchronize.<br />
+ * <br />
+ * <b>TODO: implement name constraints</b>
+ * <b>TODO: implement match check for path to names</b><br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier},
+ * {@link org.spongycastle.asn1.DEROutputStream DEROutputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object},
+ * {@link org.spongycastle.asn1.OIDTokenizer OIDTokenizer},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name},
+ * {@link org.spongycastle.asn1.x509.X509Extensions X509Extensions},
+ * {@link org.spongycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage},
+ * {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId},
+ * {@link org.spongycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo},
+ * {@link org.spongycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier}
+ */
+public class X509CertSelector implements CertSelector
+{
+ private static final Hashtable keyPurposeIdMap = new Hashtable();
+ static
+ {
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_serverAuth.getId(),
+ KeyPurposeId.id_kp_serverAuth);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_clientAuth.getId(),
+ KeyPurposeId.id_kp_clientAuth);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_codeSigning.getId(),
+ KeyPurposeId.id_kp_codeSigning);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_emailProtection.getId(),
+ KeyPurposeId.id_kp_emailProtection);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecEndSystem.getId(),
+ KeyPurposeId.id_kp_ipsecEndSystem);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecTunnel.getId(),
+ KeyPurposeId.id_kp_ipsecTunnel);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_ipsecUser.getId(),
+ KeyPurposeId.id_kp_ipsecUser);
+ keyPurposeIdMap.put(KeyPurposeId.id_kp_timeStamping.getId(),
+ KeyPurposeId.id_kp_timeStamping);
+ }
+
+ private X509Certificate x509Cert = null;
+
+ private BigInteger serialNumber = null;
+
+ private Object issuerDN = null;
+
+ private X509Name issuerDNX509 = null;
+
+ private Object subjectDN = null;
+
+ private X509Name subjectDNX509 = null;
+
+ private byte[] subjectKeyID = null;
+
+ private byte[] authorityKeyID = null;
+
+ private Date certValid = null;
+
+ private Date privateKeyValid = null;
+
+ private ASN1ObjectIdentifier subjectKeyAlgID = null;
+
+ private PublicKey subjectPublicKey = null;
+
+ private byte[] subjectPublicKeyByte = null;
+
+ private boolean[] keyUsage = null;
+
+ private Set keyPurposeSet = null;
+
+ private boolean matchAllSubjectAltNames = true;
+
+ private Set subjectAltNames = null;
+
+ private Set subjectAltNamesByte = null;
+
+ private int minMaxPathLen = -1;
+
+ private Set policy = null;
+
+ private Set policyOID = null;
+
+ private Set pathToNames = null;
+
+ private Set pathToNamesByte = null;
+
+ /**
+ * Creates an <code>X509CertSelector</code>. Initially, no criteria are
+ * set so any <code>X509Certificate</code> will match.
+ */
+ public X509CertSelector()
+ {
+ }
+
+ /**
+ * Sets the certificateEquals criterion. The specified
+ * <code>X509Certificate</code> must be equal to the
+ * <code>X509Certificate</code> passed to the match method. If
+ * <code>null</code>, then this check is not applied.<br />
+ * <br />
+ * This method is particularly useful when it is necessary to match a single
+ * certificate. Although other criteria can be specified in conjunction with
+ * the certificateEquals criterion, it is usually not practical or
+ * necessary.
+ *
+ * @param cert
+ * the X509Certificate to match (or <code>null</code>)
+ *
+ * @see #getCertificate()
+ */
+ public void setCertificate(X509Certificate cert)
+ {
+ x509Cert = cert;
+ }
+
+ /**
+ * Sets the serialNumber criterion. The specified serial number must match
+ * the certificate serial number in the <code>X509Certificate</code>. If
+ * <code>null</code>, any certificate serial number will do.
+ *
+ * @param serial
+ * the certificate serial number to match (or <code>null</code>)
+ *
+ * @see #getSerialNumber()
+ */
+ public void setSerialNumber(BigInteger serial)
+ {
+ serialNumber = serial;
+ }
+
+ /**
+ * Sets the issuer criterion. The specified distinguished name must match
+ * the issuer distinguished name in the <code>X509Certificate</code>. If
+ * <code>null</code>, any issuer distinguished name will do.<br />
+ * <br />
+ * If <code>issuerDN</code> is not <code>null</code>, it should contain
+ * a distinguished name, in RFC 2253 format.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for parsing the
+ * issuerDN.
+ *
+ * @param issuerDN
+ * a distinguished name in RFC 2253 format (or <code>null</code>)
+ *
+ * @exception IOException
+ * if a parsing error occurs (incorrect form for DN)
+ */
+ public void setIssuer(String issuerDN) throws IOException
+ {
+ if (issuerDN == null)
+ {
+ this.issuerDN = null;
+ this.issuerDNX509 = null;
+ }
+ else
+ {
+ X509Name nameX509;
+ try
+ {
+ nameX509 = new X509Name(issuerDN);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IOException(ex.getMessage());
+ }
+ this.issuerDNX509 = nameX509;
+ this.issuerDN = issuerDN;
+ }
+ }
+
+ /**
+ * Sets the issuer criterion. The specified distinguished name must match
+ * the issuer distinguished name in the <code>X509Certificate</code>. If
+ * null is specified, the issuer criterion is disabled and any issuer
+ * distinguished name will do.<br />
+ * <br />
+ * If <code>issuerDN</code> is not <code>null</code>, it should contain
+ * a single DER encoded distinguished name, as defined in X.501. The ASN.1
+ * notation for this structure is as follows.<br />
+ * <br />
+ *
+ * <pre>
+ * Name ::= CHOICE {
+ * RDNSequence }
+ *
+ * RDNSequence ::= SEQUENCE OF RDN
+ *
+ * RDN ::=
+ * SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ * ....
+ * DirectoryString ::= CHOICE {
+ * teletexString TeletexString (SIZE (1..MAX)),
+ * printableString PrintableString (SIZE (1..MAX)),
+ * universalString UniversalString (SIZE (1..MAX)),
+ * utf8String UTF8String (SIZE (1.. MAX)),
+ * bmpString BMPString (SIZE (1..MAX)) }
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Note that the byte array specified here is cloned to protect against
+ * subsequent modifications.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name}
+ *
+ * @param issuerDN -
+ * a byte array containing the distinguished name in ASN.1 DER
+ * encoded form (or <code>null</code>)
+ *
+ * @exception IOException
+ * if an encoding error occurs (incorrect form for DN)
+ */
+ public void setIssuer(byte[] issuerDN) throws IOException
+ {
+ if (issuerDN == null)
+ {
+ this.issuerDN = null;
+ this.issuerDNX509 = null;
+ }
+ else
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(issuerDN);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object obj = derInStream.readObject();
+ if (obj instanceof ASN1Sequence)
+ {
+ this.issuerDNX509 = new X509Name((ASN1Sequence)obj);
+ }
+ else
+ {
+ throw new IOException("parsing error");
+ }
+ this.issuerDN = (byte[])issuerDN.clone();
+ }
+ }
+
+ /**
+ * Sets the subject criterion. The specified distinguished name must match
+ * the subject distinguished name in the <code>X509Certificate</code>. If
+ * null, any subject distinguished name will do.<br />
+ * <br />
+ * If <code>subjectDN</code> is not <code>null</code>, it should
+ * contain a distinguished name, in RFC 2253 format.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for parsing the
+ * subjectDN.
+ *
+ * @param subjectDN
+ * a distinguished name in RFC 2253 format (or <code>null</code>)
+ *
+ * @exception IOException
+ * if a parsing error occurs (incorrect form for DN)
+ */
+ public void setSubject(String subjectDN) throws IOException
+ {
+ if (subjectDN == null)
+ {
+ this.subjectDN = null;
+ this.subjectDNX509 = null;
+ }
+ else
+ {
+ X509Name nameX509;
+ try
+ {
+ nameX509 = new X509Name(subjectDN);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IOException(ex.getMessage());
+ }
+
+ this.subjectDNX509 = nameX509;
+ this.subjectDN = subjectDN;
+ }
+ }
+
+ /**
+ * Sets the subject criterion. The specified distinguished name must match
+ * the subject distinguished name in the <code>X509Certificate</code>. If
+ * null, any subject distinguished name will do.<br />
+ * <br />
+ * If <code>subjectDN</code> is not <code>null</code>, it should
+ * contain a single DER encoded distinguished name, as defined in X.501. For
+ * the ASN.1 notation for this structure, see
+ * {@link #setIssuer(byte []) setIssuer(byte [] issuerDN)}.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name}
+ *
+ * @param subjectDN
+ * a byte array containing the distinguished name in ASN.1 DER
+ * format (or <code>null</code>)
+ *
+ * @exception IOException
+ * if an encoding error occurs (incorrect form for DN)
+ */
+ public void setSubject(byte[] subjectDN) throws IOException
+ {
+ if (subjectDN == null)
+ {
+ this.subjectDN = null;
+ this.subjectDNX509 = null;
+ }
+ else
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(subjectDN);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object obj = derInStream.readObject();
+
+ if (obj instanceof ASN1Sequence)
+ {
+ this.subjectDNX509 = new X509Name((ASN1Sequence)obj);
+ }
+ else
+ {
+ throw new IOException("parsing error");
+ }
+ this.subjectDN = (byte[])subjectDN.clone();
+ }
+ }
+
+ /**
+ * Sets the subjectKeyIdentifier criterion. The <code>X509Certificate</code>
+ * must contain a SubjectKeyIdentifier extension for which the contents of
+ * the extension matches the specified criterion value. If the criterion
+ * value is null, no subjectKeyIdentifier check will be done.<br />
+ * <br />
+ * If <code>subjectKeyID</code> is not <code>null</code>, it should
+ * contain a single DER encoded value corresponding to the contents of the
+ * extension value (not including the object identifier, criticality
+ * setting, and encapsulating OCTET STRING) for a SubjectKeyIdentifier
+ * extension. The ASN.1 notation for this structure follows.<br />
+ * <br />
+ *
+ * <pre>
+ * SubjectKeyIdentifier ::= KeyIdentifier
+ *
+ * KeyIdentifier ::= OCTET STRING
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Since the format of subject key identifiers is not mandated by any
+ * standard, subject key identifiers are not parsed by the
+ * <code>X509CertSelector</code>. Instead, the values are compared using
+ * a byte-by-byte comparison.<br />
+ * <br />
+ * Note that the byte array supplied here is cloned to protect against
+ * subsequent modifications.
+ *
+ * @param subjectKeyID -
+ * the subject key identifier (or <code>null</code>)
+ *
+ * @see #getSubjectKeyIdentifier()
+ */
+ public void setSubjectKeyIdentifier(byte[] subjectKeyID)
+ {
+ if (subjectKeyID == null)
+ {
+ this.subjectKeyID = null;
+ }
+ else
+ {
+ this.subjectKeyID = (byte[])subjectKeyID.clone();
+ }
+ }
+
+ /**
+ * Sets the authorityKeyIdentifier criterion. The
+ * <code>X509Certificate</code> must contain an AuthorityKeyIdentifier
+ * extension for which the contents of the extension value matches the
+ * specified criterion value. If the criterion value is <code>null</code>,
+ * no authorityKeyIdentifier check will be done.<br />
+ * <br />
+ * If <code>authorityKeyID</code> is not <code>null</code>, it should
+ * contain a single DER encoded value corresponding to the contents of the
+ * extension value (not including the object identifier, criticality
+ * setting, and encapsulating OCTET STRING) for an AuthorityKeyIdentifier
+ * extension. The ASN.1 notation for this structure follows.<br />
+ * <br />
+ *
+ * <pre>
+ * AuthorityKeyIdentifier ::= SEQUENCE {
+ * keyIdentifier [0] KeyIdentifier OPTIONAL,
+ * authorityCertIssuer [1] GeneralNames OPTIONAL,
+ * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ *
+ * KeyIdentifier ::= OCTET STRING
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Authority key identifiers are not parsed by the
+ * <code>X509CertSelector</code>. Instead, the values are compared using
+ * a byte-by-byte comparison.<br />
+ * <br />
+ * When the <code>keyIdentifier</code> field of
+ * <code>AuthorityKeyIdentifier</code> is populated, the value is usually
+ * taken from the SubjectKeyIdentifier extension in the issuer's
+ * certificate. Note, however, that the result of
+ * X509Certificate.getExtensionValue(<SubjectKeyIdentifier Object
+ * Identifier>) on the issuer's certificate may NOT be used directly as the
+ * input to setAuthorityKeyIdentifier. This is because the
+ * SubjectKeyIdentifier contains only a KeyIdentifier OCTET STRING, and not
+ * a SEQUENCE of KeyIdentifier, GeneralNames, and CertificateSerialNumber.
+ * In order to use the extension value of the issuer certificate's
+ * SubjectKeyIdentifier extension, it will be necessary to extract the value
+ * of the embedded KeyIdentifier OCTET STRING, then DER encode this OCTET
+ * STRING inside a SEQUENCE. For more details on SubjectKeyIdentifier, see
+ * {@link #setSubjectKeyIdentifier(byte[]) setSubjectKeyIdentifier(byte[] subjectKeyID }).<br />
+ * <br />
+ * Note also that the byte array supplied here is cloned to protect against
+ * subsequent modifications.
+ *
+ * @param authorityKeyID
+ * the authority key identifier (or <code>null</code>)
+ *
+ * @see #getAuthorityKeyIdentifier()
+ */
+ public void setAuthorityKeyIdentifier(byte[] authorityKeyID)
+ {
+ if (authorityKeyID == null)
+ {
+ this.authorityKeyID = null;
+ }
+ else
+ {
+ this.authorityKeyID = (byte[])authorityKeyID.clone();
+ }
+ }
+
+ /**
+ * Sets the certificateValid criterion. The specified date must fall within
+ * the certificate validity period for the X509Certificate. If
+ * <code>null</code>, no certificateValid check will be done.<br />
+ * <br />
+ * Note that the Date supplied here is cloned to protect against subsequent
+ * modifications.
+ *
+ * @param certValid
+ * the Date to check (or <code>null</code>)
+ *
+ * @see #getCertificateValid()
+ */
+ public void setCertificateValid(Date certValid)
+ {
+ if (certValid == null)
+ {
+ this.certValid = null;
+ }
+ else
+ {
+ this.certValid = new Date(certValid.getTime());
+ }
+ }
+
+ /**
+ * Sets the privateKeyValid criterion. The specified date must fall within
+ * the private key validity period for the X509Certificate. If
+ * <code>null</code>, no privateKeyValid check will be done.<br />
+ * <br />
+ * Note that the Date supplied here is cloned to protect against subsequent
+ * modifications.
+ *
+ * @param privateKeyValid
+ * the Date to check (or <code>null</code>)
+ *
+ * @see #getPrivateKeyValid()
+ */
+ public void setPrivateKeyValid(Date privateKeyValid)
+ {
+ if (privateKeyValid == null)
+ {
+ this.privateKeyValid = null;
+ }
+ else
+ {
+ this.privateKeyValid = new Date(privateKeyValid.getTime());
+ }
+ }
+
+ /**
+ * Sets the subjectPublicKeyAlgID criterion. The X509Certificate must
+ * contain a subject public key with the specified algorithm. If
+ * <code>null</code>, no subjectPublicKeyAlgID check will be done.
+ *
+ * @param oid
+ * The object identifier (OID) of the algorithm to check for (or
+ * <code>null</code>). An OID is represented by a set of
+ * nonnegative integers separated by periods.
+ *
+ * @exception IOException
+ * if the OID is invalid, such as the first component being
+ * not 0, 1 or 2 or the second component being greater than
+ * 39.
+ *
+ * @see #getSubjectPublicKeyAlgID()
+ */
+ public void setSubjectPublicKeyAlgID(String oid) throws IOException
+ {
+ CertUtil.parseOID(oid);
+ subjectKeyAlgID = new ASN1ObjectIdentifier(oid);
+ }
+
+ /**
+ * Sets the subjectPublicKey criterion. The X509Certificate must contain the
+ * specified subject public key. If null, no subjectPublicKey check will be
+ * done.
+ *
+ * @param key
+ * the subject public key to check for (or null)
+ *
+ * @see #getSubjectPublicKey()
+ */
+ public void setSubjectPublicKey(PublicKey key)
+ {
+ if (key == null)
+ {
+ subjectPublicKey = null;
+ subjectPublicKeyByte = null;
+ }
+ else
+ {
+ subjectPublicKey = key;
+ subjectPublicKeyByte = key.getEncoded();
+ }
+ }
+
+ /**
+ * Sets the subjectPublicKey criterion. The <code>X509Certificate</code>
+ * must contain the specified subject public key. If <code>null</code>,
+ * no subjectPublicKey check will be done.<br />
+ * <br />
+ * Because this method allows the public key to be specified as a byte
+ * array, it may be used for unknown key types.<br />
+ * <br />
+ * If key is not <code>null</code>, it should contain a single DER
+ * encoded SubjectPublicKeyInfo structure, as defined in X.509. The ASN.1
+ * notation for this structure is as follows.<br />
+ * <br />
+ *
+ * <pre>
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ * -- contains a value of the type
+ * -- registered for use with the
+ * -- algorithm object identifier value
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Note that the byte array supplied here is cloned to protect against
+ * subsequent modifications.
+ *
+ * @param key
+ * a byte array containing the subject public key in ASN.1 DER
+ * form (or <code>null</code>)
+ *
+ * @exception IOException
+ * if an encoding error occurs (incorrect form for subject
+ * public key)
+ *
+ * @see #getSubjectPublicKey()
+ */
+ public void setSubjectPublicKey(byte[] key) throws IOException
+ {
+ if (key == null)
+ {
+ subjectPublicKey = null;
+ subjectPublicKeyByte = null;
+ }
+ else
+ {
+ subjectPublicKey = null;
+ subjectPublicKeyByte = (byte[])key.clone();
+ // TODO
+ // try to generyte PublicKey Object from subjectPublicKeyByte
+ }
+ }
+
+ /**
+ * Sets the keyUsage criterion. The X509Certificate must allow the specified
+ * keyUsage values. If null, no keyUsage check will be done. Note that an
+ * X509Certificate that has no keyUsage extension implicitly allows all
+ * keyUsage values.<br />
+ * <br />
+ * Note that the boolean array supplied here is cloned to protect against
+ * subsequent modifications.
+ *
+ * @param keyUsage
+ * a boolean array in the same format as the boolean array
+ * returned by X509Certificate.getKeyUsage(). Or
+ * <code>null</code>.
+ *
+ * @see #getKeyUsage()
+ */
+ public void setKeyUsage(boolean[] keyUsage)
+ {
+ if (keyUsage == null)
+ {
+ this.keyUsage = null;
+ }
+ else
+ {
+ this.keyUsage = (boolean[])keyUsage.clone();
+ }
+ }
+
+ /**
+ * Sets the extendedKeyUsage criterion. The <code>X509Certificate</code>
+ * must allow the specified key purposes in its extended key usage
+ * extension. If <code>keyPurposeSet</code> is empty or <code>null</code>,
+ * no extendedKeyUsage check will be done. Note that an
+ * <code>X509Certificate</code> that has no extendedKeyUsage extension
+ * implicitly allows all key purposes.<br />
+ * <br />
+ * Note that the Set is cloned to protect against subsequent modifications.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId}
+ *
+ * @param keyPurposeSet
+ * a <code>Set</code> of key purpose OIDs in string format (or
+ * <code>null</code>). Each OID is represented by a set of
+ * nonnegative integers separated by periods.
+ *
+ * @exception IOException
+ * if the OID is invalid, such as the first component being
+ * not 0, 1 or 2 or the second component being greater than
+ * 39.
+ *
+ * @see #getExtendedKeyUsage()
+ */
+ public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException
+ {
+ if (keyPurposeSet == null || keyPurposeSet.isEmpty())
+ {
+ this.keyPurposeSet = keyPurposeSet;
+ }
+ else
+ {
+ this.keyPurposeSet = new HashSet();
+ Iterator iter = keyPurposeSet.iterator();
+ Object obj;
+ KeyPurposeId purposeID;
+ while (iter.hasNext())
+ {
+ obj = iter.next();
+ if (obj instanceof String)
+ {
+ purposeID = (KeyPurposeId)keyPurposeIdMap.get((String)obj);
+ if (purposeID == null)
+ {
+ throw new IOException("unknown purposeID "
+ + (String)obj);
+ }
+ this.keyPurposeSet.add(purposeID);
+ }
+ }
+ }
+ }
+
+ /**
+ * Enables/disables matching all of the subjectAlternativeNames specified in
+ * the {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or
+ * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If
+ * enabled, the <code>X509Certificate</code> must contain all of the
+ * specified subject alternative names. If disabled, the X509Certificate
+ * must contain at least one of the specified subject alternative names.<br />
+ * <br />
+ * The matchAllNames flag is <code>true</code> by default.
+ *
+ * @param matchAllNames
+ * if <code>true</code>, the flag is enabled; if
+ * <code>false</code>, the flag is disabled.
+ *
+ * @see #getMatchAllSubjectAltNames()
+ */
+ public void setMatchAllSubjectAltNames(boolean matchAllNames)
+ {
+ matchAllSubjectAltNames = matchAllNames;
+ }
+
+ /**
+ * Sets the subjectAlternativeNames criterion. The
+ * <code>X509Certificate</code> must contain all or at least one of the
+ * specified subjectAlternativeNames, depending on the value of the
+ * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).<br />
+ * <br />
+ * This method allows the caller to specify, with a single method call, the
+ * complete set of subject alternative names for the subjectAlternativeNames
+ * criterion. The specified value replaces the previous value for the
+ * subjectAlternativeNames criterion.<br />
+ * <br />
+ * The <code>names</code> parameter (if not <code>null</code>) is a
+ * <code>Collection</code> with one entry for each name to be included in
+ * the subject alternative name criterion. Each entry is a <code>List</code>
+ * whose first entry is an <code>Integer</code> (the name type, 0-8) and
+ * whose second entry is a <code>String</code> or a byte array (the name,
+ * in string or ASN.1 DER encoded form, respectively). There can be multiple
+ * names of the same type. If <code>null</code> is supplied as the value
+ * for this argument, no subjectAlternativeNames check will be performed.<br />
+ * <br />
+ * Each subject alternative name in the <code>Collection</code> may be
+ * specified either as a <code>String</code> or as an ASN.1 encoded byte
+ * array. For more details about the formats used, see
+ * {@link #addSubjectAlternativeName(int, String) addSubjectAlternativeName(int type, String name)}
+ * and
+ * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name}).<br />
+ * <br />
+ * Note that the <code>names</code> parameter can contain duplicate names
+ * (same name and name type), but they may be removed from the
+ * <code>Collection</code> of names returned by the
+ * {@link #getSubjectAlternativeNames} method.<br />
+ * <br />
+ * Note that a deep copy is performed on the Collection to protect against
+ * subsequent modifications.
+ *
+ * @param names -
+ * a Collection of names (or null)
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ *
+ * @see #getSubjectAlternativeNames()
+ */
+ public void setSubjectAlternativeNames(Collection names) throws IOException
+ {
+ try
+ {
+ if (names == null || names.isEmpty())
+ {
+ subjectAltNames = null;
+ subjectAltNamesByte = null;
+ }
+ else
+ {
+ subjectAltNames = new HashSet();
+ subjectAltNamesByte = new HashSet();
+ Iterator iter = names.iterator();
+ List item;
+ int type;
+ Object data;
+ while (iter.hasNext())
+ {
+ item = (List)iter.next();
+ type = ((Integer)item.get(0)).intValue();
+ data = item.get(1);
+ if (data instanceof String)
+ {
+ addSubjectAlternativeName(type, (String)data);
+ }
+ else if (data instanceof byte[])
+ {
+ addSubjectAlternativeName(type, (byte[])data);
+ }
+ else
+ {
+ throw new IOException(
+ "parsing error: unknown data type");
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new IOException("parsing exception:\n" + ex.toString());
+ }
+ }
+
+ /**
+ * Adds a name to the subjectAlternativeNames criterion. The
+ * <code>X509Certificate</code> must contain all or at least one of the
+ * specified subjectAlternativeNames, depending on the value of the
+ * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).<br />
+ * <br />
+ * This method allows the caller to add a name to the set of subject
+ * alternative names. The specified name is added to any previous value for
+ * the subjectAlternativeNames criterion. If the specified name is a
+ * duplicate, it may be ignored.<br />
+ * <br />
+ * The name is provided in string format. RFC 822, DNS, and URI names use
+ * the well-established string formats for those types (subject to the
+ * restrictions included in RFC 2459). IPv4 address names are supplied using
+ * dotted quad notation. OID address names are represented as a series of
+ * nonnegative integers separated by periods. And directory names
+ * (distinguished names) are supplied in RFC 2253 format. No standard string
+ * format is defined for otherNames, X.400 names, EDI party names, IPv6
+ * address names, or any other type of names. They should be specified using
+ * the
+ * {@link #addSubjectAlternativeName(int, byte[]) addSubjectAlternativeName(int type, byte [] name)}
+ * method.
+ *
+ * @param type
+ * the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
+ * @param name -
+ * the name in string form (not null)
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ */
+ public void addSubjectAlternativeName(int type, String name)
+ throws IOException
+ {
+ // TODO full implementation of CertUtil.parseGeneralName
+ byte[] encoded = CertUtil.parseGeneralName(type, name);
+ List tmpList = new ArrayList();
+ tmpList.add(Integers.valueOf(type));
+ tmpList.add(name);
+ subjectAltNames.add(tmpList);
+ tmpList.set(1, encoded);
+ subjectAltNamesByte.add(tmpList);
+ }
+
+ /**
+ * Adds a name to the subjectAlternativeNames criterion. The
+ * <code>X509Certificate</code> must contain all or at least one of the
+ * specified subjectAlternativeNames, depending on the value of the
+ * matchAllNames flag (see {@link #setMatchAllSubjectAltNames}).<br />
+ * <br />
+ * This method allows the caller to add a name to the set of subject
+ * alternative names. The specified name is added to any previous value for
+ * the subjectAlternativeNames criterion. If the specified name is a
+ * duplicate, it may be ignored.<br />
+ * <br />
+ * The name is provided as a byte array. This byte array should contain the
+ * DER encoded name, as it would appear in the GeneralName structure defined
+ * in RFC 2459 and X.509. The encoded byte array should only contain the
+ * encoded value of the name, and should not include the tag associated with
+ * the name in the GeneralName structure. The ASN.1 definition of this
+ * structure appears below.<br />
+ * <br />
+ *
+ * <pre>
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Note that the byte array supplied here is cloned to protect against
+ * subsequent modifications.<br />
+ * <br />
+ * <b>TODO: check encoded format</b>
+ *
+ * @param type
+ * the name type (0-8, as listed above)
+ * @param name
+ * a byte array containing the name in ASN.1 DER encoded form
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ */
+ public void addSubjectAlternativeName(int type, byte[] name)
+ throws IOException
+ {
+ // TODO check encoded format
+ List tmpList = new ArrayList();
+ tmpList.add(Integers.valueOf(type));
+ tmpList.add(name.clone());
+ subjectAltNames.add(tmpList);
+ subjectAltNamesByte.add(tmpList);
+ }
+
+ /**
+ * Sets the name constraints criterion. The <code>X509Certificate</code>
+ * must have subject and subject alternative names that meet the specified
+ * name constraints.<br />
+ * <br />
+ * The name constraints are specified as a byte array. This byte array
+ * should contain the DER encoded form of the name constraints, as they
+ * would appear in the NameConstraints structure defined in RFC 2459 and
+ * X.509. The ASN.1 definition of this structure appears below.<br />
+ * <br />
+ *
+ * <pre>
+ * NameConstraints ::= SEQUENCE {
+ * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+ *
+ * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+ *
+ * GeneralSubtree ::= SEQUENCE {
+ * base GeneralName,
+ * minimum [0] BaseDistance DEFAULT 0,
+ * maximum [1] BaseDistance OPTIONAL }
+ *
+ * BaseDistance ::= INTEGER (0..MAX)
+ *
+ * GeneralName ::= CHOICE {
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER}
+ * </pre>
+ *
+ * <br />
+ * <br />
+ * Note that the byte array supplied here is cloned to protect against
+ * subsequent modifications.<br />
+ * <br />
+ * <b>TODO: implement this</b>
+ *
+ * @param bytes
+ * a byte array containing the ASN.1 DER encoding of a
+ * NameConstraints extension to be used for checking name
+ * constraints. Only the value of the extension is included, not
+ * the OID or criticality flag. Can be <code>null</code>, in
+ * which case no name constraints check will be performed
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ * @exception UnsupportedOperationException
+ * because this method is not supported
+ * @see #getNameConstraints()
+ */
+ public void setNameConstraints(byte[] bytes) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Sets the basic constraints constraint. If the value is greater than or
+ * equal to zero, <code>X509Certificates</code> must include a
+ * basicConstraints extension with a pathLen of at least this value. If the
+ * value is -2, only end-entity certificates are accepted. If the value is
+ * -1, no check is done.<br />
+ * <br />
+ * This constraint is useful when building a certification path forward
+ * (from the target toward the trust anchor. If a partial path has been
+ * built, any candidate certificate must have a maxPathLen value greater
+ * than or equal to the number of certificates in the partial path.
+ *
+ * @param minMaxPathLen
+ * the value for the basic constraints constraint
+ *
+ * @exception IllegalArgumentException
+ * if the value is less than -2
+ *
+ * @see #getBasicConstraints()
+ */
+ public void setBasicConstraints(int minMaxPathLen)
+ {
+ if (minMaxPathLen < -2)
+ {
+ throw new IllegalArgumentException("minMaxPathLen must be >= -2");
+ }
+
+ this.minMaxPathLen = minMaxPathLen;
+ }
+
+ /**
+ * Sets the policy constraint. The X509Certificate must include at least one
+ * of the specified policies in its certificate policies extension. If
+ * certPolicySet is empty, then the X509Certificate must include at least
+ * some specified policy in its certificate policies extension. If
+ * certPolicySet is null, no policy check will be performed.<br />
+ * <br />
+ * Note that the Set is cloned to protect against subsequent modifications.<br />
+ * <br />
+ * <b>TODO: implement match check for this</b>
+ *
+ * @param certPolicySet
+ * a Set of certificate policy OIDs in string format (or null).
+ * Each OID is represented by a set of nonnegative integers
+ * separated by periods.
+ *
+ * @exception IOException
+ * if a parsing error occurs on the OID such as the first
+ * component is not 0, 1 or 2 or the second component is
+ * greater than 39.
+ *
+ * @see #getPolicy()
+ */
+ public void setPolicy(Set certPolicySet) throws IOException
+ {
+ if (certPolicySet == null)
+ {
+ policy = null;
+ policyOID = null;
+ }
+ else
+ {
+ policyOID = new HashSet();
+ Iterator iter = certPolicySet.iterator();
+ Object item;
+ while (iter.hasNext())
+ {
+ item = iter.next();
+ if (item instanceof String)
+ {
+ CertUtil.parseOID((String)item);
+ policyOID.add(new ASN1ObjectIdentifier((String)item));
+ }
+ else
+ {
+ throw new IOException(
+ "certPolicySet contains null values or non String objects");
+ }
+ }
+ policy = new HashSet(certPolicySet);
+ }
+ }
+
+ /**
+ * Sets the pathToNames criterion. The <code>X509Certificate</code> must
+ * not include name constraints that would prohibit building a path to the
+ * specified names.<br />
+ * <br />
+ * This method allows the caller to specify, with a single method call, the
+ * complete set of names which the <code>X509Certificates</code>'s name
+ * constraints must permit. The specified value replaces the previous value
+ * for the pathToNames criterion.<br />
+ * <br />
+ * This constraint is useful when building a certification path forward
+ * (from the target toward the trust anchor. If a partial path has been
+ * built, any candidate certificate must not include name constraints that
+ * would prohibit building a path to any of the names in the partial path.<br />
+ * <br />
+ * The names parameter (if not <code>null</code>) is a
+ * <code>Collection</code> with one entry for each name to be included in
+ * the pathToNames criterion. Each entry is a <code>List</code> whose
+ * first entry is an Integer (the name type, 0-8) and whose second entry is
+ * a <code>String</code> or a byte array (the name, in string or ASN.1 DER
+ * encoded form, respectively). There can be multiple names of the same
+ * type. If <code>null</code> is supplied as the value for this argument,
+ * no pathToNames check will be performed.<br />
+ * <br />
+ * Each name in the Collection may be specified either as a String or as an
+ * ASN.1 encoded byte array. For more details about the formats used, see
+ * {@link #addPathToName(int, String) addPathToName(int type, String name)}
+ * and
+ * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)}.<br />
+ * <br />
+ * Note that the names parameter can contain duplicate names (same name and
+ * name type), but they may be removed from the Collection of names returned
+ * by the {@link #getPathToNames} method.<br />
+ * <br />
+ * Note that a deep copy is performed on the Collection to protect against
+ * subsequent modifications.<br />
+ * <br />
+ * <b>TODO: implement this match check for this</b>
+ *
+ * @param names
+ * a Collection with one entry per name (or <code>null</code>)
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ * @exception UnsupportedOperationException
+ * because this method is not supported
+ *
+ * @see #getPathToNames()
+ */
+ public void setPathToNames(Collection names) throws IOException
+ {
+ try
+ {
+ if (names == null || names.isEmpty())
+ {
+ pathToNames = null;
+ pathToNamesByte = null;
+ }
+ else
+ {
+ pathToNames = new HashSet();
+ pathToNamesByte = new HashSet();
+ Iterator iter = names.iterator();
+ List item;
+ int type;
+ Object data;
+
+ while (iter.hasNext())
+ {
+ item = (List)iter.next();
+ type = ((Integer)item.get(0)).intValue();
+ data = item.get(1);
+ if (data instanceof String)
+ {
+ addPathToName(type, (String)data);
+ }
+ else if (data instanceof byte[])
+ {
+ addPathToName(type, (byte[])data);
+ }
+ else
+ {
+ throw new IOException(
+ "parsing error: unknown data type");
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new IOException("parsing exception:\n" + ex.toString());
+ }
+ }
+
+ /**
+ * Adds a name to the pathToNames criterion. The
+ * <code>X509Certificate</code> must not include name constraints that
+ * would prohibit building a path to the specified name.<br />
+ * <br />
+ * This method allows the caller to add a name to the set of names which the
+ * <code>X509Certificates</code>'s name constraints must permit. The
+ * specified name is added to any previous value for the pathToNames
+ * criterion. If the name is a duplicate, it may be ignored.<br />
+ * <br />
+ * The name is provided in string format. RFC 822, DNS, and URI names use
+ * the well-established string formats for those types (subject to the
+ * restrictions included in RFC 2459). IPv4 address names are supplied using
+ * dotted quad notation. OID address names are represented as a series of
+ * nonnegative integers separated by periods. And directory names
+ * (distinguished names) are supplied in RFC 2253 format. No standard string
+ * format is defined for otherNames, X.400 names, EDI party names, IPv6
+ * address names, or any other type of names. They should be specified using
+ * the
+ * {@link #addPathToName(int, byte[]) addPathToName(int type, byte [] name)}
+ * method.<br />
+ * <br />
+ * <b>TODO: implement this match check for this</b>
+ *
+ * @param type
+ * the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
+ * @param name
+ * the name in string form
+ *
+ * @exceptrion IOException if a parsing error occurs
+ */
+ public void addPathToName(int type, String name) throws IOException
+ {
+ // TODO full implementation of CertUtil.parseGeneralName
+ byte[] encoded = CertUtil.parseGeneralName(type, name);
+ List tmpList = new ArrayList();
+ tmpList.add(Integers.valueOf(type));
+ tmpList.add(name);
+ pathToNames.add(tmpList);
+ tmpList.set(1, encoded);
+ pathToNamesByte.add(tmpList);
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a name to the pathToNames criterion. The
+ * <code>X509Certificate</code> must not include name constraints that
+ * would prohibit building a path to the specified name.<br />
+ * <br />
+ * This method allows the caller to add a name to the set of names which the
+ * <code>X509Certificates</code>'s name constraints must permit. The
+ * specified name is added to any previous value for the pathToNames
+ * criterion. If the name is a duplicate, it may be ignored.<br />
+ * <br />
+ * The name is provided as a byte array. This byte array should contain the
+ * DER encoded name, as it would appear in the GeneralName structure defined
+ * in RFC 2459 and X.509. The ASN.1 definition of this structure appears in
+ * the documentation for
+ * {@link #addSubjectAlternativeName(int,byte[]) addSubjectAlternativeName(int type, byte[] name)}.<br />
+ * <br />
+ * Note that the byte array supplied here is cloned to protect against
+ * subsequent modifications.<br />
+ * <br />
+ * <b>TODO: implement this match check for this</b>
+ *
+ * @param type
+ * the name type (0-8, as specified in RFC 2459, section 4.2.1.7)
+ * @param name
+ * a byte array containing the name in ASN.1 DER encoded form
+ *
+ * @exception IOException
+ * if a parsing error occurs
+ */
+ public void addPathToName(int type, byte[] name) throws IOException
+ {
+ // TODO check encoded format
+ List tmpList = new ArrayList();
+ tmpList.add(Integers.valueOf(type));
+ tmpList.add(name.clone());
+ pathToNames.add(tmpList);
+ pathToNamesByte.add(tmpList);
+ }
+
+ /**
+ * Returns the certificateEquals criterion. The specified
+ * <code>X509Certificate</code> must be equal to the
+ * <code>X509Certificate</code> passed to the match method. If
+ * <code>null</code>, this check is not applied.
+ *
+ * @retrun the <code>X509Certificate</code> to match (or <code>null</code>)
+ *
+ * @see #setCertificate(java.security.cert.X509Certificate)
+ */
+ public X509Certificate getCertificate()
+ {
+ return x509Cert;
+ }
+
+ /**
+ * Returns the serialNumber criterion. The specified serial number must
+ * match the certificate serial number in the <code>X509Certificate</code>.
+ * If <code>null</code>, any certificate serial number will do.
+ *
+ * @return the certificate serial number to match (or <code>null</code>)
+ *
+ * @see #setSerialNumber(java.math.BigInteger)
+ */
+ public BigInteger getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ /**
+ * Returns the issuer criterion as a String. This distinguished name must
+ * match the issuer distinguished name in the <code>X509Certificate</code>.
+ * If <code>null</code>, the issuer criterion is disabled and any issuer
+ * distinguished name will do.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a distinguished
+ * name, in RFC 2253 format.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for formatiing
+ * byte[] issuerDN to String.
+ *
+ * @return the required issuer distinguished name in RFC 2253 format (or
+ * <code>null</code>)
+ */
+ public String getIssuerAsString()
+ {
+ if (issuerDN instanceof String)
+ {
+ return new String((String)issuerDN);
+ }
+ else if (issuerDNX509 != null)
+ {
+ return issuerDNX509.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the issuer criterion as a byte array. This distinguished name
+ * must match the issuer distinguished name in the
+ * <code>X509Certificate</code>. If <code>null</code>, the issuer
+ * criterion is disabled and any issuer distinguished name will do.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a byte array
+ * containing a single DER encoded distinguished name, as defined in X.501.
+ * The ASN.1 notation for this structure is supplied in the documentation
+ * for {@link #setIssuer(byte[]) setIssuer(byte [] issuerDN)}.<br />
+ * <br />
+ * Note that the byte array returned is cloned to protect against subsequent
+ * modifications.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.DEROutputStream DEROutputStream},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name} to gnerate byte[]
+ * output for String issuerDN.
+ *
+ * @return a byte array containing the required issuer distinguished name in
+ * ASN.1 DER format (or <code>null</code>)
+ *
+ * @exception IOException
+ * if an encoding error occurs
+ */
+ public byte[] getIssuerAsBytes() throws IOException
+ {
+ if (issuerDN instanceof byte[])
+ {
+ return (byte[])((byte[])issuerDN).clone();
+ }
+ else if (issuerDNX509 != null)
+ {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+
+ derOutStream.writeObject(issuerDNX509.toASN1Primitive());
+ derOutStream.close();
+
+ return outStream.toByteArray();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the subject criterion as a String. This distinguished name must
+ * match the subject distinguished name in the <code>X509Certificate</code>.
+ * If <code>null</code>, the subject criterion is disabled and any
+ * subject distinguished name will do.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a distinguished
+ * name, in RFC 2253 format.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.x509.X509Name X509Name} for formatiing
+ * byte[] subjectDN to String.
+ *
+ * @return the required subject distinguished name in RFC 2253 format (or
+ * <code>null</code>)
+ */
+ public String getSubjectAsString()
+ {
+ if (subjectDN instanceof String)
+ {
+ return new String((String)subjectDN);
+ }
+ else if (subjectDNX509 != null)
+ {
+ return subjectDNX509.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the subject criterion as a byte array. This distinguished name
+ * must match the subject distinguished name in the
+ * <code>X509Certificate</code>. If <code>null</code>, the subject
+ * criterion is disabled and any subject distinguished name will do.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a byte array
+ * containing a single DER encoded distinguished name, as defined in X.501.
+ * The ASN.1 notation for this structure is supplied in the documentation
+ * for {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.<br />
+ * <br />
+ * Note that the byte array returned is cloned to protect against subsequent
+ * modifications.<br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.DEROutputStream DEROutputStream},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name} to gnerate byte[]
+ * output for String subjectDN.
+ *
+ * @return a byte array containing the required subject distinguished name
+ * in ASN.1 DER format (or <code>null</code>)
+ *
+ * @exception IOException
+ * if an encoding error occurs
+ */
+ public byte[] getSubjectAsBytes() throws IOException
+ {
+ if (subjectDN instanceof byte[])
+ {
+ return (byte[])((byte[])subjectDN).clone();
+ }
+ else if (subjectDNX509 != null)
+ {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ DEROutputStream derOutStream = new DEROutputStream(outStream);
+
+ derOutStream.writeObject(subjectDNX509.toASN1Primitive());
+ derOutStream.close();
+
+ return outStream.toByteArray();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the subjectKeyIdentifier criterion. The
+ * <code>X509Certificate</code> must contain a SubjectKeyIdentifier
+ * extension with the specified value. If <code>null</code>, no
+ * subjectKeyIdentifier check will be done.<br />
+ * <br />
+ * Note that the byte array returned is cloned to protect against subsequent
+ * modifications.
+ *
+ * @return the key identifier (or <code>null</code>)
+ *
+ * @see #setSubjectKeyIdentifier
+ */
+ public byte[] getSubjectKeyIdentifier()
+ {
+ if (subjectKeyID != null)
+ {
+ return (byte[])subjectKeyID.clone();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the authorityKeyIdentifier criterion. The
+ * <code>X509Certificate</code> must contain a AuthorityKeyIdentifier
+ * extension with the specified value. If <code>null</code>, no
+ * authorityKeyIdentifier check will be done.<br />
+ * <br />
+ * Note that the byte array returned is cloned to protect against subsequent
+ * modifications.
+ *
+ * @return the key identifier (or <code>null</code>)
+ *
+ * @see #setAuthorityKeyIdentifier
+ */
+ public byte[] getAuthorityKeyIdentifier()
+ {
+ if (authorityKeyID != null)
+ {
+ return (byte[])authorityKeyID.clone();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the certificateValid criterion. The specified date must fall
+ * within the certificate validity period for the
+ * <code>X509Certificate</code>. If <code>null</code>, no
+ * certificateValid check will be done.<br />
+ * <br />
+ * Note that the <code>Date</code> returned is cloned to protect against
+ * subsequent modifications.
+ *
+ * @return the <code>Date</code> to check (or <code>null</code>)
+ *
+ * @see #setCertificateValid
+ */
+ public Date getCertificateValid()
+ {
+ if (certValid != null)
+ {
+ return new Date(certValid.getTime());
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the privateKeyValid criterion. The specified date must fall
+ * within the private key validity period for the
+ * <code>X509Certificate</code>. If <code>null</code>, no
+ * privateKeyValid check will be done.<br />
+ * <br />
+ * Note that the <code>Date</code> returned is cloned to protect against
+ * subsequent modifications.
+ *
+ * @return the <code>Date</code> to check (or <code>null</code>)
+ *
+ * @see #setPrivateKeyValid
+ */
+ public Date getPrivateKeyValid()
+ {
+ if (privateKeyValid != null)
+ {
+ return new Date(privateKeyValid.getTime());
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the subjectPublicKeyAlgID criterion. The
+ * <code>X509Certificate</code> must contain a subject public key with the
+ * specified algorithm. If <code>null</code>, no subjectPublicKeyAlgID
+ * check will be done.
+ *
+ * @return the object identifier (OID) of the signature algorithm to check
+ * for (or <code>null</code>). An OID is represented by a set of
+ * nonnegative integers separated by periods.
+ *
+ * @see #setSubjectPublicKeyAlgID
+ */
+ public String getSubjectPublicKeyAlgID()
+ {
+ if (subjectKeyAlgID != null)
+ {
+ return subjectKeyAlgID.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the subjectPublicKey criterion. The <code>X509Certificate</code>
+ * must contain the specified subject public key. If <code>null</code>,
+ * no subjectPublicKey check will be done.
+ *
+ * @return the subject public key to check for (or <code>null</code>)
+ *
+ * @see #setSubjectPublicKey
+ */
+ public PublicKey getSubjectPublicKey()
+ {
+ return subjectPublicKey;
+ }
+
+ /**
+ * Returns the keyUsage criterion. The <code>X509Certificate</code> must
+ * allow the specified keyUsage values. If null, no keyUsage check will be
+ * done.<br />
+ * <br />
+ * Note that the boolean array returned is cloned to protect against
+ * subsequent modifications.
+ *
+ * @return a boolean array in the same format as the boolean array returned
+ * by
+ * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}.
+ * Or <code>null</code>.
+ *
+ * @see #setKeyUsage
+ */
+ public boolean[] getKeyUsage()
+ {
+ if (keyUsage != null)
+ {
+ return (boolean[])keyUsage.clone();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the extendedKeyUsage criterion. The <code>X509Certificate</code>
+ * must allow the specified key purposes in its extended key usage
+ * extension. If the <code>keyPurposeSet</code> returned is empty or
+ * <code>null</code>, no extendedKeyUsage check will be done. Note that
+ * an <code>X509Certificate</code> that has no extendedKeyUsage extension
+ * implicitly allows all key purposes.
+ *
+ * @return an immutable <code>Set</code> of key purpose OIDs in string
+ * format (or <code>null</code>)
+ * @see #setExtendedKeyUsage
+ */
+ public Set getExtendedKeyUsage()
+ {
+ if (keyPurposeSet == null || keyPurposeSet.isEmpty())
+ {
+ return keyPurposeSet;
+ }
+
+ Set returnSet = new HashSet();
+ Iterator iter = keyPurposeSet.iterator();
+ while (iter.hasNext())
+ {
+ returnSet.add(iter.next().toString());
+ }
+
+ return Collections.unmodifiableSet(returnSet);
+ }
+
+ /**
+ * Indicates if the <code>X509Certificate</code> must contain all or at
+ * least one of the subjectAlternativeNames specified in the
+ * {@link #setSubjectAlternativeNames setSubjectAlternativeNames} or
+ * {@link #addSubjectAlternativeName addSubjectAlternativeName} methods. If
+ * <code>true</code>, the <code>X509Certificate</code> must contain all
+ * of the specified subject alternative names. If <code>false</code>, the
+ * <code>X509Certificate</code> must contain at least one of the specified
+ * subject alternative names.
+ *
+ * @return <code>true</code> if the flag is enabled; <code>false</code>
+ * if the flag is disabled. The flag is <code>true</code> by
+ * default.
+ *
+ * @see #setMatchAllSubjectAltNames
+ */
+ public boolean getMatchAllSubjectAltNames()
+ {
+ return matchAllSubjectAltNames;
+ }
+
+ /**
+ * Returns a copy of the subjectAlternativeNames criterion. The
+ * <code>X509Certificate</code> must contain all or at least one of the
+ * specified subjectAlternativeNames, depending on the value of the
+ * matchAllNames flag (see {@link #getMatchAllSubjectAltNames
+ * getMatchAllSubjectAltNames}). If the value returned is <code>null</code>,
+ * no subjectAlternativeNames check will be performed.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a
+ * <code>Collection</code> with one entry for each name to be included in
+ * the subject alternative name criterion. Each entry is a <code>List</code>
+ * whose first entry is an <code>Integer</code> (the name type, 0-8) and
+ * whose second entry is a <code>String</code> or a byte array (the name,
+ * in string or ASN.1 DER encoded form, respectively). There can be multiple
+ * names of the same type. Note that the <code>Collection</code> returned
+ * may contain duplicate names (same name and name type).<br />
+ * <br />
+ * Each subject alternative name in the <code>Collection</code> may be
+ * specified either as a <code>String</code> or as an ASN.1 encoded byte
+ * array. For more details about the formats used, see
+ * {@link #addSubjectAlternativeName(int type, String name)
+ * addSubjectAlternativeName(int type, String name)} and
+ * {@link #addSubjectAlternativeName(int type, byte [] name)
+ * addSubjectAlternativeName(int type, byte [] name)}.<br />
+ * <br />
+ * Note that a deep copy is performed on the <code>Collection</code> to
+ * protect against subsequent modifications.
+ *
+ * @return a <code>Collection</code> of names (or <code>null</code>)
+ *
+ * @see #setSubjectAlternativeNames
+ */
+ public Collection getSubjectAlternativeNames()
+ {
+ if (subjectAltNames != null)
+ {
+ return null;
+ }
+
+ Set returnAltNames = new HashSet();
+ List returnList;
+ Iterator iter = subjectAltNames.iterator();
+ List obj;
+ while (iter.hasNext())
+ {
+ obj = (List)iter.next();
+ returnList = new ArrayList();
+ returnList.add(obj.get(0));
+ if (obj.get(1) instanceof byte[])
+ {
+ returnList.add(((byte[])obj.get(1)).clone());
+ }
+ else
+ {
+ returnList.add(obj.get(1));
+ }
+ returnAltNames.add(returnList);
+ }
+
+ return returnAltNames;
+ }
+
+ /**
+ * Returns the name constraints criterion. The <code>X509Certificate</code>
+ * must have subject and subject alternative names that meet the specified
+ * name constraints.<br />
+ * <br />
+ * The name constraints are returned as a byte array. This byte array
+ * contains the DER encoded form of the name constraints, as they would
+ * appear in the NameConstraints structure defined in RFC 2459 and X.509.
+ * The ASN.1 notation for this structure is supplied in the documentation
+ * for
+ * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.<br />
+ * <br />
+ * Note that the byte array returned is cloned to protect against subsequent
+ * modifications.<br />
+ * <br />
+ * <b>TODO: implement this</b>
+ *
+ * @return a byte array containing the ASN.1 DER encoding of a
+ * NameConstraints extension used for checking name constraints.
+ * <code>null</code> if no name constraints check will be
+ * performed.
+ *
+ * @exception UnsupportedOperationException
+ * because this method is not supported
+ *
+ * @see #setNameConstraints
+ */
+ public byte[] getNameConstraints()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the basic constraints constraint. If the value is greater than or
+ * equal to zero, the <code>X509Certificates</code> must include a
+ * basicConstraints extension with a pathLen of at least this value. If the
+ * value is -2, only end-entity certificates are accepted. If the value is
+ * -1, no basicConstraints check is done.
+ *
+ * @return the value for the basic constraints constraint
+ *
+ * @see #setBasicConstraints
+ */
+ public int getBasicConstraints()
+ {
+ return minMaxPathLen;
+ }
+
+ /**
+ * Returns the policy criterion. The <code>X509Certificate</code> must
+ * include at least one of the specified policies in its certificate
+ * policies extension. If the <code>Set</code> returned is empty, then the
+ * <code>X509Certificate</code> must include at least some specified
+ * policy in its certificate policies extension. If the <code>Set</code>
+ * returned is <code>null</code>, no policy check will be performed.
+ *
+ * @return an immutable <code>Set</code> of certificate policy OIDs in
+ * string format (or <code>null</code>)
+ *
+ * @see #setPolicy
+ */
+ public Set getPolicy()
+ {
+ if (policy == null)
+ {
+ return null;
+ }
+
+ return Collections.unmodifiableSet(policy);
+ }
+
+ /**
+ * Returns a copy of the pathToNames criterion. The
+ * <code>X509Certificate</code> must not include name constraints that
+ * would prohibit building a path to the specified names. If the value
+ * returned is <code>null</code>, no pathToNames check will be performed.<br />
+ * <br />
+ * If the value returned is not <code>null</code>, it is a
+ * <code>Collection</code> with one entry for each name to be included in
+ * the pathToNames criterion. Each entry is a <code>List</code> whose
+ * first entry is an <code>Integer</code> (the name type, 0-8) and whose
+ * second entry is a <code>String</code> or a byte array (the name, in
+ * string or ASN.1 DER encoded form, respectively). There can be multiple
+ * names of the same type. Note that the <code>Collection</code> returned
+ * may contain duplicate names (same name and name type).<br />
+ * <br />
+ * Each name in the <code>Collection</code> may be specified either as a
+ * <code>String</code> or as an ASN.1 encoded byte array. For more details
+ * about the formats used, see {@link #addPathToName(int type, String name)
+ * addPathToName(int type, String name)} and
+ * {@link #addPathToName(int type, byte [] name) addPathToName(int type,
+ * byte [] name)}.<br />
+ * <br />
+ * Note that a deep copy is performed on the <code>Collection</code> to
+ * protect against subsequent modifications.
+ *
+ * @return a <code>Collection</code> of names (or <code>null</code>)
+ *
+ * @see #setPathToNames
+ */
+ public Collection getPathToNames()
+ {
+ if (pathToNames == null)
+ {
+ return null;
+ }
+
+ Set returnPathToNames = new HashSet();
+ List returnList;
+ Iterator iter = pathToNames.iterator();
+ List obj;
+
+ while (iter.hasNext())
+ {
+ obj = (List)iter.next();
+ returnList = new ArrayList();
+ returnList.add(obj.get(0));
+ if (obj.get(1) instanceof byte[])
+ {
+ returnList.add(((byte[])obj.get(1)).clone());
+ }
+ else
+ {
+ returnList.add(obj.get(1));
+ }
+ returnPathToNames.add(returnList);
+ }
+
+ return returnPathToNames;
+ }
+
+ /**
+ * Return a printable representation of the <code>CertSelector</code>.<br />
+ * <br />
+ * <b>TODO: implement output for currently unsupported options(name
+ * constraints)</b><br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object},
+ * {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId}
+ *
+ * @return a <code>String</code> describing the contents of the
+ * <code>CertSelector</code>
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("X509CertSelector: [\n");
+ if (x509Cert != null)
+ {
+ sb.append(" Certificate: ").append(x509Cert).append('\n');
+ }
+ if (serialNumber != null)
+ {
+ sb.append(" Serial Number: ").append(serialNumber).append('\n');
+ }
+ if (issuerDN != null)
+ {
+ sb.append(" Issuer: ").append(getIssuerAsString()).append('\n');
+ }
+ if (subjectDN != null)
+ {
+ sb.append(" Subject: ").append(getSubjectAsString()).append('\n');
+ }
+ try
+ {
+ if (subjectKeyID != null)
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ subjectKeyID);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object derObject = derInStream.readObject();
+ sb.append(" Subject Key Identifier: ")
+ .append(ASN1Dump.dumpAsString(derObject)).append('\n');
+ }
+ if (authorityKeyID != null)
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ authorityKeyID);
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object derObject = derInStream.readObject();
+ sb.append(" Authority Key Identifier: ")
+ .append(ASN1Dump.dumpAsString(derObject)).append('\n');
+ }
+ }
+ catch (IOException ex)
+ {
+ sb.append(ex.getMessage()).append('\n');
+ }
+ if (certValid != null)
+ {
+ sb.append(" Certificate Valid: ").append(certValid).append('\n');
+ }
+ if (privateKeyValid != null)
+ {
+ sb.append(" Private Key Valid: ").append(privateKeyValid)
+ .append('\n');
+ }
+ if (subjectKeyAlgID != null)
+ {
+ sb.append(" Subject Public Key AlgID: ")
+ .append(subjectKeyAlgID).append('\n');
+ }
+ if (subjectPublicKey != null)
+ {
+ sb.append(" Subject Public Key: ").append(subjectPublicKey)
+ .append('\n');
+ }
+ if (keyUsage != null)
+ {
+ sb.append(" Key Usage: ").append(keyUsage).append('\n');
+ }
+ if (keyPurposeSet != null)
+ {
+ sb.append(" Extended Key Usage: ").append(keyPurposeSet)
+ .append('\n');
+ }
+ if (policy != null)
+ {
+ sb.append(" Policy: ").append(policy).append('\n');
+ }
+ sb.append(" matchAllSubjectAltNames flag: ")
+ .append(matchAllSubjectAltNames).append('\n');
+ if (subjectAltNamesByte != null)
+ {
+ sb.append(" SubjectAlternativNames: \n[");
+ Iterator iter = subjectAltNamesByte.iterator();
+ List obj;
+ try
+ {
+ while (iter.hasNext())
+ {
+ obj = (List)iter.next();
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ (byte[])obj.get(1));
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object derObject = derInStream.readObject();
+ sb.append(" Type: ").append(obj.get(0)).append(" Data: ")
+ .append(ASN1Dump.dumpAsString(derObject)).append('\n');
+ }
+ }
+ catch (IOException ex)
+ {
+ sb.append(ex.getMessage()).append('\n');
+ }
+ sb.append("]\n");
+ }
+ if (pathToNamesByte != null)
+ {
+ sb.append(" PathToNamesNames: \n[");
+ Iterator iter = pathToNamesByte.iterator();
+ List obj;
+ try
+ {
+ while (iter.hasNext())
+ {
+ obj = (List)iter.next();
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ (byte[])obj.get(1));
+ ASN1InputStream derInStream = new ASN1InputStream(inStream);
+ ASN1Object derObject = derInStream.readObject();
+ sb.append(" Type: ").append(obj.get(0)).append(" Data: ")
+ .append(ASN1Dump.dumpAsString(derObject)).append('\n');
+ }
+ }
+ catch (IOException ex)
+ {
+ sb.append(ex.getMessage()).append('\n');
+ }
+ sb.append("]\n");
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+
+ /**
+ * Decides whether a <code>Certificate</code> should be selected.<br />
+ * <br />
+ * <b>TODO: implement missing tests (name constraints and path to names)</b><br />
+ * <br />
+ * Uses {@link org.spongycastle.asn1.ASN1InputStream ASN1InputStream},
+ * {@link org.spongycastle.asn1.ASN1Sequence ASN1Sequence},
+ * {@link org.spongycastle.asn1.ASN1ObjectIdentifier ASN1ObjectIdentifier},
+ * {@link org.spongycastle.asn1.ASN1Object ASN1Object},
+ * {@link org.spongycastle.asn1.DERGeneralizedTime DERGeneralizedTime},
+ * {@link org.spongycastle.asn1.x509.X509Name X509Name},
+ * {@link org.spongycastle.asn1.x509.X509Extensions X509Extensions},
+ * {@link org.spongycastle.asn1.x509.ExtendedKeyUsage ExtendedKeyUsage},
+ * {@link org.spongycastle.asn1.x509.KeyPurposeId KeyPurposeId},
+ * {@link org.spongycastle.asn1.x509.SubjectPublicKeyInfo SubjectPublicKeyInfo},
+ * {@link org.spongycastle.asn1.x509.AlgorithmIdentifier AlgorithmIdentifier}
+ * to access X509 extensions
+ *
+ * @param cert
+ * the <code>Certificate</code> to be checked
+ *
+ * @return <code>true</code> if the <code>Certificate</code> should be
+ * selected, <code>false</code> otherwise
+ */
+ public boolean match(Certificate cert)
+ {
+ boolean[] booleanArray;
+ List tempList;
+ Iterator tempIter;
+
+ if (!(cert instanceof X509Certificate))
+ {
+ return false;
+ }
+ X509Certificate certX509 = (X509Certificate)cert;
+
+ if (x509Cert != null && !x509Cert.equals(certX509))
+ {
+ return false;
+ }
+ if (serialNumber != null
+ && !serialNumber.equals(certX509.getSerialNumber()))
+ {
+ return false;
+ }
+ try
+ {
+ if (issuerDNX509 != null)
+ {
+ if (!issuerDNX509.equals(PrincipalUtil
+ .getIssuerX509Principal(certX509), true))
+ {
+ return false;
+ }
+ }
+ if (subjectDNX509 != null)
+ {
+ if (!subjectDNX509.equals(PrincipalUtil
+ .getSubjectX509Principal(certX509), true))
+ {
+ return false;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ if (subjectKeyID != null)
+ {
+ byte[] data = certX509
+ .getExtensionValue(X509Extensions.SubjectKeyIdentifier
+ .getId());
+ if (data == null)
+ {
+ return false;
+ }
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ byte[] testData = ((ASN1OctetString)derInputStream.readObject())
+ .getOctets();
+ if (!Arrays.equals(subjectKeyID, testData))
+ {
+ return false;
+ }
+ }
+ catch (IOException ex)
+ {
+ return false;
+ }
+ }
+ if (authorityKeyID != null)
+ {
+ byte[] data = certX509
+ .getExtensionValue(X509Extensions.AuthorityKeyIdentifier
+ .getId());
+ if (data == null)
+ {
+ return false;
+ }
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ byte[] testData = ((ASN1OctetString)derInputStream.readObject())
+ .getOctets();
+ if (!Arrays.equals(authorityKeyID, testData))
+ {
+ return false;
+ }
+ }
+ catch (IOException ex)
+ {
+ return false;
+ }
+ }
+ if (certValid != null)
+ {
+ if (certX509.getNotAfter() != null
+ && certValid.after(certX509.getNotAfter()))
+ {
+ return false;
+ }
+ if (certX509.getNotBefore() != null
+ && certValid.before(certX509.getNotBefore()))
+ {
+ return false;
+ }
+ }
+ if (privateKeyValid != null)
+ {
+ try
+ {
+ byte[] data = certX509
+ .getExtensionValue(X509Extensions.PrivateKeyUsagePeriod
+ .getId());
+ if (data != null)
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ inStream = new ByteArrayInputStream(
+ ((ASN1OctetString)derInputStream.readObject())
+ .getOctets());
+ derInputStream = new ASN1InputStream(inStream);
+ // TODO fix this, Sequence contains tagged objects
+ ASN1Sequence derObject = (ASN1Sequence)derInputStream
+ .readObject();
+ DERGeneralizedTime derDate = DERGeneralizedTime
+ .getInstance(derObject.getObjectAt(0));
+ SimpleDateFormat dateF = new SimpleDateFormat(
+ "yyyyMMddHHmmssZ");
+ if (privateKeyValid.before(dateF.parse(derDate.getTime())))
+ {
+ return false;
+ }
+ derDate = DERGeneralizedTime.getInstance(derObject
+ .getObjectAt(1));
+ if (privateKeyValid.after(dateF.parse(derDate.getTime())))
+ {
+ return false;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+ if (subjectKeyAlgID != null)
+ {
+ try
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ certX509.getPublicKey().getEncoded());
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(
+ (ASN1Sequence)derInputStream.readObject());
+ AlgorithmIdentifier algInfo = publicKeyInfo.getAlgorithmId();
+ if (!algInfo.getObjectId().equals(subjectKeyAlgID))
+ {
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+ if (subjectPublicKeyByte != null)
+ {
+ if (!Arrays.equals(subjectPublicKeyByte, certX509.getPublicKey()
+ .getEncoded()))
+ {
+ return false;
+ }
+ }
+ if (subjectPublicKey != null)
+ {
+ if (!subjectPublicKey.equals(certX509.getPublicKey()))
+ {
+ return false;
+ }
+ }
+ if (keyUsage != null)
+ {
+ booleanArray = certX509.getKeyUsage();
+ if (booleanArray != null)
+ {
+ for (int i = 0; i < keyUsage.length; i++)
+ {
+ if (keyUsage[i]
+ && (booleanArray.length <= i || !booleanArray[i]))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ if (keyPurposeSet != null && !keyPurposeSet.isEmpty())
+ {
+ try
+ {
+ byte[] data = certX509
+ .getExtensionValue(X509Extensions.ExtendedKeyUsage
+ .getId());
+ if (data != null)
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ ExtendedKeyUsage extendedKeyUsage = ExtendedKeyUsage.getInstance(
+ (ASN1Sequence)derInputStream.readObject());
+ tempIter = keyPurposeSet.iterator();
+ while (tempIter.hasNext())
+ {
+ if (!extendedKeyUsage
+ .hasKeyPurposeId((KeyPurposeId)tempIter.next()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+ if (minMaxPathLen != -1)
+ {
+ if (minMaxPathLen == -2 && certX509.getBasicConstraints() != -1)
+ {
+ return false;
+ }
+ if (minMaxPathLen >= 0
+ && certX509.getBasicConstraints() < minMaxPathLen)
+ {
+ return false;
+ }
+ }
+ if (policyOID != null)
+ {
+ try
+ {
+ byte[] data = certX509
+ .getExtensionValue(X509Extensions.CertificatePolicies
+ .getId());
+ if (data == null)
+ {
+ return false;
+ }
+ if (!policyOID.isEmpty())
+ {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(
+ data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ inStream = new ByteArrayInputStream(
+ ((ASN1OctetString)derInputStream.readObject())
+ .getOctets());
+ derInputStream = new ASN1InputStream(inStream);
+ Enumeration policySequence = ((ASN1Sequence)derInputStream
+ .readObject()).getObjects();
+ ASN1Sequence policyObject;
+ boolean test = false;
+ while (policySequence.hasMoreElements() && !test)
+ {
+ policyObject = (ASN1Sequence)policySequence
+ .nextElement();
+ if (policyOID.contains(policyObject.getObjectAt(0)))
+ {
+ test = true;
+ }
+ }
+ if (!test)
+ {
+ return false;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+ if (subjectAltNamesByte != null)
+ {
+ try
+ {
+ byte[] data = certX509
+ .getExtensionValue(X509Extensions.SubjectAlternativeName
+ .getId());
+ if (data == null)
+ {
+ return false;
+ }
+ ByteArrayInputStream inStream = new ByteArrayInputStream(data);
+ ASN1InputStream derInputStream = new ASN1InputStream(inStream);
+ inStream = new ByteArrayInputStream(
+ ((ASN1OctetString)derInputStream.readObject())
+ .getOctets());
+ derInputStream = new ASN1InputStream(inStream);
+ Enumeration altNamesSequence = ((ASN1Sequence)derInputStream
+ .readObject()).getObjects();
+ ASN1TaggedObject altNameObject;
+ boolean test = false;
+ Set testSet = new HashSet(subjectAltNamesByte);
+ List testList;
+ ASN1Object derData;
+ ByteArrayOutputStream outStream;
+ DEROutputStream derOutStream;
+ while (altNamesSequence.hasMoreElements() && !test)
+ {
+ altNameObject = (ASN1TaggedObject)altNamesSequence
+ .nextElement();
+ testList = new ArrayList(2);
+ testList.add(Integers.valueOf(altNameObject.getTagNo()));
+ derData = altNameObject.getObject();
+ outStream = new ByteArrayOutputStream();
+ derOutStream = new DEROutputStream(outStream);
+ derOutStream.writeObject(derData);
+ derOutStream.close();
+ testList.add(outStream.toByteArray());
+
+ if (testSet.remove(testList))
+ {
+ test = true;
+ }
+
+ if (matchAllSubjectAltNames && !testSet.isEmpty())
+ {
+ test = false;
+ }
+ }
+ if (!test)
+ {
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a copy of this object.
+ *
+ * @return the copy
+ */
+ public Object clone()
+ {
+ try
+ {
+ X509CertSelector copy = (X509CertSelector)super.clone();
+ if (issuerDN instanceof byte[])
+ {
+ copy.issuerDN = ((byte[])issuerDN).clone();
+ }
+ if (subjectDN instanceof byte[])
+ {
+ copy.subjectDN = ((byte[])subjectDN).clone();
+ }
+ if (subjectKeyID != null)
+ {
+ copy.subjectKeyID = (byte[])subjectKeyID.clone();
+ }
+ if (authorityKeyID != null)
+ {
+ copy.authorityKeyID = (byte[])authorityKeyID.clone();
+ }
+ if (subjectPublicKeyByte != null)
+ {
+ copy.subjectPublicKeyByte = (byte[])subjectPublicKeyByte
+ .clone();
+ }
+ if (keyUsage != null)
+ {
+ copy.keyUsage = (boolean[])keyUsage.clone();
+ }
+ if (keyPurposeSet != null)
+ {
+ copy.keyPurposeSet = new HashSet(keyPurposeSet);
+ }
+ if (policy != null)
+ {
+ copy.policy = new HashSet(policy);
+ copy.policyOID = new HashSet();
+ Iterator iter = policyOID.iterator();
+ while (iter.hasNext())
+ {
+ copy.policyOID.add(new ASN1ObjectIdentifier(
+ ((ASN1ObjectIdentifier)iter.next()).getId()));
+ }
+ }
+ if (subjectAltNames != null)
+ {
+ copy.subjectAltNames = new HashSet(getSubjectAlternativeNames());
+ Iterator iter = subjectAltNamesByte.iterator();
+ List obj;
+ List cloneObj;
+ while (iter.hasNext())
+ {
+ obj = (List)iter.next();
+ cloneObj = new ArrayList();
+ cloneObj.add(obj.get(0));
+ cloneObj.add(((byte[])obj.get(1)).clone());
+ copy.subjectAltNamesByte.add(cloneObj);
+ }
+ }
+ if (pathToNames != null)
+ {
+ copy.pathToNames = new HashSet(getPathToNames());
+ Iterator iter = pathToNamesByte.iterator();
+ List obj;
+ List cloneObj;
+ while (iter.hasNext())
+ {
+ obj = (List)iter.next();
+ cloneObj = new ArrayList();
+ cloneObj.add(obj.get(0));
+ cloneObj.add(((byte[])obj.get(1)).clone());
+ copy.pathToNamesByte.add(cloneObj);
+ }
+ }
+ return copy;
+ }
+ catch (CloneNotSupportedException e)
+ {
+ /* Cannot happen */
+ throw new InternalError(e.toString());
+ }
+ }
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Certificate.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Certificate.java
new file mode 100644
index 000000000..d56f1c6f3
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Certificate.java
@@ -0,0 +1,33 @@
+
+package java.security.cert;
+
+import java.math.BigInteger;
+import java.security.Principal;
+import java.util.Date;
+
+public abstract class X509Certificate extends Certificate
+implements X509Extension
+{
+ protected X509Certificate()
+ {
+ super("X.509");
+ }
+
+ public abstract void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException;
+ public abstract void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException;
+ public abstract int getBasicConstraints();
+ public abstract Principal getIssuerDN();
+ public abstract boolean[] getIssuerUniqueID();
+ public abstract boolean[] getKeyUsage();
+ public abstract Date getNotAfter();
+ public abstract Date getNotBefore();
+ public abstract BigInteger getSerialNumber();
+ public abstract String getSigAlgName();
+ public abstract String getSigAlgOID();
+ public abstract byte[] getSigAlgParams();
+ public abstract byte[] getSignature();
+ public abstract Principal getSubjectDN();
+ public abstract boolean[] getSubjectUniqueID();
+ public abstract byte[] getTBSCertificate() throws CertificateEncodingException;
+ public abstract int getVersion();
+}
diff --git a/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Extension.java b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Extension.java
new file mode 100644
index 000000000..20855be1e
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/jdk1.1/java/security/cert/X509Extension.java
@@ -0,0 +1,12 @@
+
+package java.security.cert;
+
+import java.util.Set;
+
+public interface X509Extension
+{
+ public abstract Set getCriticalExtensionOIDs();
+ public abstract byte[] getExtensionValue(String oid);
+ public abstract Set getNonCriticalExtensionOIDs();
+ public abstract boolean hasUnsupportedCriticalExtension();
+}