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 'pkix/src/main/jdk1.3/org/spongycastle')
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java55
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java25
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java22
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java151
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java58
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java138
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java31
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java15
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java54
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java30
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java19
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java34
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java57
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java54
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java36
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java32
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java30
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java23
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java23
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java44
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java470
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java25
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java204
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java207
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java90
27 files changed, 2008 insertions, 0 deletions
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
new file mode 100644
index 00000000..eac007e0
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.CertificateRequestMessage;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+
+public class JcaCertificateRequestMessage
+ extends CertificateRequestMessage
+{
+ private CRMFHelper helper = new CRMFHelper(new DefaultJcaJceHelper());
+
+ public JcaCertificateRequestMessage(CertificateRequestMessage certReqMsg)
+ {
+ this(certReqMsg.toASN1Structure());
+ }
+
+ public JcaCertificateRequestMessage(CertReqMsg certReqMsg)
+ {
+ super(certReqMsg);
+ }
+
+ public JcaCertificateRequestMessage setProvider(String providerName)
+ {
+ this.helper = new CRMFHelper(new NamedJcaJceHelper(providerName));
+
+ return this;
+ }
+
+ public JcaCertificateRequestMessage setProvider(Provider provider)
+ {
+ this.helper = new CRMFHelper(new ProviderJcaJceHelper(provider));
+
+ return this;
+ }
+
+ public PublicKey getPublicKey()
+ throws CRMFException
+ {
+ SubjectPublicKeyInfo subjectPublicKeyInfo = getCertTemplate().getPublicKey();
+
+ if (subjectPublicKeyInfo != null)
+ {
+ return helper.toPublicKey(subjectPublicKeyInfo);
+ }
+
+ return null;
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
new file mode 100644
index 00000000..6b2f8521
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
@@ -0,0 +1,25 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.crmf.CertificateRequestMessageBuilder;
+
+public class JcaCertificateRequestMessageBuilder
+ extends CertificateRequestMessageBuilder
+{
+ public JcaCertificateRequestMessageBuilder(BigInteger certReqId)
+ {
+ super(certReqId);
+ }
+
+ public JcaCertificateRequestMessageBuilder setPublicKey(PublicKey publicKey)
+ {
+ setPublicKey(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+
+ return this;
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
new file mode 100644
index 00000000..9e2963c8
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
@@ -0,0 +1,22 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.PrivateKey;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.crmf.PKIArchiveControlBuilder;
+
+public class JcaPKIArchiveControlBuilder
+ extends PKIArchiveControlBuilder
+{
+ public JcaPKIArchiveControlBuilder(PrivateKey privateKey, X500Name name)
+ {
+ this(privateKey, new GeneralName(name));
+ }
+
+ public JcaPKIArchiveControlBuilder(PrivateKey privateKey, GeneralName generalName)
+ {
+ super(PrivateKeyInfo.getInstance(privateKey.getEncoded()), generalName);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
new file mode 100644
index 00000000..37a1723c
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
@@ -0,0 +1,151 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.cert.CRLException;
+import org.spongycastle.jce.cert.CertStore;
+import java.security.cert.CertificateException;
+import org.spongycastle.jce.cert.CollectionCertStoreParameters;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.Store;
+
+/**
+ * Builder to create a CertStore from certificate and CRL stores.
+ */
+public class JcaCertStoreBuilder
+{
+ private List certs = new ArrayList();
+ private List crls = new ArrayList();
+ private Object provider;
+ private JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter();
+ private JcaX509CRLConverter crlConverter = new JcaX509CRLConverter();
+ private String type = "Collection";
+
+ /**
+ * Add a store full of X509CertificateHolder objects.
+ *
+ * @param certStore a store of X509CertificateHolder objects.
+ */
+ public JcaCertStoreBuilder addCertificates(Store certStore)
+ {
+ certs.addAll(certStore.getMatches(null));
+
+ return this;
+ }
+
+ /**
+ * Add a single certificate.
+ *
+ * @param cert the X509 certificate holder containing the certificate.
+ */
+ public JcaCertStoreBuilder addCertificate(X509CertificateHolder cert)
+ {
+ certs.add(cert);
+
+ return this;
+ }
+
+ /**
+ * Add a store full of X509CRLHolder objects.
+ * @param crlStore a store of X509CRLHolder objects.
+ */
+ public JcaCertStoreBuilder addCRLs(Store crlStore)
+ {
+ crls.addAll(crlStore.getMatches(null));
+
+ return this;
+ }
+
+ /**
+ * Add a single CRL.
+ *
+ * @param crl the X509 CRL holder containing the CRL.
+ */
+ public JcaCertStoreBuilder addCRL(X509CRLHolder crl)
+ {
+ crls.add(crl);
+
+ return this;
+ }
+
+ public JcaCertStoreBuilder setProvider(String providerName)
+ {
+ certificateConverter.setProvider(providerName);
+ crlConverter.setProvider(providerName);
+ this.provider = providerName;
+
+ return this;
+ }
+
+ public JcaCertStoreBuilder setProvider(Provider provider)
+ {
+ certificateConverter.setProvider(provider);
+ crlConverter.setProvider(provider);
+ this.provider = provider;
+
+ return this;
+ }
+
+ /**
+ * Set the type of the CertStore generated. By default it is "Collection".
+ *
+ * @param type type of CertStore passed to CertStore.getInstance().
+ * @return the current builder.
+ */
+ public JcaCertStoreBuilder setType(String type)
+ {
+ this.type = type;
+
+ return this;
+ }
+
+ /**
+ * Build the CertStore from the current inputs.
+ *
+ * @return a CertStore.
+ * @throws GeneralSecurityException
+ */
+ public CertStore build()
+ throws GeneralSecurityException
+ {
+ CollectionCertStoreParameters params = convertHolders(certificateConverter, crlConverter);
+
+ if (provider instanceof String)
+ {
+ return CertStore.getInstance(type, params, (String)provider);
+ }
+
+ if (provider instanceof Provider)
+ {
+ return CertStore.getInstance(type, params, (Provider)provider);
+ }
+
+ return CertStore.getInstance(type, params);
+ }
+
+ private CollectionCertStoreParameters convertHolders(JcaX509CertificateConverter certificateConverter, JcaX509CRLConverter crlConverter)
+ throws CertificateException, CRLException
+ {
+ List jcaObjs = new ArrayList(certs.size() + crls.size());
+
+ for (Iterator it = certs.iterator(); it.hasNext();)
+ {
+ jcaObjs.add(certificateConverter.getCertificate((X509CertificateHolder)it.next()));
+ }
+
+ for (Iterator it = crls.iterator(); it.hasNext();)
+ {
+ jcaObjs.add(crlConverter.getCRL((X509CRLHolder)it.next()));
+ }
+
+ return new CollectionCertStoreParameters(jcaObjs);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java
new file mode 100644
index 00000000..840dde55
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java
@@ -0,0 +1,58 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.X500NameStyle;
+import org.spongycastle.jce.PrincipalUtil;
+
+public class JcaX500NameUtil
+{
+ public static X500Name getIssuer(X509Certificate certificate)
+ {
+try
+{
+ return X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(certificate).getEncoded());
+}
+catch (Exception e)
+{
+ throw new IllegalStateException(e.toString());
+}
+ }
+
+ public static X500Name getSubject(X509Certificate certificate)
+ {
+try
+{
+ return X500Name.getInstance(PrincipalUtil.getSubjectX509Principal(certificate).getEncoded());
+}
+catch (Exception e)
+{
+ throw new IllegalStateException(e.toString());
+}
+ }
+
+ public static X500Name getIssuer(X500NameStyle style, X509Certificate certificate)
+ {
+try
+{
+ return X500Name.getInstance(style, PrincipalUtil.getIssuerX509Principal(certificate).getEncoded());
+}
+catch (Exception e)
+{
+ throw new IllegalStateException(e.toString());
+}
+ }
+
+ public static X500Name getSubject(X500NameStyle style, X509Certificate certificate)
+ {
+try
+{
+ return X500Name.getInstance(style, PrincipalUtil.getSubjectX509Principal(certificate).getEncoded());
+}
+catch (Exception e)
+{
+ throw new IllegalStateException(e.toString());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java
new file mode 100644
index 00000000..f40ab480
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java
@@ -0,0 +1,138 @@
+package org.spongycastle.cert.jcajce;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509ExtensionUtils;
+import org.spongycastle.operator.DigestCalculator;
+
+public class JcaX509ExtensionUtils
+ extends X509ExtensionUtils
+{
+ /**
+ * Create a utility class pre-configured with a SHA-1 digest calculator based on the
+ * default implementation.
+ *
+ * @throws java.security.NoSuchAlgorithmException
+ */
+ public JcaX509ExtensionUtils()
+ throws NoSuchAlgorithmException
+ {
+ super(new SHA1DigestCalculator(MessageDigest.getInstance("SHA1")));
+ }
+
+ public JcaX509ExtensionUtils(DigestCalculator calculator)
+ {
+ super(calculator);
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(
+ X509Certificate cert)
+ throws CertificateEncodingException
+ {
+ return super.createAuthorityKeyIdentifier(new JcaX509CertificateHolder(cert));
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(
+ PublicKey pubKey)
+ {
+ return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()));
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, GeneralNames generalNames, BigInteger serial)
+ {
+ return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), generalNames, serial);
+ }
+
+ /**
+ * Return a RFC 3280 type 1 key identifier. As in:
+ * <pre>
+ * (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ * </pre>
+ * @param publicKey the key object containing the key identifier is to be based on.
+ * @return the key identifier.
+ */
+ public SubjectKeyIdentifier createSubjectKeyIdentifier(
+ PublicKey publicKey)
+ {
+ return super.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+ }
+
+ /**
+ * Return a RFC 3280 type 2 key identifier. As in:
+ * <pre>
+ * (2) The keyIdentifier is composed of a four bit type field with
+ * the value 0100 followed by the least significant 60 bits of the
+ * SHA-1 hash of the value of the BIT STRING subjectPublicKey.
+ * </pre>
+ * @param publicKey the key object of interest.
+ * @return the key identifier.
+ */
+ public SubjectKeyIdentifier createTruncatedSubjectKeyIdentifier(PublicKey publicKey)
+ {
+ return super.createSubjectKeyIdentifier(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+ }
+
+ /**
+ * Return the ASN.1 object contained in a byte[] returned by a getExtensionValue() call.
+ *
+ * @param encExtValue DER encoded OCTET STRING containing the DER encoded extension object.
+ * @return an ASN.1 object
+ * @throws java.io.IOException on a parsing error.
+ */
+ public static ASN1Primitive parseExtensionValue(byte[] encExtValue)
+ throws IOException
+ {
+ return ASN1Primitive.fromByteArray(ASN1OctetString.getInstance(encExtValue).getOctets());
+ }
+
+ private static class SHA1DigestCalculator
+ implements DigestCalculator
+ {
+ private ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ private MessageDigest digest;
+
+ public SHA1DigestCalculator(MessageDigest digest)
+ {
+ this.digest = digest;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return bOut;
+ }
+
+ public byte[] getDigest()
+ {
+ byte[] bytes = digest.digest(bOut.toByteArray());
+
+ bOut.reset();
+
+ return bytes;
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
new file mode 100644
index 00000000..b67959bc
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
@@ -0,0 +1,31 @@
+package org.spongycastle.cert.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Date;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509v1CertificateBuilder;
+
+/**
+ * JCA helper class to allow JCA objects to be used in the construction of a Version 1 certificate.
+ */
+public class JcaX509v1CertificateBuilder
+ extends X509v1CertificateBuilder
+{
+ /**
+ * Initialise the builder using a PublicKey.
+ *
+ * @param issuer X500Name representing the issuer of this certificate.
+ * @param serial the serial number for the certificate.
+ * @param notBefore date before which the certificate is not valid.
+ * @param notAfter date after which the certificate is not valid.
+ * @param subject X500Name representing the subject of this certificate.
+ * @param publicKey the public key to be associated with the certificate.
+ */
+ public JcaX509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey)
+ {
+ super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java
new file mode 100644
index 00000000..4b1f4907
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java
@@ -0,0 +1,15 @@
+package org.spongycastle.cert.jcajce;
+
+import java.util.Date;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.X509v2CRLBuilder;
+
+public class JcaX509v2CRLBuilder
+ extends X509v2CRLBuilder
+{
+ public JcaX509v2CRLBuilder(X500Name issuer, Date now)
+ {
+ super(issuer, now);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
new file mode 100644
index 00000000..4f7a4a1e
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cert.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509v3CertificateBuilder;
+
+/**
+ * JCA helper class to allow JCA objects to be used in the construction of a Version 3 certificate.
+ */
+public class JcaX509v3CertificateBuilder
+ extends X509v3CertificateBuilder
+{
+ /**
+ * Initialise the builder using a PublicKey.
+ *
+ * @param issuer X500Name representing the issuer of this certificate.
+ * @param serial the serial number for the certificate.
+ * @param notBefore date before which the certificate is not valid.
+ * @param notAfter date after which the certificate is not valid.
+ * @param subject X500Name representing the subject of this certificate.
+ * @param publicKey the public key to be associated with the certificate.
+ */
+ public JcaX509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, PublicKey publicKey)
+ {
+ super(issuer, serial, notBefore, notAfter, subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3)
+ * copying the extension value from another certificate.
+ *
+ * @param oid the type of the extension to be copied.
+ * @param critical true if the extension is to be marked critical, false otherwise.
+ * @param certificate the source of the extension to be copied.
+ * @return the builder instance.
+ */
+ public JcaX509v3CertificateBuilder copyAndAddExtension(
+ ASN1ObjectIdentifier oid,
+ boolean critical,
+ X509Certificate certificate)
+ throws CertificateEncodingException
+ {
+ this.copyAndAddExtension(oid, critical, new JcaX509CertificateHolder(certificate));
+
+ return this;
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java
new file mode 100644
index 00000000..a28a7c56
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java
@@ -0,0 +1,30 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.Provider;
+import java.security.NoSuchProviderException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+class ProviderCertHelper
+ extends CertHelper
+{
+ private final Provider provider;
+
+ ProviderCertHelper(Provider provider)
+ {
+ this.provider = provider;
+ }
+
+ protected CertificateFactory createCertificateFactory(String type)
+ throws CertificateException
+ {
+ try
+ {
+ return CertificateFactory.getInstance(type, provider.getName());
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new CertificateException(e.toString());
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java
new file mode 100644
index 00000000..41d9072c
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java
@@ -0,0 +1,19 @@
+package org.spongycastle.cert.ocsp.jcajce;
+
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.ocsp.OCSPException;
+import org.spongycastle.cert.ocsp.RespID;
+import org.spongycastle.operator.DigestCalculator;
+
+public class JcaRespID
+ extends RespID
+{
+ public JcaRespID(PublicKey pubKey, DigestCalculator digCalc)
+ throws OCSPException
+ {
+ super(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), digCalc);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..cede4acc
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,34 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.selector.X509CertificateHolderSelector;
+
+public class JcaSelectorConverter
+{
+ public JcaSelectorConverter()
+ {
+
+ }
+
+ public X509CertificateHolderSelector getCertificateHolderSelector(X509CertSelector certSelector)
+ {
+try
+{
+ if (certSelector.getSubjectKeyIdentifier() != null)
+ {
+ return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets());
+ }
+ else
+ {
+ return new X509CertificateHolderSelector(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber());
+ }
+}
+catch (Exception e)
+{
+throw new IllegalArgumentException("conversion failed: " + e.toString());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..b2dbb563
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.selector.X509CertificateHolderSelector;
+
+public class JcaX509CertSelectorConverter
+{
+ public JcaX509CertSelectorConverter()
+ {
+ }
+
+ protected X509CertSelector doConversion(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyIdentifier)
+ {
+ X509CertSelector selector = new X509CertSelector();
+
+ if (issuer != null)
+ {
+ try
+ {
+ selector.setIssuer(issuer.getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage());
+ }
+ }
+
+ if (serialNumber != null)
+ {
+ selector.setSerialNumber(serialNumber);
+ }
+
+ if (subjectKeyIdentifier != null)
+ {
+ try
+ {
+ selector.setSubjectKeyIdentifier(new DEROctetString(subjectKeyIdentifier).getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to convert issuer: " + e.getMessage());
+ }
+ }
+
+ return selector;
+ }
+
+ public X509CertSelector getCertSelector(X509CertificateHolderSelector holderSelector)
+ {
+ return doConversion(holderSelector.getIssuer(), holderSelector.getSerialNumber(), holderSelector.getSubjectKeyIdentifier());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
new file mode 100644
index 00000000..3280af2a
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.PrincipalUtil;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.X509Extension;
+import org.spongycastle.cert.selector.X509CertificateHolderSelector;
+
+public class JcaX509CertificateHolderSelector
+ extends X509CertificateHolderSelector
+{
+ /**
+ * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in
+ * certificate.
+ *
+ * @param certificate certificate providing the issue and serial number and subject key identifier.
+ */
+ public JcaX509CertificateHolderSelector(X509Certificate certificate)
+ {
+ super(convertPrincipal(certificate), certificate.getSerialNumber(), getSubjectKeyId(certificate));
+ }
+
+ private static X500Name convertPrincipal(X509Certificate issuer)
+ {
+ if (issuer == null)
+ {
+ return null;
+ }
+try
+{
+ return X500Name.getInstance(PrincipalUtil.getIssuerX509Principal(issuer).toASN1Primitive());
+}
+catch (Exception e)
+{
+ throw new IllegalArgumentException("conversion failed: " + e.toString());
+}
+ }
+
+ private static byte[] getSubjectKeyId(X509Certificate cert)
+ {
+ byte[] ext = cert.getExtensionValue(X509Extension.subjectKeyIdentifier.getId());
+
+ if (ext != null)
+ {
+ return ASN1OctetString.getInstance(ASN1OctetString.getInstance(ext).getOctets()).getOctets();
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..c6d0cebe
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cms.jcajce;
+
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.cms.SignerId;
+
+public class JcaSelectorConverter
+{
+ public JcaSelectorConverter()
+ {
+
+ }
+
+ public SignerId getSignerId(X509CertSelector certSelector)
+ {
+try
+{
+ if (certSelector.getSubjectKeyIdentifier() != null)
+ {
+ return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets());
+ }
+ else
+ {
+ return new SignerId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber());
+ }
+}
+catch (Exception e)
+{
+ throw new IllegalArgumentException("conversion failed: " + e.toString());
+}
+ }
+
+ public KeyTransRecipientId getKeyTransRecipientId(X509CertSelector certSelector)
+ {
+try
+{
+ if (certSelector.getSubjectKeyIdentifier() != null)
+ {
+ return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber(), ASN1OctetString.getInstance(certSelector.getSubjectKeyIdentifier()).getOctets());
+ }
+ else
+ {
+ return new KeyTransRecipientId(X500Name.getInstance(certSelector.getIssuerAsBytes()), certSelector.getSerialNumber());
+ }
+}
+catch (Exception e)
+{
+ throw new IllegalArgumentException("conversion failed: " + e.toString());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java
new file mode 100644
index 00000000..99650cfb
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java
@@ -0,0 +1,36 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.SignerId;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+
+public class JcaSignerId
+ extends SignerId
+{
+ private static X509Principal getPrincipal(X509Certificate cert)
+ {
+ try
+ {
+ return PrincipalUtil.getIssuerX509Principal(cert);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("unable to extract principle");
+ }
+ }
+
+ /**
+ * Construct a signer identifier based on the issuer, serial number and subject key identifier (if present) of the passed in
+ * certificate.
+ *
+ * @param certificate certificate providing the issue and serial number and subject key identifier.
+ */
+ public JcaSignerId(X509Certificate certificate)
+ {
+ super(X500Name.getInstance(getPrincipal(certificate).getEncoded()), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate));
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..594ed1d5
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cms.jcajce;
+
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.cms.SignerId;
+
+public class JcaX509CertSelectorConverter
+ extends org.spongycastle.cert.selector.jcajce.JcaX509CertSelectorConverter
+{
+ public JcaX509CertSelectorConverter()
+ {
+ }
+
+ public X509CertSelector getCertSelector(KeyTransRecipientId recipientId)
+ {
+ return doConversion(recipientId.getIssuer(), recipientId.getSerialNumber(), recipientId.getSubjectKeyIdentifier());
+ }
+
+ public X509CertSelector getCertSelector(SignerId signerId)
+ {
+ return doConversion(signerId.getIssuer(), signerId.getSerialNumber(), signerId.getSubjectKeyIdentifier());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java
new file mode 100644
index 00000000..91875037
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java
@@ -0,0 +1,32 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyAgreeRecipientId;
+
+public class JceKeyAgreeRecipientId
+ extends KeyAgreeRecipientId
+{
+ public JceKeyAgreeRecipientId(X509Certificate certificate)
+ {
+ super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber());
+ }
+
+ private static X509Principal extractIssuer(X509Certificate certificate)
+ {
+ try
+ {
+ return PrincipalUtil.getIssuerX509Principal(certificate);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IllegalStateException("can't extract issuer");
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java
new file mode 100644
index 00000000..5bac48b5
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java
@@ -0,0 +1,30 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+
+public class JceKeyTransRecipientId
+ extends KeyTransRecipientId
+{
+ public JceKeyTransRecipientId(X509Certificate certificate)
+ {
+ super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate));
+ }
+
+ private static X509Principal extractIssuer(X509Certificate certificate)
+ {
+ try
+ {
+ return PrincipalUtil.getIssuerX509Principal(certificate);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IllegalStateException("can't extract issuer");
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java
new file mode 100644
index 00000000..4bc4dfa3
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java
@@ -0,0 +1,23 @@
+package org.spongycastle.eac.jcajce;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+
+class ProviderEACHelper
+ implements EACHelper
+{
+ private final Provider provider;
+
+ ProviderEACHelper(Provider provider)
+ {
+ this.provider = provider;
+ }
+
+ public KeyFactory createKeyFactory(String type)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return KeyFactory.getInstance(type, provider.getName());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java
new file mode 100644
index 00000000..dcdd1e1c
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java
@@ -0,0 +1,23 @@
+package org.spongycastle.eac.operator.jcajce;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Signature;
+
+class ProviderEACHelper
+ extends EACHelper
+{
+ private final Provider provider;
+
+ ProviderEACHelper(Provider provider)
+ {
+ this.provider = provider;
+ }
+
+ protected Signature createSignature(String type)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return Signature.getInstance(type, provider.getName());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
new file mode 100644
index 00000000..a4de4911
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
@@ -0,0 +1,44 @@
+package org.spongycastle.operator.jcajce;
+
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSAESOAEPparams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+
+public class JcaAlgorithmParametersConverter
+{
+ public JcaAlgorithmParametersConverter()
+ {
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
+
+ return new AlgorithmIdentifier(algId, params);
+ }
+ catch (IOException e)
+ {
+ throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
+ }
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java
new file mode 100644
index 00000000..419f0939
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java
@@ -0,0 +1,470 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+//import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+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.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.operator.OperatorCreationException;
+
+class OperatorHelper
+{
+ private static final Map oids = new HashMap();
+ private static final Map asymmetricWrapperAlgNames = new HashMap();
+ private static final Map symmetricWrapperAlgNames = new HashMap();
+ private static final Map symmetricKeyAlgNames = new HashMap();
+
+ static
+ {
+ //
+ // reverse mappings
+ //
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA");
+ oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA");
+ oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410");
+ oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410");
+
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA");
+ oids.put(new ASN1ObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA");
+ oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA");
+ oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
+ oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA");
+ oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA");
+ oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA");
+
+ oids.put(OIWObjectIdentifiers.idSHA1, "SHA-1");
+ oids.put(NISTObjectIdentifiers.id_sha224, "SHA-224");
+ oids.put(NISTObjectIdentifiers.id_sha256, "SHA-256");
+ oids.put(NISTObjectIdentifiers.id_sha384, "SHA-384");
+ oids.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-256");
+
+ asymmetricWrapperAlgNames.put(PKCSObjectIdentifiers.rsaEncryption, "RSA/ECB/PKCS1Padding");
+
+ symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, "DESEDEWrap");
+ symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2Wrap");
+ symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes128_wrap, "AESWrap");
+ symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes192_wrap, "AESWrap");
+ symmetricWrapperAlgNames.put(NISTObjectIdentifiers.id_aes256_wrap, "AESWrap");
+ symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia128_wrap, "CamelliaWrap");
+ symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia192_wrap, "CamelliaWrap");
+ symmetricWrapperAlgNames.put(NTTObjectIdentifiers.id_camellia256_wrap, "CamelliaWrap");
+ symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap");
+ symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
+
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES");
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES");
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES");
+ symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES");
+ symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
+ symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2");
+ }
+
+ private JcaJceHelper helper;
+
+ OperatorHelper(JcaJceHelper helper)
+ {
+ this.helper = helper;
+ }
+
+ Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames)
+ throws OperatorCreationException
+ {
+ try
+ {
+ String cipherName = null;
+
+ if (!extraAlgNames.isEmpty())
+ {
+ cipherName = (String)extraAlgNames.get(algorithm);
+ }
+
+ if (cipherName == null)
+ {
+ cipherName = (String)asymmetricWrapperAlgNames.get(algorithm);
+ }
+
+ if (cipherName != null)
+ {
+ try
+ {
+ // this is reversed as the Sun policy files now allow unlimited strength RSA
+ return helper.createCipher(cipherName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // try alternate for RSA
+ if (cipherName.equals("RSA/ECB/PKCS1Padding"))
+ {
+ try
+ {
+ return helper.createCipher("RSA/NONE/PKCS1Padding");
+ }
+ catch (NoSuchAlgorithmException ex)
+ {
+ // Ignore
+ }
+ }
+ // Ignore
+ }
+ }
+
+ return helper.createCipher(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
+ }
+ }
+
+ Cipher createSymmetricWrapper(ASN1ObjectIdentifier algorithm)
+ throws OperatorCreationException
+ {
+ try
+ {
+ String cipherName = (String)symmetricWrapperAlgNames.get(algorithm);
+
+ if (cipherName != null)
+ {
+ try
+ {
+ // this is reversed as the Sun policy files now allow unlimited strength RSA
+ return helper.createCipher(cipherName);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // Ignore
+ }
+ }
+ return helper.createCipher(algorithm.getId());
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
+ }
+ }
+
+ AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmParameters parameters;
+
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
+ {
+ return null;
+ }
+
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
+
+ try
+ {
+ parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
+ }
+
+ return parameters;
+ }
+
+ MessageDigest createDigest(AlgorithmIdentifier digAlgId)
+ throws GeneralSecurityException
+ {
+ MessageDigest dig;
+
+ try
+ {
+ dig = helper.createDigest(getDigestAlgName(digAlgId.getAlgorithm()));
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //
+ // try an alternate
+ //
+ if (oids.get(digAlgId.getAlgorithm()) != null)
+ {
+ String digestAlgorithm = (String)oids.get(digAlgId.getAlgorithm());
+
+ dig = helper.createDigest(digestAlgorithm);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+
+ return dig;
+ }
+
+ Signature createSignature(AlgorithmIdentifier sigAlgId)
+ throws GeneralSecurityException
+ {
+ Signature sig;
+
+ try
+ {
+ sig = helper.createSignature(getSignatureName(sigAlgId));
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //
+ // try an alternate
+ //
+ if (oids.get(sigAlgId.getAlgorithm()) != null)
+ {
+ String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
+
+ sig = helper.createSignature(signatureAlgorithm);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+
+ return sig;
+ }
+
+ public Signature createRawSignature(AlgorithmIdentifier algorithm)
+ {
+ Signature sig;
+
+ try
+ {
+ String algName = getSignatureName(algorithm);
+
+ algName = "NONE" + algName.substring(algName.indexOf("WITH"));
+
+ sig = helper.createSignature(algName);
+
+ // RFC 4056
+ // When the id-RSASSA-PSS algorithm identifier is used for a signature,
+ // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
+/*
+ if (algorithm.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ AlgorithmParameters params = helper.createAlgorithmParameters(algName);
+
+ JcaJceUtils.loadParameters(params, algorithm.getParameters());
+
+ PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
+ sig.setParameter(spec);
+ }
+*/
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+
+ return sig;
+ }
+
+ private static String getSignatureName(
+ AlgorithmIdentifier sigAlgId)
+ {
+ ASN1Encodable params = sigAlgId.getParameters();
+
+ if (params != null && !DERNull.INSTANCE.equals(params))
+ {
+ if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ {
+ RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
+ return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
+ }
+ }
+
+ if (oids.containsKey(sigAlgId.getAlgorithm()))
+ {
+ return (String)oids.get(sigAlgId.getAlgorithm());
+ }
+
+ return sigAlgId.getAlgorithm().getId();
+ }
+
+ private static String getDigestAlgName(
+ ASN1ObjectIdentifier digestAlgOID)
+ {
+ if (PKCSObjectIdentifiers.md5.equals(digestAlgOID))
+ {
+ return "MD5";
+ }
+ else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID))
+ {
+ return "SHA1";
+ }
+ else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID))
+ {
+ return "SHA224";
+ }
+ else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
+ {
+ return "SHA256";
+ }
+ else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID))
+ {
+ return "SHA384";
+ }
+ else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID))
+ {
+ return "SHA512";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID))
+ {
+ return "RIPEMD128";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID))
+ {
+ return "RIPEMD160";
+ }
+ else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID))
+ {
+ return "RIPEMD256";
+ }
+ else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID))
+ {
+ return "GOST3411";
+ }
+ else
+ {
+ return digestAlgOID.getId();
+ }
+ }
+
+ public X509Certificate convertCertificate(X509CertificateHolder certHolder)
+ throws CertificateException
+ {
+
+ try
+ {
+ CertificateFactory certFact = helper.createCertificateFactory("X.509");
+
+ return (X509Certificate)certFact.generateCertificate(new ByteArrayInputStream(certHolder.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OpCertificateException("cannot get encoded form of certificate: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OpCertificateException("cannot create certificate factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OpCertificateException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ }
+
+ public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
+
+ return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ }
+
+ // TODO: put somewhere public so cause easily accessed
+ private static class OpCertificateException
+ extends CertificateException
+ {
+ private Throwable cause;
+
+ public OpCertificateException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
+
+ String getKeyAlgorithmName(ASN1ObjectIdentifier oid)
+ {
+
+ String name = (String)symmetricKeyAlgNames.get(oid);
+
+ if (name != null)
+ {
+ return name;
+ }
+
+ return oid.getId();
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
new file mode 100644
index 00000000..2e0000e0
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
@@ -0,0 +1,25 @@
+package org.spongycastle.pkcs.jcajce;
+
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.pkcs.PKCS10CertificationRequestBuilder;
+
+/**
+ * Extension of the PKCS#10 builder to support PublicKey and X500Principal objects.
+ */
+public class JcaPKCS10CertificationRequestBuilder
+ extends PKCS10CertificationRequestBuilder
+{
+ /**
+ * Create a PKCS#10 builder for the passed in subject and JCA public key.
+ *
+ * @param subject an X500Name containing the subject associated with the request we are building.
+ * @param publicKey a JCA public key that is to be associated with the request we are building.
+ */
+ public JcaPKCS10CertificationRequestBuilder(X500Name subject, PublicKey publicKey)
+ {
+ super(subject, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java
new file mode 100644
index 00000000..0b5cb6fd
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java
@@ -0,0 +1,204 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.Evidence;
+import org.spongycastle.asn1.cms.TimeStampAndCRL;
+import org.spongycastle.asn1.cms.TimeStampTokenEvidence;
+import org.spongycastle.asn1.cms.TimeStampedData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.tsp.TimeStampToken;
+
+public class CMSTimeStampedData
+{
+ private TimeStampedData timeStampedData;
+ private ContentInfo contentInfo;
+ private TimeStampDataUtil util;
+
+ public CMSTimeStampedData(ContentInfo contentInfo)
+ {
+ this.initialize(contentInfo);
+ }
+
+ public CMSTimeStampedData(InputStream in)
+ throws IOException
+ {
+ try
+ {
+ initialize(ContentInfo.getInstance(new ASN1InputStream(in).readObject()));
+ }
+ catch (ClassCastException e)
+ {
+ throw new IOException("Malformed content: " + e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IOException("Malformed content: " + e);
+ }
+ }
+
+ public CMSTimeStampedData(byte[] baseData)
+ throws IOException
+ {
+ this(new ByteArrayInputStream(baseData));
+ }
+
+ private void initialize(ContentInfo contentInfo)
+ {
+ this.contentInfo = contentInfo;
+
+ if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType()))
+ {
+ this.timeStampedData = TimeStampedData.getInstance(contentInfo.getContent());
+ }
+ else
+ {
+ throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId());
+ }
+
+ util = new TimeStampDataUtil(this.timeStampedData);
+ }
+
+ public byte[] calculateNextHash(DigestCalculator calculator)
+ throws CMSException
+ {
+ return util.calculateNextHash(calculator);
+ }
+
+ /**
+ * Return a new timeStampedData object with the additional token attached.
+ *
+ * @throws CMSException
+ */
+ public CMSTimeStampedData addTimeStamp(TimeStampToken token)
+ throws CMSException
+ {
+ TimeStampAndCRL[] timeStamps = util.getTimeStamps();
+ TimeStampAndCRL[] newTimeStamps = new TimeStampAndCRL[timeStamps.length + 1];
+
+ System.arraycopy(timeStamps, 0, newTimeStamps, 0, timeStamps.length);
+
+ newTimeStamps[timeStamps.length] = new TimeStampAndCRL(token.toCMSSignedData().toASN1Structure());
+
+ return new CMSTimeStampedData(new ContentInfo(CMSObjectIdentifiers.timestampedData, new TimeStampedData(timeStampedData.getDataUri(), timeStampedData.getMetaData(), timeStampedData.getContent(), new Evidence(new TimeStampTokenEvidence(newTimeStamps)))));
+ }
+
+ public byte[] getContent()
+ {
+ if (timeStampedData.getContent() != null)
+ {
+ return timeStampedData.getContent().getOctets();
+ }
+
+ return null;
+ }
+
+ public URL getDataUri()
+ throws MalformedURLException
+ {
+ DERIA5String dataURI = this.timeStampedData.getDataUri();
+
+ if (dataURI != null)
+ {
+ return new URL(dataURI.getString());
+ }
+
+ return null;
+ }
+
+ public String getFileName()
+ {
+ return util.getFileName();
+ }
+
+ public String getMediaType()
+ {
+ return util.getMediaType();
+ }
+
+ public AttributeTable getOtherMetaData()
+ {
+ return util.getOtherMetaData();
+ }
+
+ public TimeStampToken[] getTimeStampTokens()
+ throws CMSException
+ {
+ return util.getTimeStampTokens();
+ }
+
+ /**
+ * Initialise the passed in calculator with the MetaData for this message, if it is
+ * required as part of the initial message imprint calculation.
+ *
+ * @param calculator the digest calculator to be initialised.
+ * @throws CMSException if the MetaData is required and cannot be processed
+ */
+ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator)
+ throws CMSException
+ {
+ util.initialiseMessageImprintDigestCalculator(calculator);
+ }
+
+ /**
+ * Returns an appropriately initialised digest calculator based on the message imprint algorithm
+ * described in the first time stamp in the TemporalData for this message. If the metadata is required
+ * to be included in the digest calculation, the returned calculator will be pre-initialised.
+ *
+ * @param calculatorProvider a provider of DigestCalculator objects.
+ * @return an initialised digest calculator.
+ * @throws OperatorCreationException if the provider is unable to create the calculator.
+ */
+ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider)
+ throws OperatorCreationException
+ {
+ return util.getMessageImprintDigestCalculator(calculatorProvider);
+ }
+
+ /**
+ * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData.
+ *
+ * @param calculatorProvider provider for digest calculators
+ * @param dataDigest the calculated data digest for the message
+ * @throws ImprintDigestInvalidException if an imprint digest fails to compare
+ * @throws CMSException if an exception occurs processing the message.
+ */
+ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest)
+ throws ImprintDigestInvalidException, CMSException
+ {
+ util.validate(calculatorProvider, dataDigest);
+ }
+
+ /**
+ * Validate the passed in timestamp token against the tokens and data present in the message.
+ *
+ * @param calculatorProvider provider for digest calculators
+ * @param dataDigest the calculated data digest for the message.
+ * @param timeStampToken the timestamp token of interest.
+ * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare.
+ * @throws CMSException if an exception occurs processing the message.
+ */
+ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken)
+ throws ImprintDigestInvalidException, CMSException
+ {
+ util.validate(calculatorProvider, dataDigest, timeStampToken);
+ }
+
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return contentInfo.getEncoded();
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
new file mode 100644
index 00000000..2b1a695f
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
@@ -0,0 +1,207 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.asn1.cms.TimeStampedDataParser;
+import org.spongycastle.cms.CMSContentInfoParser;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.util.io.Streams;
+
+public class CMSTimeStampedDataParser
+ extends CMSContentInfoParser
+{
+ private TimeStampedDataParser timeStampedData;
+ private TimeStampDataUtil util;
+
+ public CMSTimeStampedDataParser(InputStream in)
+ throws CMSException
+ {
+ super(in);
+
+ initialize(_contentInfo);
+ }
+
+ public CMSTimeStampedDataParser(byte[] baseData)
+ throws CMSException
+ {
+ this(new ByteArrayInputStream(baseData));
+ }
+
+ private void initialize(ContentInfoParser contentInfo)
+ throws CMSException
+ {
+ try
+ {
+ if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType()))
+ {
+ this.timeStampedData = TimeStampedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE));
+ }
+ else
+ {
+ throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("parsing exception: " + e.getMessage(), e);
+ }
+ }
+
+ public byte[] calculateNextHash(DigestCalculator calculator)
+ throws CMSException
+ {
+ return util.calculateNextHash(calculator);
+ }
+
+ public InputStream getContent()
+ {
+ if (timeStampedData.getContent() != null)
+ {
+ return timeStampedData.getContent().getOctetStream();
+ }
+
+ return null;
+ }
+
+ public URL getDataUri()
+ throws MalformedURLException
+ {
+ DERIA5String dataURI = this.timeStampedData.getDataUri();
+
+ if (dataURI != null)
+ {
+ return new URL(dataURI.getString());
+ }
+
+ return null;
+ }
+
+ /**
+ * Initialise the passed in calculator with the MetaData for this message, if it is
+ * required as part of the initial message imprint calculation.
+ *
+ * @param calculator the digest calculator to be initialised.
+ * @throws CMSException if the MetaData is required and cannot be processed
+ */
+ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator)
+ throws CMSException
+ {
+ util.initialiseMessageImprintDigestCalculator(calculator);
+ }
+
+ /**
+ * Returns an appropriately initialised digest calculator based on the message imprint algorithm
+ * described in the first time stamp in the TemporalData for this message. If the metadata is required
+ * to be included in the digest calculation, the returned calculator will be pre-initialised.
+ *
+ * @param calculatorProvider a provider of DigestCalculator objects.
+ * @return an initialised digest calculator.
+ * @throws OperatorCreationException if the provider is unable to create the calculator.
+ */
+ public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider)
+ throws OperatorCreationException
+ {
+ try
+ {
+ parseTimeStamps();
+ }
+ catch (CMSException e)
+ {
+ throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e);
+ }
+
+ return util.getMessageImprintDigestCalculator(calculatorProvider);
+ }
+
+ public String getFileName()
+ {
+ return util.getFileName();
+ }
+
+ public String getMediaType()
+ {
+ return util.getMediaType();
+ }
+
+ public AttributeTable getOtherMetaData()
+ {
+ return util.getOtherMetaData();
+ }
+
+ public TimeStampToken[] getTimeStampTokens()
+ throws CMSException
+ {
+ parseTimeStamps();
+
+ return util.getTimeStampTokens();
+ }
+
+ /**
+ * Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData.
+ *
+ * @param calculatorProvider provider for digest calculators
+ * @param dataDigest the calculated data digest for the message
+ * @throws ImprintDigestInvalidException if an imprint digest fails to compare
+ * @throws CMSException if an exception occurs processing the message.
+ */
+ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest)
+ throws ImprintDigestInvalidException, CMSException
+ {
+ parseTimeStamps();
+
+ util.validate(calculatorProvider, dataDigest);
+ }
+
+ /**
+ * Validate the passed in timestamp token against the tokens and data present in the message.
+ *
+ * @param calculatorProvider provider for digest calculators
+ * @param dataDigest the calculated data digest for the message.
+ * @param timeStampToken the timestamp token of interest.
+ * @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare.
+ * @throws CMSException if an exception occurs processing the message.
+ */
+ public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken)
+ throws ImprintDigestInvalidException, CMSException
+ {
+ parseTimeStamps();
+
+ util.validate(calculatorProvider, dataDigest, timeStampToken);
+ }
+
+ private void parseTimeStamps()
+ throws CMSException
+ {
+ try
+ {
+ if (util == null)
+ {
+ InputStream cont = this.getContent();
+
+ if (cont != null)
+ {
+ Streams.drain(cont);
+ }
+
+ util = new TimeStampDataUtil(timeStampedData);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("unable to parse evidence block: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
new file mode 100644
index 00000000..614a744b
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
@@ -0,0 +1,90 @@
+package org.spongycastle.tsp.cms;
+
+import java.net.URL;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.DERBoolean;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.cms.Attributes;
+import org.spongycastle.asn1.cms.MetaData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.util.Integers;
+
+public class CMSTimeStampedGenerator
+{
+ protected MetaData metaData;
+ protected URL dataUri;
+
+ /**
+ * Set the dataURL to be included in message.
+ *
+ * @param dataUri URL for the data the initial message imprint digest is based on.
+ */
+ public void setDataUri(URL dataUri)
+ {
+ this.dataUri = dataUri;
+ }
+
+ /**
+ * Set the MetaData for the generated message.
+ *
+ * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise.
+ * @param fileName optional file name, may be null.
+ * @param mediaType optional media type, may be null.
+ */
+ public void setMetaData(boolean hashProtected, String fileName, String mediaType)
+ {
+ setMetaData(hashProtected, fileName, mediaType, null);
+ }
+
+ /**
+ * Set the MetaData for the generated message.
+ *
+ * @param hashProtected true if the MetaData should be included in first imprint calculation, false otherwise.
+ * @param fileName optional file name, may be null.
+ * @param mediaType optional media type, may be null.
+ * @param attributes optional attributes, may be null.
+ */
+ public void setMetaData(boolean hashProtected, String fileName, String mediaType, Attributes attributes)
+ {
+ DERUTF8String asn1FileName = null;
+
+ if (fileName != null)
+ {
+ asn1FileName = new DERUTF8String(fileName);
+ }
+
+ DERIA5String asn1MediaType = null;
+
+ if (mediaType != null)
+ {
+ asn1MediaType = new DERIA5String(mediaType);
+ }
+
+ setMetaData(hashProtected, asn1FileName, asn1MediaType, attributes);
+ }
+
+ private void setMetaData(boolean hashProtected, DERUTF8String fileName, DERIA5String mediaType, Attributes attributes)
+ {
+ this.metaData = new MetaData(ASN1Boolean.getInstance(hashProtected), fileName, mediaType, attributes);
+ }
+
+ /**
+ * Initialise the passed in calculator with the MetaData for this message, if it is
+ * required as part of the initial message imprint calculation. After initialisation the
+ * calculator can then be used to calculate the initial message imprint digest for the first
+ * timestamp.
+ *
+ * @param calculator the digest calculator to be initialised.
+ * @throws CMSException if the MetaData is required and cannot be processed
+ */
+ public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator)
+ throws CMSException
+ {
+ MetaDataUtil util = new MetaDataUtil(metaData);
+
+ util.initialiseMessageImprintDigestCalculator(calculator);
+ }
+}