Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'prov/src/main/jdk1.3/org/spongycastle/x509')
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateHolder.java406
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateIssuer.java211
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXBuilderParameters.java210
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXParameters.java647
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509AttributeCertStoreSelector.java486
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509CRLStoreSelector.java330
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509CertStoreSelector.java86
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509Util.java397
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509V1CertificateGenerator.java341
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509V2CRLGenerator.java430
-rw-r--r--prov/src/main/jdk1.3/org/spongycastle/x509/X509V3CertificateGenerator.java491
11 files changed, 4035 insertions, 0 deletions
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateHolder.java b/prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateHolder.java
new file mode 100644
index 00000000..5b161b4d
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateHolder.java
@@ -0,0 +1,406 @@
+package org.spongycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.Holder;
+import org.spongycastle.asn1.x509.IssuerSerial;
+import org.spongycastle.asn1.x509.ObjectDigestInfo;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.cert.CertSelector;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Selector;
+
+/**
+ * The Holder object.
+ *
+ * <pre>
+ * Holder ::= SEQUENCE {
+ * baseCertificateID [0] IssuerSerial OPTIONAL,
+ * -- the issuer and serial number of
+ * -- the holder's Public Key Certificate
+ * entityName [1] GeneralNames OPTIONAL,
+ * -- the name of the claimant or role
+ * objectDigestInfo [2] ObjectDigestInfo OPTIONAL
+ * -- used to directly authenticate the holder,
+ * -- for example, an executable
+ * }
+ * </pre>
+ * @deprecated use org.spongycastle.cert.AttributeCertificateHolder
+ */
+public class AttributeCertificateHolder
+ implements CertSelector, Selector
+{
+ final Holder holder;
+
+ AttributeCertificateHolder(ASN1Sequence seq)
+ {
+ holder = Holder.getInstance(seq);
+ }
+
+ public AttributeCertificateHolder(X509Principal issuerName,
+ BigInteger serialNumber)
+ {
+ holder = new org.spongycastle.asn1.x509.Holder(new IssuerSerial(
+ new GeneralNames(new GeneralName(issuerName)),
+ new ASN1Integer(serialNumber)));
+ }
+
+ public AttributeCertificateHolder(X509Certificate cert)
+ throws CertificateParsingException
+ {
+ X509Principal name;
+
+ try
+ {
+ name = PrincipalUtil.getIssuerX509Principal(cert);
+ }
+ catch (Exception e)
+ {
+ throw new CertificateParsingException(e.getMessage());
+ }
+
+ holder = new Holder(new IssuerSerial(generateGeneralNames(name),
+ new ASN1Integer(cert.getSerialNumber())));
+ }
+
+ public AttributeCertificateHolder(X509Principal principal)
+ {
+ holder = new Holder(generateGeneralNames(principal));
+ }
+
+ /**
+ * Constructs a holder for v2 attribute certificates with a hash value for
+ * some type of object.
+ * <p>
+ * <code>digestedObjectType</code> can be one of the following:
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ * <p>
+ * This cannot be used if a v1 attribute certificate is used.
+ *
+ * @param digestedObjectType The digest object type.
+ * @param digestAlgorithm The algorithm identifier for the hash.
+ * @param otherObjectTypeID The object type ID if
+ * <code>digestedObjectType</code> is
+ * <code>otherObjectDigest</code>.
+ * @param objectDigest The hash value.
+ */
+ public AttributeCertificateHolder(int digestedObjectType,
+ String digestAlgorithm, String otherObjectTypeID, byte[] objectDigest)
+ {
+ holder = new Holder(new ObjectDigestInfo(digestedObjectType,
+ new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(digestAlgorithm), Arrays
+ .clone(objectDigest)));
+ }
+
+ /**
+ * Returns the digest object type if an object digest info is used.
+ * <p>
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ *
+ * @return The digest object type or -1 if no object digest info is set.
+ */
+ public int getDigestedObjectType()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getDigestedObjectType()
+ .getValue().intValue();
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the other object type ID if an object digest info is used.
+ *
+ * @return The other object type ID or <code>null</code> if no object
+ * digest info is set.
+ */
+ public String getDigestAlgorithm()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getDigestAlgorithm().getObjectId()
+ .getId();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the hash if an object digest info is used.
+ *
+ * @return The hash or <code>null</code> if no object digest info is set.
+ */
+ public byte[] getObjectDigest()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ return holder.getObjectDigestInfo().getObjectDigest().getBytes();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the digest algorithm ID if an object digest info is used.
+ *
+ * @return The digest algorithm ID or <code>null</code> if no object
+ * digest info is set.
+ */
+ public String getOtherObjectTypeID()
+ {
+ if (holder.getObjectDigestInfo() != null)
+ {
+ holder.getObjectDigestInfo().getOtherObjectTypeID().getId();
+ }
+ return null;
+ }
+
+ private GeneralNames generateGeneralNames(X509Principal principal)
+ {
+ return new GeneralNames(new GeneralName(principal));
+ }
+
+ private boolean matchesDN(X509Principal subject, GeneralNames targets)
+ {
+ GeneralName[] names = targets.getNames();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive()
+ .getEncoded()).equals(subject))
+ {
+ return true;
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private Object[] getNames(GeneralName[] names)
+ {
+ List l = new ArrayList(names.length);
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ l.add(new X509Principal(
+ ((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("badly formed Name object");
+ }
+ }
+ }
+
+ return l.toArray(new Object[l.size()]);
+ }
+
+ private Principal[] getPrincipals(GeneralNames names)
+ {
+ Object[] p = this.getNames(names.getNames());
+ List l = new ArrayList();
+
+ for (int i = 0; i != p.length; i++)
+ {
+ if (p[i] instanceof Principal)
+ {
+ l.add(p[i]);
+ }
+ }
+
+ return (Principal[])l.toArray(new Principal[l.size()]);
+ }
+
+ /**
+ * Return any principal objects inside the attribute certificate holder
+ * entity names field.
+ *
+ * @return an array of Principal objects (usually X509Principal), null if no
+ * entity names field is set.
+ */
+ public Principal[] getEntityNames()
+ {
+ if (holder.getEntityName() != null)
+ {
+ return getPrincipals(holder.getEntityName());
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the principals associated with the issuer attached to this holder
+ *
+ * @return an array of principals, null if no BaseCertificateID is set.
+ */
+ public Principal[] getIssuer()
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return getPrincipals(holder.getBaseCertificateID().getIssuer());
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the serial number associated with the issuer attached to this
+ * holder.
+ *
+ * @return the certificate serial number, null if no BaseCertificateID is
+ * set.
+ */
+ public BigInteger getSerialNumber()
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return holder.getBaseCertificateID().getSerial().getValue();
+ }
+
+ return null;
+ }
+
+ public Object clone()
+ {
+ return new AttributeCertificateHolder((ASN1Sequence)holder
+ .toASN1Object());
+ }
+
+ public boolean match(Certificate cert)
+ {
+ if (!(cert instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ X509Certificate x509Cert = (X509Certificate)cert;
+
+ try
+ {
+ if (holder.getBaseCertificateID() != null)
+ {
+ return holder.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), holder.getBaseCertificateID().getIssuer());
+ }
+
+ if (holder.getEntityName() != null)
+ {
+ if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert),
+ holder.getEntityName()))
+ {
+ return true;
+ }
+ }
+ if (holder.getObjectDigestInfo() != null)
+ {
+ MessageDigest md = null;
+ try
+ {
+ md = MessageDigest.getInstance(getDigestAlgorithm(), "SC");
+
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ switch (getDigestedObjectType())
+ {
+ case ObjectDigestInfo.publicKey:
+ // TODO: DSA Dss-parms
+ md.update(cert.getPublicKey().getEncoded());
+ break;
+ case ObjectDigestInfo.publicKeyCert:
+ md.update(cert.getEncoded());
+ break;
+ }
+ if (!Arrays.areEqual(md.digest(), getObjectDigest()))
+ {
+ return false;
+ }
+ }
+ }
+ catch (CertificateEncodingException e)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof AttributeCertificateHolder))
+ {
+ return false;
+ }
+
+ AttributeCertificateHolder other = (AttributeCertificateHolder)obj;
+
+ return this.holder.equals(other.holder);
+ }
+
+ public int hashCode()
+ {
+ return this.holder.hashCode();
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ return match((Certificate)obj);
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateIssuer.java b/prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateIssuer.java
new file mode 100644
index 00000000..44512802
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/AttributeCertificateIssuer.java
@@ -0,0 +1,211 @@
+package org.spongycastle.x509;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.x509.AttCertIssuer;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.V2Form;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.cert.CertSelector;
+import org.spongycastle.util.Selector;
+
+/**
+ * Carrying class for an attribute certificate issuer.
+ */
+public class AttributeCertificateIssuer
+ implements CertSelector, Selector
+{
+ final ASN1Encodable form;
+
+ /**
+ * @param issuer
+ */
+ AttributeCertificateIssuer(
+ AttCertIssuer issuer)
+ {
+ form = issuer.getIssuer();
+ }
+
+ public AttributeCertificateIssuer(
+ X509Principal principal)
+ {
+ form = new V2Form(new GeneralNames(new GeneralName(principal)));
+ }
+
+ private Object[] getNames()
+ {
+ GeneralNames name;
+
+ if (form instanceof V2Form)
+ {
+ name = ((V2Form)form).getIssuerName();
+ }
+ else
+ {
+ name = (GeneralNames)form;
+ }
+
+ GeneralName[] names = name.getNames();
+
+ List l = new ArrayList(names.length);
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ l.add(new X509Principal(((ASN1Encodable)names[i].getName()).toASN1Primitive().getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("badly formed Name object");
+ }
+ }
+ }
+
+ return l.toArray(new Object[l.size()]);
+ }
+
+ /**
+ * Return any principal objects inside the attribute certificate issuer object.
+ *
+ * @return an array of Principal objects (usually X509Principal)
+ */
+ public Principal[] getPrincipals()
+ {
+ Object[] p = this.getNames();
+ List l = new ArrayList();
+
+ for (int i = 0; i != p.length; i++)
+ {
+ if (p[i] instanceof Principal)
+ {
+ l.add(p[i]);
+ }
+ }
+
+ return (Principal[])l.toArray(new Principal[l.size()]);
+ }
+
+ private boolean matchesDN(X509Principal subject, GeneralNames targets)
+ {
+ GeneralName[] names = targets.getNames();
+
+ for (int i = 0; i != names.length; i++)
+ {
+ GeneralName gn = names[i];
+
+ if (gn.getTagNo() == GeneralName.directoryName)
+ {
+ try
+ {
+ if (new X509Principal(((ASN1Encodable)gn.getName()).toASN1Primitive().getEncoded()).equals(subject))
+ {
+ return true;
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.cert.CertSelector#clone()
+ */
+ public Object clone()
+ {
+ return new AttributeCertificateIssuer(AttCertIssuer.getInstance(form));
+ }
+
+ /* (non-Javadoc)
+ * @see java.security.cert.CertSelector#match(java.security.cert.Certificate)
+ */
+ public boolean match(Certificate cert)
+ {
+ if (!(cert instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ X509Certificate x509Cert = (X509Certificate)cert;
+
+ try
+ {
+ if (form instanceof V2Form)
+ {
+ V2Form issuer = (V2Form)form;
+ if (issuer.getBaseCertificateID() != null)
+ {
+ return issuer.getBaseCertificateID().getSerial().getValue().equals(x509Cert.getSerialNumber())
+ && matchesDN(PrincipalUtil.getIssuerX509Principal(x509Cert), issuer.getBaseCertificateID().getIssuer());
+ }
+
+ GeneralNames name = issuer.getIssuerName();
+ if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), name))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ GeneralNames name = (GeneralNames)form;
+ if (matchesDN(PrincipalUtil.getSubjectX509Principal(x509Cert), name))
+ {
+ return true;
+ }
+ }
+ }
+ catch (CertificateEncodingException e)
+ {
+ return false;
+ }
+
+ return false;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof AttributeCertificateIssuer))
+ {
+ return false;
+ }
+
+ AttributeCertificateIssuer other = (AttributeCertificateIssuer)obj;
+
+ return this.form.equals(other.form);
+ }
+
+ public int hashCode()
+ {
+ return this.form.hashCode();
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ return match((Certificate)obj);
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXBuilderParameters.java b/prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXBuilderParameters.java
new file mode 100644
index 00000000..55d80de9
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXBuilderParameters.java
@@ -0,0 +1,210 @@
+package org.spongycastle.x509;
+
+import org.spongycastle.util.Selector;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import org.spongycastle.jce.cert.PKIXBuilderParameters;
+import org.spongycastle.jce.cert.PKIXParameters;
+import org.spongycastle.jce.cert.TrustAnchor;
+import org.spongycastle.jce.cert.X509CertSelector;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class contains extended parameters for PKIX certification path builders.
+ *
+ * @see java.security.cert.PKIXBuilderParameters
+ * @see org.spongycastle.jce.provider.PKIXCertPathBuilderSpi
+ */
+public class ExtendedPKIXBuilderParameters extends ExtendedPKIXParameters
+{
+
+ private int maxPathLength = 5;
+
+ private Set excludedCerts = Collections.EMPTY_SET;
+
+ /**
+ * Excluded certificates are not used for building a certification path.
+ * <p>
+ * The returned set is immutable.
+ *
+ * @return Returns the excluded certificates.
+ */
+ public Set getExcludedCerts()
+ {
+ return Collections.unmodifiableSet(excludedCerts);
+ }
+
+ /**
+ * Sets the excluded certificates which are not used for building a
+ * certification path. If the <code>Set</code> is <code>null</code> an
+ * empty set is assumed.
+ * <p>
+ * The given set is cloned to protect it against subsequent modifications.
+ *
+ * @param excludedCerts The excluded certificates to set.
+ */
+ public void setExcludedCerts(Set excludedCerts)
+ {
+ if (excludedCerts == null)
+ {
+ excludedCerts = Collections.EMPTY_SET;
+ }
+ else
+ {
+ this.excludedCerts = new HashSet(excludedCerts);
+ }
+ }
+
+ /**
+ * 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}.
+ *
+ * <p>
+ * 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>Selector</code> specifying the
+ * constraints on the target certificate or attribute
+ * certificate.
+ * @throws InvalidAlgorithmParameterException if <code>trustAnchors</code>
+ * is empty.
+ * @throws NullPointerException if <code>trustAnchors</code> is
+ * <code>null</code>
+ * @throws ClassCastException if any of the elements of
+ * <code>trustAnchors</code> is not of type
+ * <code>java.security.cert.TrustAnchor</code>
+ */
+ public ExtendedPKIXBuilderParameters(Set trustAnchors,
+ Selector targetConstraints)
+ throws InvalidAlgorithmParameterException
+ {
+ super(trustAnchors);
+ setTargetConstraints(targetConstraints);
+ }
+
+ /**
+ * Sets the maximum number of intermediate non-self-issued certificates in a
+ * certification path. The PKIX <code>CertPathBuilder</code> must not
+ * build paths longer then this length.
+ * <p>
+ * A value of 0 implies that the path can only contain a single certificate.
+ * A value of -1 does not limit the length. The default length is 5.
+ *
+ * <p>
+ *
+ * The basic constraints extension of a CA certificate overrides this value
+ * if smaller.
+ *
+ * @param maxPathLength the maximum number of non-self-issued intermediate
+ * certificates in the certification path
+ * @throws InvalidParameterException if <code>maxPathLength</code> is set
+ * to a value less than -1
+ *
+ * @see org.spongycastle.jce.provider.PKIXCertPathBuilderSpi
+ * @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 in the certification path.
+ *
+ * @return the maximum number of non-self-issued intermediate certificates
+ * in the certification path, or -1 if no limit exists.
+ *
+ * @see #setMaxPathLength(int)
+ */
+ public int getMaxPathLength()
+ {
+ return maxPathLength;
+ }
+
+ /**
+ * Can alse handle <code>ExtendedPKIXBuilderParameters</code> and
+ * <code>PKIXBuilderParameters</code>.
+ *
+ * @param params Parameters to set.
+ * @see org.spongycastle.x509.ExtendedPKIXParameters#setParams(java.security.cert.PKIXParameters)
+ */
+ protected void setParams(PKIXParameters params)
+ {
+ super.setParams(params);
+ if (params instanceof ExtendedPKIXBuilderParameters)
+ {
+ ExtendedPKIXBuilderParameters _params = (ExtendedPKIXBuilderParameters) params;
+ maxPathLength = _params.maxPathLength;
+ excludedCerts = new HashSet(_params.excludedCerts);
+ }
+ if (params instanceof PKIXBuilderParameters)
+ {
+ PKIXBuilderParameters _params = (PKIXBuilderParameters) params;
+ maxPathLength = _params.getMaxPathLength();
+ }
+ }
+
+ /**
+ * Makes a copy of this <code>PKIXParameters</code> 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()
+ {
+ ExtendedPKIXBuilderParameters params = null;
+ try
+ {
+ params = new ExtendedPKIXBuilderParameters(getTrustAnchors(),
+ getTargetConstraints());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(this);
+ return params;
+ }
+
+ /**
+ * Returns an instance of <code>ExtendedPKIXParameters</code> which can be
+ * safely casted to <code>ExtendedPKIXBuilderParameters</code>.
+ * <p>
+ * This method can be used to get a copy from other
+ * <code>PKIXBuilderParameters</code>, <code>PKIXParameters</code>,
+ * and <code>ExtendedPKIXParameters</code> instances.
+ *
+ * @param pkixParams The PKIX parameters to create a copy of.
+ * @return An <code>ExtendedPKIXBuilderParameters</code> instance.
+ */
+ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
+ {
+ ExtendedPKIXBuilderParameters params;
+ try
+ {
+ params = new ExtendedPKIXBuilderParameters(pkixParams
+ .getTrustAnchors(), X509CertStoreSelector
+ .getInstance((X509CertSelector) pkixParams
+ .getTargetCertConstraints()));
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(pkixParams);
+ return params;
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXParameters.java b/prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXParameters.java
new file mode 100644
index 00000000..c2636c5b
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/ExtendedPKIXParameters.java
@@ -0,0 +1,647 @@
+package org.spongycastle.x509;
+
+import org.spongycastle.util.Selector;
+import org.spongycastle.util.Store;
+
+import java.security.InvalidAlgorithmParameterException;
+import org.spongycastle.jce.cert.CertSelector;
+import org.spongycastle.jce.cert.CertStore;
+import org.spongycastle.jce.cert.CollectionCertStoreParameters;
+import org.spongycastle.jce.cert.LDAPCertStoreParameters;
+import org.spongycastle.jce.cert.PKIXParameters;
+import org.spongycastle.jce.cert.TrustAnchor;
+import org.spongycastle.jce.cert.X509CertSelector;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class extends the PKIXParameters with a validity model parameter.
+ */
+public class ExtendedPKIXParameters
+ extends PKIXParameters
+{
+
+ private List stores;
+
+ private Selector selector;
+
+ private boolean additionalLocationsEnabled;
+
+ private List additionalStores;
+
+ private Set trustedACIssuers;
+
+ private Set necessaryACAttributes;
+
+ private Set prohibitedACAttributes;
+
+ private Set attrCertCheckers;
+
+ /**
+ * Creates an instance of <code>PKIXParameters</code> with the specified
+ * <code>Set</code> of most-trusted CAs. Each element of the set is a
+ * {@link TrustAnchor TrustAnchor}. <p/> Note that the <code>Set</code>
+ * is copied to protect against subsequent modifications.
+ *
+ * @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
+ * @throws InvalidAlgorithmParameterException if the specified
+ * <code>Set</code> is empty.
+ * @throws NullPointerException if the specified <code>Set</code> is
+ * <code>null</code>
+ * @throws ClassCastException if any of the elements in the <code>Set</code>
+ * is not of type <code>java.security.cert.TrustAnchor</code>
+ */
+ public ExtendedPKIXParameters(Set trustAnchors)
+ throws InvalidAlgorithmParameterException
+ {
+ super(trustAnchors);
+ stores = new ArrayList();
+ additionalStores = new ArrayList();
+ trustedACIssuers = new HashSet();
+ necessaryACAttributes = new HashSet();
+ prohibitedACAttributes = new HashSet();
+ attrCertCheckers = new HashSet();
+ }
+
+ /**
+ * Returns an instance with the parameters of a given
+ * <code>PKIXParameters</code> object.
+ *
+ * @param pkixParams The given <code>PKIXParameters</code>
+ * @return an extended PKIX params object
+ */
+ public static ExtendedPKIXParameters getInstance(PKIXParameters pkixParams)
+ {
+ ExtendedPKIXParameters params;
+ try
+ {
+ params = new ExtendedPKIXParameters(pkixParams.getTrustAnchors());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(pkixParams);
+ return params;
+ }
+
+ /**
+ * Method to support <code>clone()</code> under J2ME.
+ * <code>super.clone()</code> does not exist and fields are not copied.
+ *
+ * @param params Parameters to set. If this are
+ * <code>ExtendedPKIXParameters</code> they are copied to.
+ */
+ protected void setParams(PKIXParameters params)
+ {
+ setDate(params.getDate());
+ setCertPathCheckers(params.getCertPathCheckers());
+ setCertStores(params.getCertStores());
+ setAnyPolicyInhibited(params.isAnyPolicyInhibited());
+ setExplicitPolicyRequired(params.isExplicitPolicyRequired());
+ setPolicyMappingInhibited(params.isPolicyMappingInhibited());
+ setRevocationEnabled(params.isRevocationEnabled());
+ setInitialPolicies(params.getInitialPolicies());
+ setPolicyQualifiersRejected(params.getPolicyQualifiersRejected());
+ setSigProvider(params.getSigProvider());
+ setTargetCertConstraints(params.getTargetCertConstraints());
+ try
+ {
+ setTrustAnchors(params.getTrustAnchors());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ if (params instanceof ExtendedPKIXParameters)
+ {
+ ExtendedPKIXParameters _params = (ExtendedPKIXParameters) params;
+ validityModel = _params.validityModel;
+ useDeltas = _params.useDeltas;
+ additionalLocationsEnabled = _params.additionalLocationsEnabled;
+ selector = _params.selector == null ? null
+ : (Selector) _params.selector.clone();
+ stores = new ArrayList(_params.stores);
+ additionalStores = new ArrayList(_params.additionalStores);
+ trustedACIssuers = new HashSet(_params.trustedACIssuers);
+ prohibitedACAttributes = new HashSet(_params.prohibitedACAttributes);
+ necessaryACAttributes = new HashSet(_params.necessaryACAttributes);
+ attrCertCheckers = new HashSet(_params.attrCertCheckers);
+ }
+ }
+
+ /**
+ * This is the default PKIX validity model. Actually there are two variants
+ * of this: The PKIX model and the modified PKIX model. The PKIX model
+ * verifies that all involved certificates must have been valid at the
+ * current time. The modified PKIX model verifies that all involved
+ * certificates were valid at the signing time. Both are indirectly choosen
+ * with the {@link PKIXParameters#setDate(java.util.Date)} method, so this
+ * methods sets the Date when <em>all</em> certificates must have been
+ * valid.
+ */
+ public static final int PKIX_VALIDITY_MODEL = 0;
+
+ /**
+ * This model uses the following validity model. Each certificate must have
+ * been valid at the moment where is was used. That means the end
+ * certificate must have been valid at the time the signature was done. The
+ * CA certificate which signed the end certificate must have been valid,
+ * when the end certificate was signed. The CA (or Root CA) certificate must
+ * have been valid, when the CA certificate was signed and so on. So the
+ * {@link PKIXParameters#setDate(java.util.Date)} method sets the time, when
+ * the <em>end certificate</em> must have been valid. <p/> It is used e.g.
+ * in the German signature law.
+ */
+ public static final int CHAIN_VALIDITY_MODEL = 1;
+
+ private int validityModel = PKIX_VALIDITY_MODEL;
+
+ private boolean useDeltas = false;
+
+ /**
+ * Defaults to <code>false</code>.
+ *
+ * @return Returns if delta CRLs should be used.
+ */
+ public boolean isUseDeltasEnabled()
+ {
+ return useDeltas;
+ }
+
+ /**
+ * Sets if delta CRLs should be used for checking the revocation status.
+ *
+ * @param useDeltas <code>true</code> if delta CRLs should be used.
+ */
+ public void setUseDeltasEnabled(boolean useDeltas)
+ {
+ this.useDeltas = useDeltas;
+ }
+
+ /**
+ * @return Returns the validity model.
+ * @see #CHAIN_VALIDITY_MODEL
+ * @see #PKIX_VALIDITY_MODEL
+ */
+ public int getValidityModel()
+ {
+ return validityModel;
+ }
+
+ /**
+ * Sets the Java CertStore to this extended PKIX parameters.
+ *
+ * @throws ClassCastException if an element of <code>stores</code> is not
+ * a <code>CertStore</code>.
+ */
+ public void setCertStores(List stores)
+ {
+ if (stores != null)
+ {
+ Iterator it = stores.iterator();
+ while (it.hasNext())
+ {
+ addCertStore((CertStore)it.next());
+ }
+ }
+ }
+
+ /**
+ * Sets the Bouncy Castle Stores for finding CRLs, certificates, attribute
+ * certificates or cross certificates.
+ * <p>
+ * The <code>List</code> is cloned.
+ *
+ * @param stores A list of stores to use.
+ * @see #getStores
+ * @throws ClassCastException if an element of <code>stores</code> is not
+ * a {@link Store}.
+ */
+ public void setStores(List stores)
+ {
+ if (stores == null)
+ {
+ this.stores = new ArrayList();
+ }
+ else
+ {
+ for (Iterator i = stores.iterator(); i.hasNext();)
+ {
+ if (!(i.next() instanceof Store))
+ {
+ throw new ClassCastException(
+ "All elements of list must be "
+ + "of type org.spongycastle.util.Store.");
+ }
+ }
+ this.stores = new ArrayList(stores);
+ }
+ }
+
+ /**
+ * Adds a Bouncy Castle {@link Store} to find CRLs, certificates, attribute
+ * certificates or cross certificates.
+ * <p>
+ * This method should be used to add local stores, like collection based
+ * X.509 stores, if available. Local stores should be considered first,
+ * before trying to use additional (remote) locations, because they do not
+ * need possible additional network traffic.
+ * <p>
+ * If <code>store</code> is <code>null</code> it is ignored.
+ *
+ * @param store The store to add.
+ * @see #getStores
+ */
+ public void addStore(Store store)
+ {
+ if (stores != null)
+ {
+ stores.add(store);
+ }
+ }
+
+ /**
+ * Adds a additional Bouncy Castle {@link Store} to find CRLs, certificates,
+ * attribute certificates or cross certificates.
+ * <p>
+ * You should not use this method. This method is used for adding additional
+ * X.509 stores, which are used to add (remote) locations, e.g. LDAP, found
+ * during X.509 object processing, e.g. in certificates or CRLs. This method
+ * is used in PKIX certification path processing.
+ * <p>
+ * If <code>store</code> is <code>null</code> it is ignored.
+ *
+ * @param store The store to add.
+ * @see #getStores()
+ */
+ public void addAddionalStore(Store store)
+ {
+ if (store != null)
+ {
+ additionalStores.add(store);
+ }
+ }
+
+ /**
+ * Returns an immutable <code>List</code> of additional Bouncy Castle
+ * <code>Store</code>s used for finding CRLs, certificates, attribute
+ * certificates or cross certificates.
+ *
+ * @return an immutable <code>List</code> of additional Bouncy Castle
+ * <code>Store</code>s. Never <code>null</code>.
+ *
+ * @see #addAddionalStore(Store)
+ */
+ public List getAdditionalStores()
+ {
+ return Collections.unmodifiableList(additionalStores);
+ }
+
+ /**
+ * Returns an immutable <code>List</code> of Bouncy Castle
+ * <code>Store</code>s used for finding CRLs, certificates, attribute
+ * certificates or cross certificates.
+ *
+ * @return an immutable <code>List</code> of Bouncy Castle
+ * <code>Store</code>s. Never <code>null</code>.
+ *
+ * @see #setStores(List)
+ */
+ public List getStores()
+ {
+ return Collections.unmodifiableList(new ArrayList(stores));
+ }
+
+ /**
+ * @param validityModel The validity model to set.
+ * @see #CHAIN_VALIDITY_MODEL
+ * @see #PKIX_VALIDITY_MODEL
+ */
+ public void setValidityModel(int validityModel)
+ {
+ this.validityModel = validityModel;
+ }
+
+ public Object clone()
+ {
+ ExtendedPKIXParameters params;
+ try
+ {
+ params = new ExtendedPKIXParameters(getTrustAnchors());
+ }
+ catch (Exception e)
+ {
+ // cannot happen
+ throw new RuntimeException(e.getMessage());
+ }
+ params.setParams(this);
+ return params;
+ }
+
+ /**
+ * Returns if additional {@link X509Store}s for locations like LDAP found
+ * in certificates or CRLs should be used.
+ *
+ * @return Returns <code>true</code> if additional stores are used.
+ */
+ public boolean isAdditionalLocationsEnabled()
+ {
+ return additionalLocationsEnabled;
+ }
+
+ /**
+ * Sets if additional {@link X509Store}s for locations like LDAP found in
+ * certificates or CRLs should be used.
+ *
+ * @param enabled <code>true</code> if additional stores are used.
+ */
+ public void setAdditionalLocationsEnabled(boolean enabled)
+ {
+ additionalLocationsEnabled = enabled;
+ }
+
+ /**
+ * Returns the required constraints on the target certificate or attribute
+ * certificate. The constraints are returned as an instance of
+ * <code>Selector</code>. If <code>null</code>, no constraints are
+ * defined.
+ *
+ * <p>
+ * The target certificate in a PKIX path may be a certificate or an
+ * attribute certificate.
+ * <p>
+ * Note that the <code>Selector</code> returned is cloned to protect
+ * against subsequent modifications.
+ *
+ * @return a <code>Selector</code> specifying the constraints on the
+ * target certificate or attribute certificate (or <code>null</code>)
+ * @see #setTargetConstraints
+ * @see X509CertStoreSelector
+ * @see X509AttributeCertStoreSelector
+ */
+ public Selector getTargetConstraints()
+ {
+ if (selector != null)
+ {
+ return (Selector) selector.clone();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the required constraints on the target certificate or attribute
+ * certificate. The constraints are specified as an instance of
+ * <code>Selector</code>. If <code>null</code>, no constraints are
+ * defined.
+ * <p>
+ * The target certificate in a PKIX path may be a certificate or an
+ * attribute certificate.
+ * <p>
+ * Note that the <code>Selector</code> specified is cloned to protect
+ * against subsequent modifications.
+ *
+ * @param selector a <code>Selector</code> specifying the constraints on
+ * the target certificate or attribute certificate (or
+ * <code>null</code>)
+ * @see #getTargetConstraints
+ * @see X509CertStoreSelector
+ * @see X509AttributeCertStoreSelector
+ */
+ public void setTargetConstraints(Selector selector)
+ {
+ if (selector != null)
+ {
+ this.selector = (Selector) selector.clone();
+ }
+ else
+ {
+ this.selector = null;
+ }
+ }
+
+ /**
+ * Sets the required constraints on the target certificate. The constraints
+ * are specified as an instance of <code>X509CertSelector</code>. If
+ * <code>null</code>, no constraints are defined.
+ *
+ * <p>
+ * This method wraps the given <code>X509CertSelector</code> into a
+ * <code>X509CertStoreSelector</code>.
+ * <p>
+ * Note that the <code>X509CertSelector</code> specified is cloned to
+ * protect against subsequent modifications.
+ *
+ * @param selector a <code>X509CertSelector</code> specifying the
+ * constraints on the target certificate (or <code>null</code>)
+ * @see #getTargetCertConstraints
+ * @see X509CertStoreSelector
+ */
+ public void setTargetCertConstraints(CertSelector selector)
+ {
+ super.setTargetCertConstraints(selector);
+ if (selector != null)
+ {
+ this.selector = X509CertStoreSelector
+ .getInstance((X509CertSelector) selector);
+ }
+ else
+ {
+ this.selector = null;
+ }
+ }
+
+ /**
+ * Returns the trusted attribute certificate issuers. If attribute
+ * certificates is verified the trusted AC issuers must be set.
+ * <p>
+ * The returned <code>Set</code> consists of <code>TrustAnchor</code>s.
+ * <p>
+ * The returned <code>Set</code> is immutable. Never <code>null</code>
+ *
+ * @return Returns an immutable set of the trusted AC issuers.
+ */
+ public Set getTrustedACIssuers()
+ {
+ return Collections.unmodifiableSet(trustedACIssuers);
+ }
+
+ /**
+ * Sets the trusted attribute certificate issuers. If attribute certificates
+ * is verified the trusted AC issuers must be set.
+ * <p>
+ * The <code>trustedACIssuers</code> must be a <code>Set</code> of
+ * <code>TrustAnchor</code>
+ * <p>
+ * The given set is cloned.
+ *
+ * @param trustedACIssuers The trusted AC issuers to set. Is never
+ * <code>null</code>.
+ * @throws ClassCastException if an element of <code>stores</code> is not
+ * a <code>TrustAnchor</code>.
+ */
+ public void setTrustedACIssuers(Set trustedACIssuers)
+ {
+ if (trustedACIssuers == null)
+ {
+ trustedACIssuers.clear();
+ return;
+ }
+ for (Iterator it = trustedACIssuers.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof TrustAnchor))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type " + TrustAnchor.class.getName() + ".");
+ }
+ }
+ this.trustedACIssuers.clear();
+ this.trustedACIssuers.addAll(trustedACIssuers);
+ }
+
+ /**
+ * Returns the neccessary attributes which must be contained in an attribute
+ * certificate.
+ * <p>
+ * The returned <code>Set</code> is immutable and contains
+ * <code>String</code>s with the OIDs.
+ *
+ * @return Returns the necessary AC attributes.
+ */
+ public Set getNecessaryACAttributes()
+ {
+ return Collections.unmodifiableSet(necessaryACAttributes);
+ }
+
+ /**
+ * Sets the neccessary which must be contained in an attribute certificate.
+ * <p>
+ * The <code>Set</code> must contain <code>String</code>s with the
+ * OIDs.
+ * <p>
+ * The set is cloned.
+ *
+ * @param necessaryACAttributes The necessary AC attributes to set.
+ * @throws ClassCastException if an element of
+ * <code>necessaryACAttributes</code> is not a
+ * <code>String</code>.
+ */
+ public void setNecessaryACAttributes(Set necessaryACAttributes)
+ {
+ if (necessaryACAttributes == null)
+ {
+ this.necessaryACAttributes.clear();
+ return;
+ }
+ for (Iterator it = necessaryACAttributes.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof String))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type String.");
+ }
+ }
+ this.necessaryACAttributes.clear();
+ this.necessaryACAttributes.addAll(necessaryACAttributes);
+ }
+
+ /**
+ * Returns the attribute certificates which are not allowed.
+ * <p>
+ * The returned <code>Set</code> is immutable and contains
+ * <code>String</code>s with the OIDs.
+ *
+ * @return Returns the prohibited AC attributes. Is never <code>null</code>.
+ */
+ public Set getProhibitedACAttributes()
+ {
+ return prohibitedACAttributes;
+ }
+
+ /**
+ * Sets the attribute certificates which are not allowed.
+ * <p>
+ * The <code>Set</code> must contain <code>String</code>s with the
+ * OIDs.
+ * <p>
+ * The set is cloned.
+ *
+ * @param prohibitedACAttributes The prohibited AC attributes to set.
+ * @throws ClassCastException if an element of
+ * <code>prohibitedACAttributes</code> is not a
+ * <code>String</code>.
+ */
+ public void setProhibitedACAttributes(Set prohibitedACAttributes)
+ {
+ if (prohibitedACAttributes == null)
+ {
+ this.prohibitedACAttributes.clear();
+ return;
+ }
+ for (Iterator it = prohibitedACAttributes.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof String))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type String.");
+ }
+ }
+ this.prohibitedACAttributes.clear();
+ this.prohibitedACAttributes.addAll(prohibitedACAttributes);
+ }
+
+ /**
+ * Returns the attribute certificate checker. The returned set contains
+ * {@link PKIXAttrCertChecker}s and is immutable.
+ *
+ * @return Returns the attribute certificate checker. Is never
+ * <code>null</code>.
+ */
+ public Set getAttrCertCheckers()
+ {
+ return Collections.unmodifiableSet(attrCertCheckers);
+ }
+
+ /**
+ * Sets the attribute certificate checkers.
+ * <p>
+ * All elements in the <code>Set</code> must a {@link PKIXAttrCertChecker}.
+ * <p>
+ * The given set is cloned.
+ *
+ * @param attrCertCheckers The attribute certificate checkers to set. Is
+ * never <code>null</code>.
+ * @throws ClassCastException if an element of <code>attrCertCheckers</code>
+ * is not a <code>PKIXAttrCertChecker</code>.
+ */
+/*
+ public void setAttrCertCheckers(Set attrCertCheckers)
+ {
+ if (attrCertCheckers == null)
+ {
+ this.attrCertCheckers.clear();
+ return;
+ }
+ for (Iterator it = attrCertCheckers.iterator(); it.hasNext();)
+ {
+ if (!(it.next() instanceof PKIXAttrCertChecker))
+ {
+ throw new ClassCastException("All elements of set must be "
+ + "of type " + PKIXAttrCertChecker.class.getName() + ".");
+ }
+ }
+ this.attrCertCheckers.clear();
+ this.attrCertCheckers.addAll(attrCertCheckers);
+ }
+*/
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509AttributeCertStoreSelector.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509AttributeCertStoreSelector.java
new file mode 100644
index 00000000..b47236d1
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509AttributeCertStoreSelector.java
@@ -0,0 +1,486 @@
+package org.spongycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.util.Collection;
+import java.util.Collections;
+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.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.Target;
+import org.spongycastle.asn1.x509.TargetInformation;
+import org.spongycastle.asn1.x509.Targets;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.util.Selector;
+
+/**
+ * This class is an <code>Selector</code> like implementation to select
+ * attribute certificates from a given set of criteria.
+ *
+ * @see org.spongycastle.x509.X509AttributeCertificate
+ * @see org.spongycastle.x509.X509Store
+ */
+public class X509AttributeCertStoreSelector
+ implements Selector
+{
+
+ // TODO: name constraints???
+
+ private AttributeCertificateHolder holder;
+
+ private AttributeCertificateIssuer issuer;
+
+ private BigInteger serialNumber;
+
+ private Date attributeCertificateValid;
+
+ private X509AttributeCertificate attributeCert;
+
+ private Collection targetNames = new HashSet();
+
+ private Collection targetGroups = new HashSet();
+
+ public X509AttributeCertStoreSelector()
+ {
+ super();
+ }
+
+ /**
+ * Decides if the given attribute certificate should be selected.
+ *
+ * @param obj The attribute certificate which should be checked.
+ * @return <code>true</code> if the attribute certificate can be selected,
+ * <code>false</code> otherwise.
+ */
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509AttributeCertificate))
+ {
+ return false;
+ }
+
+ X509AttributeCertificate attrCert = (X509AttributeCertificate) obj;
+
+ if (this.attributeCert != null)
+ {
+ if (!this.attributeCert.equals(attrCert))
+ {
+ return false;
+ }
+ }
+ if (serialNumber != null)
+ {
+ if (!attrCert.getSerialNumber().equals(serialNumber))
+ {
+ return false;
+ }
+ }
+ if (holder != null)
+ {
+ if (!attrCert.getHolder().equals(holder))
+ {
+ return false;
+ }
+ }
+ if (issuer != null)
+ {
+ if (!attrCert.getIssuer().equals(issuer))
+ {
+ return false;
+ }
+ }
+
+ if (attributeCertificateValid != null)
+ {
+ try
+ {
+ attrCert.checkValidity(attributeCertificateValid);
+ }
+ catch (CertificateExpiredException e)
+ {
+ return false;
+ }
+ catch (CertificateNotYetValidException e)
+ {
+ return false;
+ }
+ }
+ if (!targetNames.isEmpty() || !targetGroups.isEmpty())
+ {
+
+ byte[] targetInfoExt = attrCert
+ .getExtensionValue(X509Extensions.TargetInformation.getId());
+ if (targetInfoExt != null)
+ {
+ TargetInformation targetinfo;
+ try
+ {
+ targetinfo = TargetInformation
+ .getInstance(new ASN1InputStream(
+ ((DEROctetString) DEROctetString
+ .fromByteArray(targetInfoExt)).getOctets())
+ .readObject());
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ catch (IllegalArgumentException e)
+ {
+ return false;
+ }
+ Targets[] targetss = targetinfo.getTargetsObjects();
+ if (!targetNames.isEmpty())
+ {
+ boolean found = false;
+
+ for (int i=0; i<targetss.length; i++)
+ {
+ Targets t = targetss[i];
+ Target[] targets = t.getTargets();
+ for (int j=0; j<targets.length; j++)
+ {
+ if (targetNames.contains(targets[j]
+ .getTargetName()))
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ if (!targetGroups.isEmpty())
+ {
+ boolean found = false;
+
+ for (int i=0; i<targetss.length; i++)
+ {
+ Targets t = targetss[i];
+ Target[] targets = t.getTargets();
+ for (int j=0; j<targets.length; j++)
+ {
+ if (targetGroups.contains(targets[j]
+ .getTargetGroup()))
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a clone of this object.
+ *
+ * @return the clone.
+ */
+ public Object clone()
+ {
+ X509AttributeCertStoreSelector sel = new X509AttributeCertStoreSelector();
+ sel.attributeCert = attributeCert;
+ sel.attributeCertificateValid = getAttributeCertificateValid();
+ sel.holder = holder;
+ sel.issuer = issuer;
+ sel.serialNumber = serialNumber;
+ sel.targetGroups = getTargetGroups();
+ sel.targetNames = getTargetNames();
+ return sel;
+ }
+
+ /**
+ * Returns the attribute certificate which must be matched.
+ *
+ * @return Returns the attribute certificate.
+ */
+ public X509AttributeCertificate getAttributeCert()
+ {
+ return attributeCert;
+ }
+
+ /**
+ * Set the attribute certificate to be matched. If <code>null</code> is
+ * given any will do.
+ *
+ * @param attributeCert The attribute certificate to set.
+ */
+ public void setAttributeCert(X509AttributeCertificate attributeCert)
+ {
+ this.attributeCert = attributeCert;
+ }
+
+ /**
+ * Get the criteria for the validity.
+ *
+ * @return Returns the attributeCertificateValid.
+ */
+ public Date getAttributeCertificateValid()
+ {
+ if (attributeCertificateValid != null)
+ {
+ return new Date(attributeCertificateValid.getTime());
+ }
+
+ return null;
+ }
+
+ /**
+ * Set the time, when the certificate must be valid. If <code>null</code>
+ * is given any will do.
+ *
+ * @param attributeCertificateValid The attribute certificate validation
+ * time to set.
+ */
+ public void setAttributeCertificateValid(Date attributeCertificateValid)
+ {
+ if (attributeCertificateValid != null)
+ {
+ this.attributeCertificateValid = new Date(attributeCertificateValid
+ .getTime());
+ }
+ else
+ {
+ this.attributeCertificateValid = null;
+ }
+ }
+
+ /**
+ * Gets the holder.
+ *
+ * @return Returns the holder.
+ */
+ public AttributeCertificateHolder getHolder()
+ {
+ return holder;
+ }
+
+ /**
+ * Sets the holder. If <code>null</code> is given any will do.
+ *
+ * @param holder The holder to set.
+ */
+ public void setHolder(AttributeCertificateHolder holder)
+ {
+ this.holder = holder;
+ }
+
+ /**
+ * Returns the issuer criterion.
+ *
+ * @return Returns the issuer.
+ */
+ public AttributeCertificateIssuer getIssuer()
+ {
+ return issuer;
+ }
+
+ /**
+ * Sets the issuer the attribute certificate must have. If <code>null</code>
+ * is given any will do.
+ *
+ * @param issuer The issuer to set.
+ */
+ public void setIssuer(AttributeCertificateIssuer issuer)
+ {
+ this.issuer = issuer;
+ }
+
+ /**
+ * Gets the serial number the attribute certificate must have.
+ *
+ * @return Returns the serialNumber.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ /**
+ * Sets the serial number the attribute certificate must have. If
+ * <code>null</code> is given any will do.
+ *
+ * @param serialNumber The serialNumber to set.
+ */
+ public void setSerialNumber(BigInteger serialNumber)
+ {
+ this.serialNumber = serialNumber;
+ }
+
+ /**
+ * Adds a target name criterion for the attribute certificate to the target
+ * information extension criteria. The <code>X509AttributeCertificate</code>
+ * must contain at least one of the specified target names.
+ * <p>
+ * Each attribute certificate may contain a target information extension
+ * limiting the servers where this attribute certificate can be used. If
+ * this extension is not present, the attribute certificate is not targeted
+ * and may be accepted by any server.
+ *
+ * @param name The name as a GeneralName (not <code>null</code>)
+ */
+ public void addTargetName(GeneralName name)
+ {
+ targetNames.add(name);
+ }
+
+ /**
+ * Adds a target name criterion for the attribute certificate to the target
+ * information extension criteria. The <code>X509AttributeCertificate</code>
+ * must contain at least one of the specified target names.
+ * <p>
+ * Each attribute certificate may contain a target information extension
+ * limiting the servers where this attribute certificate can be used. If
+ * this extension is not present, the attribute certificate is not targeted
+ * and may be accepted by any server.
+ *
+ * @param name a byte array containing the name in ASN.1 DER encoded form of a GeneralName
+ * @throws IOException if a parsing error occurs.
+ */
+ public void addTargetName(byte[] name) throws IOException
+ {
+ addTargetName(GeneralName.getInstance(ASN1Primitive.fromByteArray(name)));
+ }
+
+ /**
+ * Adds a collection with target names criteria. If <code>null</code> is
+ * given any will do.
+ * <p>
+ * The collection consists of either GeneralName objects or byte[] arrays representing
+ * DER encoded GeneralName structures.
+ *
+ * @param names A collection of target names.
+ * @throws IOException if a parsing error occurs.
+ * @see #addTargetName(byte[])
+ * @see #addTargetName(GeneralName)
+ */
+ public void setTargetNames(Collection names) throws IOException
+ {
+ targetNames = extractGeneralNames(names);
+ }
+
+ /**
+ * Gets the target names. The collection consists of <code>List</code>s
+ * made up of an <code>Integer</code> in the first entry and a DER encoded
+ * byte array or a <code>String</code> in the second entry.
+ * <p>
+ * The returned collection is immutable.
+ *
+ * @return The collection of target names
+ * @see #setTargetNames(Collection)
+ */
+ public Collection getTargetNames()
+ {
+ return Collections.unmodifiableCollection(targetNames);
+ }
+
+ /**
+ * Adds a target group criterion for the attribute certificate to the target
+ * information extension criteria. The <code>X509AttributeCertificate</code>
+ * must contain at least one of the specified target groups.
+ * <p>
+ * Each attribute certificate may contain a target information extension
+ * limiting the servers where this attribute certificate can be used. If
+ * this extension is not present, the attribute certificate is not targeted
+ * and may be accepted by any server.
+ *
+ * @param group The group as GeneralName form (not <code>null</code>)
+ */
+ public void addTargetGroup(GeneralName group)
+ {
+ targetGroups.add(group);
+ }
+
+ /**
+ * Adds a target group criterion for the attribute certificate to the target
+ * information extension criteria. The <code>X509AttributeCertificate</code>
+ * must contain at least one of the specified target groups.
+ * <p>
+ * Each attribute certificate may contain a target information extension
+ * limiting the servers where this attribute certificate can be used. If
+ * this extension is not present, the attribute certificate is not targeted
+ * and may be accepted by any server.
+ *
+ * @param name a byte array containing the group in ASN.1 DER encoded form of a GeneralName
+ * @throws IOException if a parsing error occurs.
+ */
+ public void addTargetGroup(byte[] name) throws IOException
+ {
+ addTargetGroup(GeneralName.getInstance(ASN1Primitive.fromByteArray(name)));
+ }
+
+ /**
+ * Adds a collection with target groups criteria. If <code>null</code> is
+ * given any will do.
+ * <p>
+ * The collection consists of <code>GeneralName</code> objects or <code>byte[]</code representing DER
+ * encoded GeneralNames.
+ *
+ * @param names A collection of target groups.
+ * @throws IOException if a parsing error occurs.
+ * @see #addTargetGroup(byte[])
+ * @see #addTargetGroup(GeneralName)
+ */
+ public void setTargetGroups(Collection names) throws IOException
+ {
+ targetGroups = extractGeneralNames(names);
+ }
+
+
+
+ /**
+ * Gets the target groups. The collection consists of <code>List</code>s
+ * made up of an <code>Integer</code> in the first entry and a DER encoded
+ * byte array or a <code>String</code> in the second entry.
+ * <p>
+ * The returned collection is immutable.
+ *
+ * @return The collection of target groups.
+ * @see #setTargetGroups(Collection)
+ */
+ public Collection getTargetGroups()
+ {
+ return Collections.unmodifiableCollection(targetGroups);
+ }
+
+ private Set extractGeneralNames(Collection names)
+ throws IOException
+ {
+ if (names == null || names.isEmpty())
+ {
+ return new HashSet();
+ }
+ Set temp = new HashSet();
+ for (Iterator it = names.iterator(); it.hasNext();)
+ {
+ Object o = it.next();
+ if (o instanceof GeneralName)
+ {
+ temp.add(o);
+ }
+ else
+ {
+ temp.add(GeneralName.getInstance(ASN1Primitive.fromByteArray((byte[])o)));
+ }
+ }
+ return temp;
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509CRLStoreSelector.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509CRLStoreSelector.java
new file mode 100644
index 00000000..554911f0
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509CRLStoreSelector.java
@@ -0,0 +1,330 @@
+package org.spongycastle.x509;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Selector;
+import org.spongycastle.x509.extension.X509ExtensionUtil;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.CRL;
+import java.security.cert.X509CRL;
+import org.spongycastle.jce.cert.X509CRLSelector;
+
+/**
+ * This class is a Selector implementation for X.509 certificate revocation
+ * lists.
+ *
+ * @see org.spongycastle.util.Selector
+ * @see org.spongycastle.x509.X509Store
+ * @see org.spongycastle.jce.provider.X509StoreCRLCollection
+ */
+public class X509CRLStoreSelector
+ extends X509CRLSelector
+ implements Selector
+{
+ private boolean deltaCRLIndicator = false;
+
+ private boolean completeCRLEnabled = false;
+
+ private BigInteger maxBaseCRLNumber = null;
+
+ private byte[] issuingDistributionPoint = null;
+
+ private boolean issuingDistributionPointEnabled = false;
+
+ private X509AttributeCertificate attrCertChecking;
+
+ /**
+ * Returns if the issuing distribution point criteria should be applied.
+ * Defaults to <code>false</code>.
+ * <p>
+ * You may also set the issuing distribution point criteria if not a missing
+ * issuing distribution point should be assumed.
+ *
+ * @return Returns if the issuing distribution point check is enabled.
+ */
+ public boolean isIssuingDistributionPointEnabled()
+ {
+ return issuingDistributionPointEnabled;
+ }
+
+ /**
+ * Enables or disables the issuing distribution point check.
+ *
+ * @param issuingDistributionPointEnabled <code>true</code> to enable the
+ * issuing distribution point check.
+ */
+ public void setIssuingDistributionPointEnabled(
+ boolean issuingDistributionPointEnabled)
+ {
+ this.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
+ }
+
+ /**
+ * Sets the attribute certificate being checked. This is not a criterion.
+ * Rather, it is optional information that may help a {@link X509Store} find
+ * CRLs that would be relevant when checking revocation for the specified
+ * attribute certificate. If <code>null</code> is specified, then no such
+ * optional information is provided.
+ *
+ * @param attrCert the <code>X509AttributeCertificate</code> being checked (or
+ * <code>null</code>)
+ * @see #getAttrCertificateChecking()
+ */
+ public void setAttrCertificateChecking(X509AttributeCertificate attrCert)
+ {
+ attrCertChecking = attrCert;
+ }
+
+ /**
+ * Returns the attribute certificate being checked.
+ *
+ * @return Returns the attribute certificate being checked.
+ * @see #setAttrCertificateChecking(X509AttributeCertificate)
+ */
+ public X509AttributeCertificate getAttrCertificateChecking()
+ {
+ return attrCertChecking;
+ }
+
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509CRL))
+ {
+ return false;
+ }
+ X509CRL crl = (X509CRL)obj;
+ ASN1Integer dci = null;
+ try
+ {
+ byte[] bytes = crl
+ .getExtensionValue(X509Extensions.DeltaCRLIndicator.getId());
+ if (bytes != null)
+ {
+ dci = ASN1Integer.getInstance(X509ExtensionUtil
+ .fromExtensionValue(bytes));
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ if (isDeltaCRLIndicatorEnabled())
+ {
+ if (dci == null)
+ {
+ return false;
+ }
+ }
+ if (isCompleteCRLEnabled())
+ {
+ if (dci != null)
+ {
+ return false;
+ }
+ }
+ if (dci != null)
+ {
+
+ if (maxBaseCRLNumber != null)
+ {
+ if (dci.getPositiveValue().compareTo(maxBaseCRLNumber) == 1)
+ {
+ return false;
+ }
+ }
+ }
+ if (issuingDistributionPointEnabled)
+ {
+ byte[] idp = crl
+ .getExtensionValue(X509Extensions.IssuingDistributionPoint
+ .getId());
+ if (issuingDistributionPoint == null)
+ {
+ if (idp != null)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!Arrays.areEqual(idp, issuingDistributionPoint))
+ {
+ return false;
+ }
+ }
+
+ }
+ return super.match((X509CRL)obj);
+ }
+
+ public boolean match(CRL crl)
+ {
+ return match((Object)crl);
+ }
+
+ /**
+ * Returns if this selector must match CRLs with the delta CRL indicator
+ * extension set. Defaults to <code>false</code>.
+ *
+ * @return Returns <code>true</code> if only CRLs with the delta CRL
+ * indicator extension are selected.
+ */
+ public boolean isDeltaCRLIndicatorEnabled()
+ {
+ return deltaCRLIndicator;
+ }
+
+ /**
+ * If this is set to <code>true</code> the CRL reported contains the delta
+ * CRL indicator CRL extension.
+ * <p>
+ * {@link #setCompleteCRLEnabled(boolean)} and
+ * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
+ *
+ * @param deltaCRLIndicator <code>true</code> if the delta CRL indicator
+ * extension must be in the CRL.
+ */
+ public void setDeltaCRLIndicatorEnabled(boolean deltaCRLIndicator)
+ {
+ this.deltaCRLIndicator = deltaCRLIndicator;
+ }
+
+ /**
+ * Returns an instance of this from a <code>X509CRLSelector</code>.
+ *
+ * @param selector A <code>X509CRLSelector</code> instance.
+ * @return An instance of an <code>X509CRLStoreSelector</code>.
+ * @exception IllegalArgumentException if selector is null or creation
+ * fails.
+ */
+ public static X509CRLStoreSelector getInstance(X509CRLSelector selector)
+ {
+ if (selector == null)
+ {
+ throw new IllegalArgumentException(
+ "cannot create from null selector");
+ }
+ X509CRLStoreSelector cs = new X509CRLStoreSelector();
+ cs.setCertificateChecking(selector.getCertificateChecking());
+ cs.setDateAndTime(selector.getDateAndTime());
+ try
+ {
+ cs.setIssuerNames(selector.getIssuerNames());
+ }
+ catch (IOException e)
+ {
+ // cannot happen
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ //cs.setIssuers(selector.getIssuers());
+ cs.setMaxCRLNumber(selector.getMaxCRL());
+ cs.setMinCRLNumber(selector.getMinCRL());
+ return cs;
+ }
+
+ public Object clone()
+ {
+ X509CRLStoreSelector sel = X509CRLStoreSelector.getInstance(this);
+ sel.deltaCRLIndicator = deltaCRLIndicator;
+ sel.completeCRLEnabled = completeCRLEnabled;
+ sel.maxBaseCRLNumber = maxBaseCRLNumber;
+ sel.attrCertChecking = attrCertChecking;
+ sel.issuingDistributionPointEnabled = issuingDistributionPointEnabled;
+ sel.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint);
+ return sel;
+ }
+
+ /**
+ * If <code>true</code> only complete CRLs are returned. Defaults to
+ * <code>false</code>.
+ *
+ * @return <code>true</code> if only complete CRLs are returned.
+ */
+ public boolean isCompleteCRLEnabled()
+ {
+ return completeCRLEnabled;
+ }
+
+ /**
+ * If set to <code>true</code> only complete CRLs are returned.
+ * <p>
+ * {@link #setCompleteCRLEnabled(boolean)} and
+ * {@link #setDeltaCRLIndicatorEnabled(boolean)} excluded each other.
+ *
+ * @param completeCRLEnabled <code>true</code> if only complete CRLs
+ * should be returned.
+ */
+ public void setCompleteCRLEnabled(boolean completeCRLEnabled)
+ {
+ this.completeCRLEnabled = completeCRLEnabled;
+ }
+
+ /**
+ * Get the maximum base CRL number. Defaults to <code>null</code>.
+ *
+ * @return Returns the maximum base CRL number.
+ * @see #setMaxBaseCRLNumber(BigInteger)
+ */
+ public BigInteger getMaxBaseCRLNumber()
+ {
+ return maxBaseCRLNumber;
+ }
+
+ /**
+ * Sets the maximum base CRL number. Setting to <code>null</code> disables
+ * this cheack.
+ * <p>
+ * This is only meaningful for delta CRLs. Complete CRLs must have a CRL
+ * number which is greater or equal than the base number of the
+ * corresponding CRL.
+ *
+ * @param maxBaseCRLNumber The maximum base CRL number to set.
+ */
+ public void setMaxBaseCRLNumber(BigInteger maxBaseCRLNumber)
+ {
+ this.maxBaseCRLNumber = maxBaseCRLNumber;
+ }
+
+ /**
+ * Returns the issuing distribution point. Defaults to <code>null</code>,
+ * which is a missing issuing distribution point extension.
+ * <p>
+ * The internal byte array is cloned before it is returned.
+ * <p>
+ * The criteria must be enable with
+ * {@link #setIssuingDistributionPointEnabled(boolean)}.
+ *
+ * @return Returns the issuing distribution point.
+ * @see #setIssuingDistributionPoint(byte[])
+ */
+ public byte[] getIssuingDistributionPoint()
+ {
+ return Arrays.clone(issuingDistributionPoint);
+ }
+
+ /**
+ * Sets the issuing distribution point.
+ * <p>
+ * The issuing distribution point extension is a CRL extension which
+ * identifies the scope and the distribution point of a CRL. The scope
+ * contains among others information about revocation reasons contained in
+ * the CRL. Delta CRLs and complete CRLs must have matching issuing
+ * distribution points.
+ * <p>
+ * The byte array is cloned to protect against subsequent modifications.
+ * <p>
+ * You must also enable or disable this criteria with
+ * {@link #setIssuingDistributionPointEnabled(boolean)}.
+ *
+ * @param issuingDistributionPoint The issuing distribution point to set.
+ * This is the DER encoded OCTET STRING extension value.
+ * @see #getIssuingDistributionPoint()
+ */
+ public void setIssuingDistributionPoint(byte[] issuingDistributionPoint)
+ {
+ this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint);
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509CertStoreSelector.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509CertStoreSelector.java
new file mode 100644
index 00000000..f4efcddb
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509CertStoreSelector.java
@@ -0,0 +1,86 @@
+package org.spongycastle.x509;
+
+import org.spongycastle.util.Selector;
+
+import java.io.IOException;
+import java.security.cert.Certificate;
+import org.spongycastle.jce.cert.X509CertSelector;
+import java.security.cert.X509Certificate;
+
+/**
+ * This class is a Selector implementation for X.509 certificates.
+ *
+ * @see org.spongycastle.util.Selector
+ * @see org.spongycastle.x509.X509Store
+ * @see org.spongycastle.jce.provider.X509StoreCertCollection
+ */
+public class X509CertStoreSelector
+ extends X509CertSelector
+ implements Selector
+{
+ public boolean match(Object obj)
+ {
+ if (!(obj instanceof X509Certificate))
+ {
+ return false;
+ }
+
+ X509Certificate other = (X509Certificate)obj;
+
+ return super.match(other);
+ }
+
+ public boolean match(Certificate cert)
+ {
+ return match((Object)cert);
+ }
+
+ public Object clone()
+ {
+ X509CertStoreSelector selector = (X509CertStoreSelector)super.clone();
+
+ return selector;
+ }
+
+ /**
+ * Returns an instance of this from a <code>X509CertSelector</code>.
+ *
+ * @param selector A <code>X509CertSelector</code> instance.
+ * @return An instance of an <code>X509CertStoreSelector</code>.
+ * @exception IllegalArgumentException if selector is null or creation fails.
+ */
+ public static X509CertStoreSelector getInstance(X509CertSelector selector)
+ {
+ if (selector == null)
+ {
+ throw new IllegalArgumentException("cannot create from null selector");
+ }
+ X509CertStoreSelector cs = new X509CertStoreSelector();
+ cs.setAuthorityKeyIdentifier(selector.getAuthorityKeyIdentifier());
+ cs.setBasicConstraints(selector.getBasicConstraints());
+ cs.setCertificate(selector.getCertificate());
+ cs.setCertificateValid(selector.getCertificateValid());
+ cs.setMatchAllSubjectAltNames(selector.getMatchAllSubjectAltNames());
+ try
+ {
+ cs.setPathToNames(selector.getPathToNames());
+ cs.setExtendedKeyUsage(selector.getExtendedKeyUsage());
+ //cs.setNameConstraints(selector.getNameConstraints());
+ cs.setPolicy(selector.getPolicy());
+ cs.setSubjectPublicKeyAlgID(selector.getSubjectPublicKeyAlgID());
+ cs.setSubject(selector.getSubjectAsBytes());
+ cs.setIssuer(selector.getIssuerAsBytes());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("error in passed in selector: " + e);
+ }
+ cs.setKeyUsage(selector.getKeyUsage());
+ cs.setPrivateKeyValid(selector.getPrivateKeyValid());
+ cs.setSerialNumber(selector.getSerialNumber());
+ cs.setSubjectKeyIdentifier(selector.getSubjectKeyIdentifier());
+ cs.setSubjectPublicKey(selector.getSubjectPublicKey());
+ return cs;
+ }
+
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509Util.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509Util.java
new file mode 100644
index 00000000..93ec8b63
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509Util.java
@@ -0,0 +1,397 @@
+package org.spongycastle.x509;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.ArrayList;
+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.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSASSAPSSparams;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.util.Strings;
+
+class X509Util
+{
+ private static Hashtable algorithms = new Hashtable();
+ private static Hashtable params = new Hashtable();
+ private static Set noParams = new HashSet();
+
+ static
+ {
+ algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
+ algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
+ algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption);
+ algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption);
+ algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption);
+ algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption);
+ algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption);
+ algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption);
+ algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption);
+ algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
+ algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
+ algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1);
+ algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1);
+ algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224);
+ algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256);
+ algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384);
+ algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512);
+ algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1);
+ algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224);
+ algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
+ algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
+ algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
+ algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+ algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+
+ //
+ // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
+ // The parameters field SHALL be NULL for RSA based signature algorithms.
+ //
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
+ noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
+ noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha384);
+ noParams.add(NISTObjectIdentifiers.dsa_with_sha512);
+
+ //
+ // RFC 4491
+ //
+ noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
+ noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
+
+ //
+ // explicit params
+ //
+ AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
+ params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
+
+ AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull());
+ params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
+
+ AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull());
+ params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
+
+ AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull());
+ params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
+
+ AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull());
+ params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
+ }
+
+ private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
+ {
+ return new RSASSAPSSparams(
+ hashAlgId,
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId),
+ new ASN1Integer(saltSize),
+ new ASN1Integer(1));
+ }
+
+ static ASN1ObjectIdentifier getAlgorithmOID(
+ String algorithmName)
+ {
+ algorithmName = Strings.toUpperCase(algorithmName);
+
+ if (algorithms.containsKey(algorithmName))
+ {
+ return (ASN1ObjectIdentifier)algorithms.get(algorithmName);
+ }
+
+ return new ASN1ObjectIdentifier(algorithmName);
+ }
+
+ static AlgorithmIdentifier getSigAlgID(
+ ASN1ObjectIdentifier sigOid,
+ String algorithmName)
+ {
+ if (noParams.contains(sigOid))
+ {
+ return new AlgorithmIdentifier(sigOid);
+ }
+
+ algorithmName = Strings.toUpperCase(algorithmName);
+
+ if (params.containsKey(algorithmName))
+ {
+ return new AlgorithmIdentifier(sigOid, (ASN1Encodable)params.get(algorithmName));
+ }
+ else
+ {
+ return new AlgorithmIdentifier(sigOid, new DERNull());
+ }
+ }
+
+ static Iterator getAlgNames()
+ {
+ Enumeration e = algorithms.keys();
+ List l = new ArrayList();
+
+ while (e.hasMoreElements())
+ {
+ l.add(e.nextElement());
+ }
+
+ return l.iterator();
+ }
+
+ static Signature getSignatureInstance(
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return Signature.getInstance(algorithm);
+ }
+
+ static Signature getSignatureInstance(
+ String algorithm,
+ String provider)
+ throws NoSuchProviderException, NoSuchAlgorithmException
+ {
+ if (provider != null)
+ {
+ return Signature.getInstance(algorithm, provider);
+ }
+ else
+ {
+ return Signature.getInstance(algorithm);
+ }
+ }
+
+ static byte[] calculateSignature(
+ ASN1ObjectIdentifier sigOid,
+ String sigName,
+ PrivateKey key,
+ SecureRandom random,
+ ASN1Encodable object)
+ throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException
+ {
+ Signature sig;
+
+ if (sigOid == null)
+ {
+ throw new IllegalStateException("no signature algorithm specified");
+ }
+
+ sig = X509Util.getSignatureInstance(sigName);
+
+ if (random != null)
+ {
+ sig.initSign(key, random);
+ }
+ else
+ {
+ sig.initSign(key);
+ }
+
+ sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+
+ return sig.sign();
+ }
+
+ static byte[] calculateSignature(
+ ASN1ObjectIdentifier sigOid,
+ String sigName,
+ String provider,
+ PrivateKey key,
+ SecureRandom random,
+ ASN1Encodable object)
+ throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException
+ {
+ Signature sig;
+
+ if (sigOid == null)
+ {
+ throw new IllegalStateException("no signature algorithm specified");
+ }
+
+ sig = X509Util.getSignatureInstance(sigName, provider);
+
+ if (random != null)
+ {
+ sig.initSign(key, random);
+ }
+ else
+ {
+ sig.initSign(key);
+ }
+
+ sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+
+ return sig.sign();
+ }
+
+ 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.
+ */
+ static Implementation getImplementation(
+ String baseName,
+ String algorithm,
+ Provider prov)
+ throws NoSuchAlgorithmException
+ {
+ algorithm = Strings.toUpperCase(algorithm);
+
+ String alias;
+
+ while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null)
+ {
+ algorithm = alias;
+ }
+
+ String className = prov.getProperty(baseName + "." + algorithm);
+
+ if (className != null)
+ {
+ try
+ {
+ Class cls;
+ ClassLoader clsLoader = prov.getClass().getClassLoader();
+
+ if (clsLoader != null)
+ {
+ cls = clsLoader.loadClass(className);
+ }
+ else
+ {
+ cls = Class.forName(className);
+ }
+
+ return new Implementation(cls.newInstance(), prov);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new IllegalStateException(
+ "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!");
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException(
+ "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!");
+ }
+ }
+
+ throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName());
+ }
+
+ /**
+ * return an implementation for a given algorithm/provider.
+ * If the provider is null, we grab the first avalaible who has the required algorithm.
+ */
+ static Implementation getImplementation(
+ String baseName,
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] prov = Security.getProviders();
+
+ //
+ // search every provider looking for the algorithm we want.
+ //
+ for (int i = 0; i != prov.length; i++)
+ {
+ //
+ // try case insensitive
+ //
+ Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]);
+ if (imp != null)
+ {
+ return imp;
+ }
+
+ try
+ {
+ imp = getImplementation(baseName, algorithm, prov[i]);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // continue
+ }
+ }
+
+ throw new NoSuchAlgorithmException("cannot find implementation " + algorithm);
+ }
+
+ static Provider getProvider(String provider)
+ throws NoSuchProviderException
+ {
+ Provider prov = Security.getProvider(provider);
+
+ if (prov == null)
+ {
+ throw new NoSuchProviderException("Provider " + provider + " not found");
+ }
+
+ return prov;
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509V1CertificateGenerator.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509V1CertificateGenerator.java
new file mode 100644
index 00000000..d038b5cf
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509V1CertificateGenerator.java
@@ -0,0 +1,341 @@
+package org.spongycastle.x509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.TBSCertificate;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V1TBSCertificateGenerator;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.jce.provider.X509CertificateObject;
+
+/**
+ * class to produce an X.509 Version 1 certificate.
+ * @deprecated use org.spongycastle.cert.X509v1CertificateBuilder.
+ */
+public class X509V1CertificateGenerator
+{
+ private V1TBSCertificateGenerator tbsGen;
+ private ASN1ObjectIdentifier sigOID;
+ private AlgorithmIdentifier sigAlgId;
+ private String signatureAlgorithm;
+
+ public X509V1CertificateGenerator()
+ {
+ tbsGen = new V1TBSCertificateGenerator();
+ }
+
+ /**
+ * reset the generator
+ */
+ public void reset()
+ {
+ tbsGen = new V1TBSCertificateGenerator();
+ }
+
+ /**
+ * set the serial number for the certificate.
+ */
+ public void setSerialNumber(
+ BigInteger serialNumber)
+ {
+ if (serialNumber.compareTo(BigInteger.ZERO) <= 0)
+ {
+ throw new IllegalArgumentException("serial number must be a positive integer");
+ }
+
+ tbsGen.setSerialNumber(new ASN1Integer(serialNumber));
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X509Name issuer)
+ {
+ tbsGen.setIssuer(issuer);
+ }
+
+ public void setNotBefore(
+ Date date)
+ {
+ tbsGen.setStartDate(new Time(date));
+ }
+
+ public void setNotAfter(
+ Date date)
+ {
+ tbsGen.setEndDate(new Time(date));
+ }
+
+ /**
+ * Set the subject distinguished name. The subject describes the entity associated with the public key.
+ */
+ public void setSubjectDN(
+ X509Name subject)
+ {
+ tbsGen.setSubject(subject);
+ }
+
+ public void setPublicKey(
+ PublicKey key)
+ {
+ try
+ {
+ tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
+ new ByteArrayInputStream(key.getEncoded())).readObject()));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("unable to process key - " + e.toString());
+ }
+ }
+
+ /**
+ * Set the signature algorithm. This can be either a name or an OID, names
+ * are treated as case insensitive.
+ *
+ * @param signatureAlgorithm string representation of the algorithm name.
+ */
+ public void setSignatureAlgorithm(
+ String signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ try
+ {
+ sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested");
+ }
+
+ sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
+
+ tbsGen.setSignature(sigAlgId);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "SC".
+ * @deprecated use generate(key, "SC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "SC", null);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "SC" and the passed in source of randomness
+ * @deprecated use generate(key, random, "SC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ SecureRandom random)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "SC", random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ return generateX509Certificate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generate(key, provider, random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw e;
+ }
+ catch (SignatureException e)
+ {
+ throw e;
+ }
+ catch (InvalidKeyException e)
+ {
+ throw e;
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SecurityException("exception: " + e);
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider.
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "SC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, (SecureRandom)null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider and the passed in source of randomness
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "SC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ return generateJcaObject(tbsCert, signature);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing, and the passed in source
+ * of randomness (if required).
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ return generateJcaObject(tbsCert, signature);
+ }
+
+ private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature)
+ throws CertificateEncodingException
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCert);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ try
+ {
+ return new X509CertificateObject(Certificate.getInstance(new DERSequence(v)));
+ }
+ catch (CertificateParsingException e)
+ {
+ throw new ExtCertificateEncodingException("exception producing certificate object", e);
+ }
+ }
+
+ /**
+ * Return an iterator of the signature names supported by the generator.
+ *
+ * @return an iterator containing recognised names.
+ */
+ public Iterator getSignatureAlgNames()
+ {
+ return X509Util.getAlgNames();
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509V2CRLGenerator.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509V2CRLGenerator.java
new file mode 100644
index 00000000..8da36afb
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509V2CRLGenerator.java
@@ -0,0 +1,430 @@
+package org.spongycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CRLException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.TBSCertList;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V2TBSCertListGenerator;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.asn1.x509.X509ExtensionsGenerator;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.jce.provider.X509CRLObject;
+
+/**
+ * class to produce an X.509 Version 2 CRL.
+ * @deprecated use org.spongycastle.cert.X509v2CRLBuilder.
+ */
+public class X509V2CRLGenerator
+{
+ private V2TBSCertListGenerator tbsGen;
+ private ASN1ObjectIdentifier sigOID;
+ private AlgorithmIdentifier sigAlgId;
+ private String signatureAlgorithm;
+ private X509ExtensionsGenerator extGenerator;
+
+ public X509V2CRLGenerator()
+ {
+ tbsGen = new V2TBSCertListGenerator();
+ extGenerator = new X509ExtensionsGenerator();
+ }
+
+ /**
+ * reset the generator
+ */
+ public void reset()
+ {
+ tbsGen = new V2TBSCertListGenerator();
+ extGenerator.reset();
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X509Name issuer)
+ {
+ tbsGen.setIssuer(issuer);
+ }
+
+ public void setThisUpdate(
+ Date date)
+ {
+ tbsGen.setThisUpdate(new Time(date));
+ }
+
+ public void setNextUpdate(
+ Date date)
+ {
+ tbsGen.setNextUpdate(new Time(date));
+ }
+
+ /**
+ * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise
+ * or 0 if CRLReason is not to be used
+ **/
+ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason)
+ {
+ tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason);
+ }
+
+ /**
+ * Add a CRL entry with an Invalidity Date extension as well as a CRLReason extension.
+ * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise
+ * or 0 if CRLReason is not to be used
+ **/
+ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason, Date invalidityDate)
+ {
+ tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate));
+ }
+
+ /**
+ * Add a CRL entry with extensions.
+ **/
+ public void addCRLEntry(BigInteger userCertificate, Date revocationDate, X509Extensions extensions)
+ {
+ tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), Extensions.getInstance(extensions));
+ }
+
+ /**
+ * Add the CRLEntry objects contained in a previous CRL.
+ *
+ * @param other the X509CRL to source the other entries from.
+ */
+ public void addCRL(X509CRL other)
+ throws CRLException
+ {
+ Set revocations = other.getRevokedCertificates();
+
+ if (revocations != null)
+ {
+ Iterator it = revocations.iterator();
+ while (it.hasNext())
+ {
+ X509CRLEntry entry = (X509CRLEntry)it.next();
+
+ ASN1InputStream aIn = new ASN1InputStream(entry.getEncoded());
+
+ try
+ {
+ tbsGen.addCRLEntry(ASN1Sequence.getInstance(aIn.readObject()));
+ }
+ catch (IOException e)
+ {
+ throw new CRLException("exception processing encoding of CRL: " + e.toString());
+ }
+ }
+ }
+ }
+
+ /**
+ * Set the signature algorithm. This can be either a name or an OID, names
+ * are treated as case insensitive.
+ *
+ * @param signatureAlgorithm string representation of the algorithm name.
+ */
+ public void setSignatureAlgorithm(
+ String signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ try
+ {
+ sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested");
+ }
+
+ sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
+
+ tbsGen.setSignature(sigAlgId);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 0)
+ */
+ public void addExtension(
+ String oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 0)
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 0)
+ */
+ public void addExtension(
+ String oid,
+ boolean critical,
+ byte[] value)
+ {
+ this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 0)
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
+ }
+
+ /**
+ * generate an X509 CRL, based on the current issuer and subject
+ * using the default provider "SC".
+ * @deprecated use generate(key, "SC")
+ */
+ public X509CRL generateX509CRL(
+ PrivateKey key)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509CRL(key, "SC", null);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 CRL, based on the current issuer and subject
+ * using the default provider "SC" and an user defined SecureRandom object as
+ * source of randomness.
+ * @deprecated use generate(key, random, "SC")
+ */
+ public X509CRL generateX509CRL(
+ PrivateKey key,
+ SecureRandom random)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509CRL(key, "SC", random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the passed in provider for the signing.
+ * @deprecated use generate()
+ */
+ public X509CRL generateX509CRL(
+ PrivateKey key,
+ String provider)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ return generateX509CRL(key, provider, null);
+ }
+
+ /**
+ * generate an X509 CRL, based on the current issuer and subject,
+ * using the passed in provider for the signing.
+ * @deprecated use generate()
+ */
+ public X509CRL generateX509CRL(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generate(key, provider, random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw e;
+ }
+ catch (SignatureException e)
+ {
+ throw e;
+ }
+ catch (InvalidKeyException e)
+ {
+ throw e;
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SecurityException("exception: " + e);
+ }
+ }
+
+ /**
+ * generate an X509 CRL, based on the current issuer and subject
+ * using the default provider.
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "SC".
+ * </p>
+ */
+ public X509CRL generate(
+ PrivateKey key)
+ throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, (SecureRandom)null);
+ }
+
+ /**
+ * generate an X509 CRL, based on the current issuer and subject
+ * using the default provider and an user defined SecureRandom object as
+ * source of randomness.
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "SC".
+ * </p>
+ */
+ public X509CRL generate(
+ PrivateKey key,
+ SecureRandom random)
+ throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertList tbsCrl = generateCertList();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCrl);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCRLException("cannot generate CRL encoding", e);
+ }
+
+ return generateJcaObject(tbsCrl, signature);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the passed in provider for the signing.
+ */
+ public X509CRL generate(
+ PrivateKey key,
+ String provider)
+ throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 CRL, based on the current issuer and subject,
+ * using the passed in provider for the signing.
+ */
+ public X509CRL generate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertList tbsCrl = generateCertList();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCrl);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCRLException("cannot generate CRL encoding", e);
+ }
+
+ return generateJcaObject(tbsCrl, signature);
+ }
+
+ private TBSCertList generateCertList()
+ {
+ if (!extGenerator.isEmpty())
+ {
+ tbsGen.setExtensions(extGenerator.generate());
+ }
+
+ return tbsGen.generateTBSCertList();
+ }
+
+ private X509CRL generateJcaObject(TBSCertList tbsCrl, byte[] signature)
+ throws CRLException
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCrl);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return new X509CRLObject(new CertificateList(new DERSequence(v)));
+ }
+
+ /**
+ * Return an iterator of the signature names supported by the generator.
+ *
+ * @return an iterator containing recognised names.
+ */
+ public Iterator getSignatureAlgNames()
+ {
+ return X509Util.getAlgNames();
+ }
+
+ private static class ExtCRLException
+ extends CRLException
+ {
+ Throwable cause;
+
+ ExtCRLException(String message, Throwable cause)
+ {
+ super(message);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
+}
diff --git a/prov/src/main/jdk1.3/org/spongycastle/x509/X509V3CertificateGenerator.java b/prov/src/main/jdk1.3/org/spongycastle/x509/X509V3CertificateGenerator.java
new file mode 100644
index 00000000..e58310e2
--- /dev/null
+++ b/prov/src/main/jdk1.3/org/spongycastle/x509/X509V3CertificateGenerator.java
@@ -0,0 +1,491 @@
+package org.spongycastle.x509;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.TBSCertificate;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V3TBSCertificateGenerator;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.X509ExtensionsGenerator;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.jce.provider.X509CertificateObject;
+import org.spongycastle.x509.extension.X509ExtensionUtil;
+
+/**
+ * class to produce an X.509 Version 3 certificate.
+ * @deprecated use org.spongycastle.cert.X509v3CertificateBuilder.
+ */
+public class X509V3CertificateGenerator
+{
+ private V3TBSCertificateGenerator tbsGen;
+ private ASN1ObjectIdentifier sigOID;
+ private AlgorithmIdentifier sigAlgId;
+ private String signatureAlgorithm;
+ private X509ExtensionsGenerator extGenerator;
+
+ public X509V3CertificateGenerator()
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ extGenerator = new X509ExtensionsGenerator();
+ }
+
+ /**
+ * reset the generator
+ */
+ public void reset()
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ extGenerator.reset();
+ }
+
+ /**
+ * set the serial number for the certificate.
+ */
+ public void setSerialNumber(
+ BigInteger serialNumber)
+ {
+ if (serialNumber.compareTo(BigInteger.ZERO) <= 0)
+ {
+ throw new IllegalArgumentException("serial number must be a positive integer");
+ }
+
+ tbsGen.setSerialNumber(new ASN1Integer(serialNumber));
+ }
+
+ /**
+ * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
+ * certificate.
+ */
+ public void setIssuerDN(
+ X509Name issuer)
+ {
+ tbsGen.setIssuer(issuer);
+ }
+
+ public void setNotBefore(
+ Date date)
+ {
+ tbsGen.setStartDate(new Time(date));
+ }
+
+ public void setNotAfter(
+ Date date)
+ {
+ tbsGen.setEndDate(new Time(date));
+ }
+
+ /**
+ * Set the subject distinguished name. The subject describes the entity associated with the public key.
+ */
+ public void setSubjectDN(
+ X509Name subject)
+ {
+ tbsGen.setSubject(subject);
+ }
+
+ public void setPublicKey(
+ PublicKey key)
+ throws IllegalArgumentException
+ {
+ try
+ {
+ tbsGen.setSubjectPublicKeyInfo(
+ SubjectPublicKeyInfo.getInstance(new ASN1InputStream(key.getEncoded()).readObject()));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("unable to process key - " + e.toString());
+ }
+ }
+
+ /**
+ * Set the signature algorithm. This can be either a name or an OID, names
+ * are treated as case insensitive.
+ *
+ * @param signatureAlgorithm string representation of the algorithm name.
+ */
+ public void setSignatureAlgorithm(
+ String signatureAlgorithm)
+ {
+ this.signatureAlgorithm = signatureAlgorithm;
+
+ try
+ {
+ sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unknown signature type requested: " + signatureAlgorithm);
+ }
+
+ sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
+
+ tbsGen.setSignature(sigAlgId);
+ }
+
+ /**
+ * Set the subject unique ID - note: it is very rare that it is correct to do this.
+ */
+ public void setSubjectUniqueID(boolean[] uniqueID)
+ {
+ tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID));
+ }
+
+ /**
+ * Set the issuer unique ID - note: it is very rare that it is correct to do this.
+ */
+ public void setIssuerUniqueID(boolean[] uniqueID)
+ {
+ tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID));
+ }
+
+ private DERBitString booleanToBitString(boolean[] id)
+ {
+ byte[] bytes = new byte[(id.length + 7) / 8];
+
+ for (int i = 0; i != id.length; i++)
+ {
+ bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0;
+ }
+
+ int pad = id.length % 8;
+
+ if (pad == 0)
+ {
+ return new DERBitString(bytes);
+ }
+ else
+ {
+ return new DERBitString(bytes, 8 - pad);
+ }
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ */
+ public void addExtension(
+ String oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ ASN1Encodable value)
+ {
+ extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ * The value parameter becomes the contents of the octet string associated
+ * with the extension.
+ */
+ public void addExtension(
+ String oid,
+ boolean critical,
+ byte[] value)
+ {
+ this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ */
+ public void addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ byte[] value)
+ {
+ extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ * copying the extension value from another certificate.
+ * @throws CertificateParsingException if the extension cannot be extracted.
+ */
+ public void copyAndAddExtension(
+ String oid,
+ boolean critical,
+ X509Certificate cert)
+ throws CertificateParsingException
+ {
+ byte[] extValue = cert.getExtensionValue(oid);
+
+ if (extValue == null)
+ {
+ throw new CertificateParsingException("extension " + oid + " not present");
+ }
+
+ try
+ {
+ ASN1Encodable value = X509ExtensionUtil.fromExtensionValue(extValue);
+
+ this.addExtension(oid, critical, value);
+ }
+ catch (IOException e)
+ {
+ throw new CertificateParsingException(e.toString());
+ }
+ }
+
+ /**
+ * add a given extension field for the standard extensions tag (tag 3)
+ * copying the extension value from another certificate.
+ * @throws CertificateParsingException if the extension cannot be extracted.
+ */
+ public void copyAndAddExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ X509Certificate cert)
+ throws CertificateParsingException
+ {
+ this.copyAndAddExtension(oid.getId(), critical, cert);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "SC".
+ * @deprecated use generate(key, "SC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "SC", null);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider "SC", and the passed in source of randomness
+ * (if required).
+ * @deprecated use generate(key, random, "SC")
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ SecureRandom random)
+ throws SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generateX509Certificate(key, "SC", random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new SecurityException("BC provider not installed!");
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing.
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ return generateX509Certificate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing and the supplied source
+ * of randomness, if required.
+ * @deprecated use generate()
+ */
+ public X509Certificate generateX509Certificate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
+ {
+ try
+ {
+ return generate(key, provider, random);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw e;
+ }
+ catch (SignatureException e)
+ {
+ throw e;
+ }
+ catch (InvalidKeyException e)
+ {
+ throw e;
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new SecurityException("exception: " + e);
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider.
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "SC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, (SecureRandom)null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject
+ * using the default provider, and the passed in source of randomness
+ * (if required).
+ * <p>
+ * <b>Note:</b> this differs from the deprecated method in that the default provider is
+ * used - not "SC".
+ * </p>
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = generateTbsCert();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ try
+ {
+ return generateJcaObject(tbsCert, signature);
+ }
+ catch (CertificateParsingException e)
+ {
+ throw new ExtCertificateEncodingException("exception producing certificate object", e);
+ }
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing.
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ return generate(key, provider, null);
+ }
+
+ /**
+ * generate an X509 certificate, based on the current issuer and subject,
+ * using the passed in provider for the signing and the supplied source
+ * of randomness, if required.
+ */
+ public X509Certificate generate(
+ PrivateKey key,
+ String provider,
+ SecureRandom random)
+ throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
+ {
+ TBSCertificate tbsCert = generateTbsCert();
+ byte[] signature;
+
+ try
+ {
+ signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert);
+ }
+ catch (IOException e)
+ {
+ throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
+ }
+
+ try
+ {
+ return generateJcaObject(tbsCert, signature);
+ }
+ catch (CertificateParsingException e)
+ {
+ throw new ExtCertificateEncodingException("exception producing certificate object", e);
+ }
+ }
+
+ private TBSCertificate generateTbsCert()
+ {
+ if (!extGenerator.isEmpty())
+ {
+ tbsGen.setExtensions(extGenerator.generate());
+ }
+
+ return tbsGen.generateTBSCertificate();
+ }
+
+ private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature)
+ throws CertificateParsingException
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(tbsCert);
+ v.add(sigAlgId);
+ v.add(new DERBitString(signature));
+
+ return new X509CertificateObject(Certificate.getInstance(new DERSequence(v)));
+ }
+
+ /**
+ * Return an iterator of the signature names supported by the generator.
+ *
+ * @return an iterator containing recognised names.
+ */
+ public Iterator getSignatureAlgNames()
+ {
+ return X509Util.getAlgNames();
+ }
+}