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:
authorDavid Hook <dgh@cryptoworkshop.com>2013-06-01 03:08:23 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2013-06-01 03:08:23 +0400
commit9d86fa64cab222f265c18994eab1d7a5db786da7 (patch)
treed133f3cb8f4f335e38c4ca5d56a32a84dc470c86 /pkix/src/main/jdk1.1/org/bouncycastle/tsp
parent1f388cb05faef261ab0fc6d3b898d3a32c00e94a (diff)
other jdk import
Diffstat (limited to 'pkix/src/main/jdk1.1/org/bouncycastle/tsp')
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampToken.java496
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampTokenGenerator.java472
2 files changed, 968 insertions, 0 deletions
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampToken.java b/pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampToken.java
new file mode 100644
index 00000000..bc4a631a
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampToken.java
@@ -0,0 +1,496 @@
+package org.bouncycastle.tsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.cert.CertStore;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Date;
+
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.cms.Attribute;
+import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
+import org.bouncycastle.asn1.ess.ESSCertID;
+import org.bouncycastle.asn1.ess.ESSCertIDv2;
+import org.bouncycastle.asn1.ess.SigningCertificate;
+import org.bouncycastle.asn1.ess.SigningCertificateV2;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.tsp.TSTInfo;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.IssuerSerial;
+import org.bouncycastle.asn1.x509.X509Name;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSProcessable;
+import org.bouncycastle.cms.CMSSignedData;
+import org.bouncycastle.cms.SignerId;
+import org.bouncycastle.cms.SignerInformation;
+import org.bouncycastle.cms.SignerInformationVerifier;
+import org.bouncycastle.jce.PrincipalUtil;
+import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.operator.DigestCalculator;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Store;
+
+public class TimeStampToken
+{
+ CMSSignedData tsToken;
+
+ SignerInformation tsaSignerInfo;
+
+ Date genTime;
+
+ TimeStampTokenInfo tstInfo;
+
+ CertID certID;
+
+ public TimeStampToken(ContentInfo contentInfo)
+ throws TSPException, IOException
+ {
+ this(getSignedData(contentInfo));
+ }
+
+ private static CMSSignedData getSignedData(ContentInfo contentInfo)
+ throws TSPException
+ {
+ try
+ {
+ return new CMSSignedData(contentInfo);
+ }
+ catch (CMSException e)
+ {
+ throw new TSPException("TSP parsing error: " + e.getMessage(), e.getCause());
+ }
+ }
+
+ public TimeStampToken(CMSSignedData signedData)
+ throws TSPException, IOException
+ {
+ this.tsToken = signedData;
+
+ if (!this.tsToken.getSignedContentTypeOID().equals(PKCSObjectIdentifiers.id_ct_TSTInfo.getId()))
+ {
+ throw new TSPValidationException("ContentInfo object not for a time stamp.");
+ }
+
+ Collection signers = tsToken.getSignerInfos().getSigners();
+
+ if (signers.size() != 1)
+ {
+ throw new IllegalArgumentException("Time-stamp token signed by "
+ + signers.size()
+ + " signers, but it must contain just the TSA signature.");
+ }
+
+ tsaSignerInfo = (SignerInformation)signers.iterator().next();
+
+ try
+ {
+ CMSProcessable content = tsToken.getSignedContent();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ content.write(bOut);
+
+ ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bOut.toByteArray()));
+
+ this.tstInfo = new TimeStampTokenInfo(TSTInfo.getInstance(aIn.readObject()));
+
+ Attribute attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificate);
+
+ if (attr != null)
+ {
+ SigningCertificate signCert = SigningCertificate.getInstance(attr.getAttrValues().getObjectAt(0));
+
+ this.certID = new CertID(ESSCertID.getInstance(signCert.getCerts()[0]));
+ }
+ else
+ {
+ attr = tsaSignerInfo.getSignedAttributes().get(PKCSObjectIdentifiers.id_aa_signingCertificateV2);
+
+ if (attr == null)
+ {
+ throw new TSPValidationException("no signing certificate attribute found, time stamp invalid.");
+ }
+
+ SigningCertificateV2 signCertV2 = SigningCertificateV2.getInstance(attr.getAttrValues().getObjectAt(0));
+
+ this.certID = new CertID(ESSCertIDv2.getInstance(signCertV2.getCerts()[0]));
+ }
+ }
+ catch (CMSException e)
+ {
+ throw new TSPException(e.getMessage(), e.getUnderlyingException());
+ }
+ }
+
+ public TimeStampTokenInfo getTimeStampInfo()
+ {
+ return tstInfo;
+ }
+
+ public SignerId getSID()
+ {
+ return tsaSignerInfo.getSID();
+ }
+
+ public AttributeTable getSignedAttributes()
+ {
+ return tsaSignerInfo.getSignedAttributes();
+ }
+
+ public AttributeTable getUnsignedAttributes()
+ {
+ return tsaSignerInfo.getUnsignedAttributes();
+ }
+
+ /**
+ * @deprecated use getCertificates() or getCRLs()
+ */
+ public CertStore getCertificatesAndCRLs(
+ String type,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException, CMSException
+ {
+ return tsToken.getCertificatesAndCRLs(type, provider);
+ }
+
+ public Store getCertificates()
+ {
+ return tsToken.getCertificates();
+ }
+
+ public Store getCRLs()
+ {
+ return tsToken.getCRLs();
+ }
+
+ public Store getAttributeCertificates()
+ {
+ return tsToken.getAttributeCertificates();
+ }
+
+ /**
+ * Validate the time stamp token.
+ * <p>
+ * To be valid the token must be signed by the passed in certificate and
+ * the certificate must be the one referred to by the SigningCertificate
+ * attribute included in the hashed attributes of the token. The
+ * certificate must also have the ExtendedKeyUsageExtension with only
+ * KeyPurposeId.id_kp_timeStamping and have been valid at the time the
+ * timestamp was created.
+ * </p>
+ * <p>
+ * A successful call to validate means all the above are true.
+ * </p>
+ * @deprecated
+ */
+ public void validate(
+ X509Certificate cert,
+ String provider)
+ throws TSPException, TSPValidationException,
+ CertificateExpiredException, CertificateNotYetValidException, NoSuchProviderException
+ {
+ try
+ {
+ if (!Arrays.constantTimeAreEqual(certID.getCertHash(), MessageDigest.getInstance(certID.getHashAlgorithmName()).digest(cert.getEncoded())))
+ {
+ throw new TSPValidationException("certificate hash does not match certID hash.");
+ }
+
+ if (certID.getIssuerSerial() != null)
+ {
+ if (!certID.getIssuerSerial().getSerial().getValue().equals(cert.getSerialNumber()))
+ {
+ throw new TSPValidationException("certificate serial number does not match certID for signature.");
+ }
+
+ GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames();
+ X509Principal principal = PrincipalUtil.getIssuerX509Principal(cert);
+ boolean found = false;
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == 4 && new X509Principal(X509Name.getInstance(names[i].getName())).equals(principal))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ throw new TSPValidationException("certificate name does not match certID for signature. ");
+ }
+ }
+
+ TSPUtil.validateCertificate(cert);
+
+ cert.checkValidity(tstInfo.getGenTime());
+
+ if (!tsaSignerInfo.verify(cert, provider))
+ {
+ throw new TSPValidationException("signature not created by certificate.");
+ }
+ }
+ catch (CMSException e)
+ {
+ if (e.getUnderlyingException() != null)
+ {
+ throw new TSPException(e.getMessage(), e.getUnderlyingException());
+ }
+ else
+ {
+ throw new TSPException("CMS exception: " + e, e);
+ }
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new TSPException("cannot find algorithm: " + e, e);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new TSPException("problem processing certificate: " + e, e);
+ }
+ }
+
+ /**
+ * Validate the time stamp token.
+ * <p>
+ * To be valid the token must be signed by the passed in certificate and
+ * the certificate must be the one referred to by the SigningCertificate
+ * attribute included in the hashed attributes of the token. The
+ * certificate must also have the ExtendedKeyUsageExtension with only
+ * KeyPurposeId.id_kp_timeStamping and have been valid at the time the
+ * timestamp was created.
+ * </p>
+ * <p>
+ * A successful call to validate means all the above are true.
+ * </p>
+ *
+ * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp.
+ * @throws TSPException if an exception occurs in processing the token.
+ * @throws TSPValidationException if the certificate or signature fail to be valid.
+ * @throws IllegalArgumentException if the sigVerifierProvider has no associated certificate.
+ */
+ public void validate(
+ SignerInformationVerifier sigVerifier)
+ throws TSPException, TSPValidationException
+ {
+ if (!sigVerifier.hasAssociatedCertificate())
+ {
+ throw new IllegalArgumentException("verifier provider needs an associated certificate");
+ }
+
+ try
+ {
+ X509CertificateHolder certHolder = sigVerifier.getAssociatedCertificate();
+ DigestCalculator calc = sigVerifier.getDigestCalculator(certID.getHashAlgorithm());
+
+ OutputStream cOut = calc.getOutputStream();
+
+ cOut.write(certHolder.getEncoded());
+ cOut.close();
+
+ if (!Arrays.constantTimeAreEqual(certID.getCertHash(), calc.getDigest()))
+ {
+ throw new TSPValidationException("certificate hash does not match certID hash.");
+ }
+
+ if (certID.getIssuerSerial() != null)
+ {
+ IssuerAndSerialNumber issuerSerial = new IssuerAndSerialNumber(certHolder.toASN1Structure());
+
+ if (!certID.getIssuerSerial().getSerial().equals(issuerSerial.getSerialNumber()))
+ {
+ throw new TSPValidationException("certificate serial number does not match certID for signature.");
+ }
+
+ GeneralName[] names = certID.getIssuerSerial().getIssuer().getNames();
+ boolean found = false;
+
+ for (int i = 0; i != names.length; i++)
+ {
+ if (names[i].getTagNo() == 4 && X500Name.getInstance(names[i].getName()).equals(X500Name.getInstance(issuerSerial.getName())))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ throw new TSPValidationException("certificate name does not match certID for signature. ");
+ }
+ }
+
+ TSPUtil.validateCertificate(certHolder);
+
+ if (!certHolder.isValidOn(tstInfo.getGenTime()))
+ {
+ throw new TSPValidationException("certificate not valid when time stamp created.");
+ }
+
+ if (!tsaSignerInfo.verify(sigVerifier))
+ {
+ throw new TSPValidationException("signature not created by certificate.");
+ }
+ }
+ catch (CMSException e)
+ {
+ if (e.getUnderlyingException() != null)
+ {
+ throw new TSPException(e.getMessage(), e.getUnderlyingException());
+ }
+ else
+ {
+ throw new TSPException("CMS exception: " + e, e);
+ }
+ }
+ catch (IOException e)
+ {
+ throw new TSPException("problem processing certificate: " + e, e);
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new TSPException("unable to create digest: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Return true if the signature on time stamp token is valid.
+ * <p>
+ * Note: this is a much weaker proof of correctness than calling validate().
+ * </p>
+ *
+ * @param sigVerifier the content verifier create the objects required to verify the CMS object in the timestamp.
+ * @return true if the signature matches, false otherwise.
+ * @throws TSPException if the signature cannot be processed or the provider cannot match the algorithm.
+ */
+ public boolean isSignatureValid(
+ SignerInformationVerifier sigVerifier)
+ throws TSPException
+ {
+ try
+ {
+ return tsaSignerInfo.verify(sigVerifier);
+ }
+ catch (CMSException e)
+ {
+ if (e.getUnderlyingException() != null)
+ {
+ throw new TSPException(e.getMessage(), e.getUnderlyingException());
+ }
+ else
+ {
+ throw new TSPException("CMS exception: " + e, e);
+ }
+ }
+ }
+
+ /**
+ * Return the underlying CMSSignedData object.
+ *
+ * @return the underlying CMS structure.
+ */
+ public CMSSignedData toCMSSignedData()
+ {
+ return tsToken;
+ }
+
+ /**
+ * Return a ASN.1 encoded byte stream representing the encoded object.
+ *
+ * @throws IOException if encoding fails.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return tsToken.getEncoded();
+ }
+
+ // perhaps this should be done using an interface on the ASN.1 classes...
+ private class CertID
+ {
+ private ESSCertID certID;
+ private ESSCertIDv2 certIDv2;
+
+ CertID(ESSCertID certID)
+ {
+ this.certID = certID;
+ this.certIDv2 = null;
+ }
+
+ CertID(ESSCertIDv2 certID)
+ {
+ this.certIDv2 = certID;
+ this.certID = null;
+ }
+
+ public String getHashAlgorithmName()
+ {
+ if (certID != null)
+ {
+ return "SHA-1";
+ }
+ else
+ {
+ if (NISTObjectIdentifiers.id_sha256.equals(certIDv2.getHashAlgorithm().getAlgorithm()))
+ {
+ return "SHA-256";
+ }
+ return certIDv2.getHashAlgorithm().getAlgorithm().getId();
+ }
+ }
+
+ public AlgorithmIdentifier getHashAlgorithm()
+ {
+ if (certID != null)
+ {
+ return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1);
+ }
+ else
+ {
+ return certIDv2.getHashAlgorithm();
+ }
+ }
+
+ public byte[] getCertHash()
+ {
+ if (certID != null)
+ {
+ return certID.getCertHash();
+ }
+ else
+ {
+ return certIDv2.getCertHash();
+ }
+ }
+
+ public IssuerSerial getIssuerSerial()
+ {
+ if (certID != null)
+ {
+ return certID.getIssuerSerial();
+ }
+ else
+ {
+ return certIDv2.getIssuerSerial();
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampTokenGenerator.java b/pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampTokenGenerator.java
new file mode 100644
index 00000000..f3093159
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/bouncycastle/tsp/TimeStampTokenGenerator.java
@@ -0,0 +1,472 @@
+package org.bouncycastle.tsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.cert.CRLException;
+import java.security.cert.CertStore;
+import java.security.cert.CertStoreException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.bouncycastle.asn1.ASN1Boolean;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1GeneralizedTime;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.DERSet;
+import org.bouncycastle.asn1.cms.Attribute;
+import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.asn1.ess.ESSCertID;
+import org.bouncycastle.asn1.ess.SigningCertificate;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.tsp.Accuracy;
+import org.bouncycastle.asn1.tsp.MessageImprint;
+import org.bouncycastle.asn1.tsp.TSTInfo;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.cert.jcajce.JcaX509CRLHolder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.bouncycastle.cms.CMSAttributeTableGenerationException;
+import org.bouncycastle.cms.CMSAttributeTableGenerator;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSProcessableByteArray;
+import org.bouncycastle.cms.CMSSignedData;
+import org.bouncycastle.cms.CMSSignedDataGenerator;
+import org.bouncycastle.cms.CMSSignedGenerator;
+import org.bouncycastle.cms.DefaultSignedAttributeTableGenerator;
+import org.bouncycastle.cms.SignerInfoGenerator;
+import org.bouncycastle.cms.SimpleAttributeTableGenerator;
+import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
+import org.bouncycastle.jce.interfaces.GOST3410PrivateKey;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.bouncycastle.util.CollectionStore;
+import org.bouncycastle.util.Store;
+
+public class TimeStampTokenGenerator
+{
+ int accuracySeconds = -1;
+
+ int accuracyMillis = -1;
+
+ int accuracyMicros = -1;
+
+ boolean ordering = false;
+
+ GeneralName tsa = null;
+
+ private ASN1ObjectIdentifier tsaPolicyOID;
+
+ PrivateKey key;
+ X509Certificate cert;
+ String digestOID;
+ AttributeTable signedAttr;
+ AttributeTable unsignedAttr;
+
+ private List certs = new ArrayList();
+ private List crls = new ArrayList();
+ private List attrCerts = new ArrayList();
+ private SignerInfoGenerator signerInfoGen;
+
+ /**
+ *
+ */
+ public TimeStampTokenGenerator(
+ final SignerInfoGenerator signerInfoGen,
+ ASN1ObjectIdentifier tsaPolicy)
+ throws IllegalArgumentException, TSPException
+ {
+ this.signerInfoGen = signerInfoGen;
+ this.tsaPolicyOID = tsaPolicy;
+
+ if (!signerInfoGen.hasAssociatedCertificate())
+ {
+ throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate");
+ }
+
+ TSPUtil.validateCertificate(signerInfoGen.getAssociatedCertificate());
+
+ try
+ {
+ final ESSCertID essCertid = new ESSCertID(MessageDigest.getInstance("SHA-1").digest(signerInfoGen.getAssociatedCertificate().getEncoded()));
+
+ this.signerInfoGen = new SignerInfoGenerator(signerInfoGen, new CMSAttributeTableGenerator()
+ {
+ public AttributeTable getAttributes(Map parameters)
+ throws CMSAttributeTableGenerationException
+ {
+ AttributeTable table = signerInfoGen.getSignedAttributeTableGenerator().getAttributes(parameters);
+
+ return table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid));
+ }
+ }, signerInfoGen.getUnsignedAttributeTableGenerator());
+
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new TSPException("Can't find a SHA-1 implementation.", e);
+ }
+ catch (IOException e)
+ {
+ throw new TSPException("Exception processing certificate.", e);
+ }
+ }
+
+ /**
+ * basic creation - only the default attributes will be included here.
+ * @deprecated use SignerInfoGenerator constructor
+ */
+ public TimeStampTokenGenerator(
+ PrivateKey key,
+ X509Certificate cert,
+ String digestOID,
+ String tsaPolicyOID)
+ throws IllegalArgumentException, TSPException
+ {
+ this(key, cert, digestOID, tsaPolicyOID, null, null);
+ }
+
+ /**
+ * basic creation - only the default attributes will be included here.
+ * @deprecated use SignerInfoGenerator constructor
+ */
+ public TimeStampTokenGenerator(
+ PrivateKey key,
+ X509Certificate cert,
+ ASN1ObjectIdentifier digestOID,
+ String tsaPolicyOID)
+ throws IllegalArgumentException, TSPException
+ {
+ this(key, cert, digestOID.getId(), tsaPolicyOID, null, null);
+ }
+
+ /**
+ * create with a signer with extra signed/unsigned attributes.
+ * @deprecated use SignerInfoGenerator constructor
+ */
+ public TimeStampTokenGenerator(
+ PrivateKey key,
+ X509Certificate cert,
+ String digestOID,
+ String tsaPolicyOID,
+ AttributeTable signedAttr,
+ AttributeTable unsignedAttr)
+ throws IllegalArgumentException, TSPException
+ {
+ this.key = key;
+ this.cert = cert;
+ this.digestOID = digestOID;
+ this.tsaPolicyOID = new ASN1ObjectIdentifier(tsaPolicyOID);
+ this.unsignedAttr = unsignedAttr;
+
+ //
+ // add the essCertid
+ //
+ Hashtable signedAttrs = null;
+
+ if (signedAttr != null)
+ {
+ signedAttrs = signedAttr.toHashtable();
+ }
+ else
+ {
+ signedAttrs = new Hashtable();
+ }
+
+
+ TSPUtil.validateCertificate(cert);
+
+ try
+ {
+ ESSCertID essCertid = new ESSCertID(MessageDigest.getInstance("SHA-1").digest(cert.getEncoded()));
+ signedAttrs.put(PKCSObjectIdentifiers.id_aa_signingCertificate,
+ new Attribute(
+ PKCSObjectIdentifiers.id_aa_signingCertificate,
+ new DERSet(new SigningCertificate(essCertid))));
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new TSPException("Can't find a SHA-1 implementation.", e);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new TSPException("Exception processing certificate.", e);
+ }
+
+ this.signedAttr = new AttributeTable(signedAttrs);
+ }
+
+ /**
+ * @deprecated use addCertificates and addCRLs
+ * @param certificates
+ * @throws CertStoreException
+ * @throws TSPException
+ */
+ public void setCertificatesAndCRLs(CertStore certificates)
+ throws CertStoreException, TSPException
+ {
+ Collection c1 = certificates.getCertificates(null);
+
+ for (Iterator it = c1.iterator(); it.hasNext();)
+ {
+ try
+ {
+ certs.add(new JcaX509CertificateHolder((X509Certificate)it.next()));
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new TSPException("cannot encode certificate: " + e.getMessage(), e);
+ }
+ }
+
+ c1 = certificates.getCRLs(null);
+
+ for (Iterator it = c1.iterator(); it.hasNext();)
+ {
+ try
+ {
+ crls.add(new JcaX509CRLHolder((X509CRL)it.next()));
+ }
+ catch (CRLException e)
+ {
+ throw new TSPException("cannot encode CRL: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Add the store of X509 Certificates to the generator.
+ *
+ * @param certStore a Store containing X509CertificateHolder objects
+ */
+ public void addCertificates(
+ Store certStore)
+ {
+ certs.addAll(certStore.getMatches(null));
+ }
+
+ /**
+ *
+ * @param crlStore a Store containing X509CRLHolder objects.
+ */
+ public void addCRLs(
+ Store crlStore)
+ {
+ crls.addAll(crlStore.getMatches(null));
+ }
+
+ /**
+ *
+ * @param attrStore a Store containing X509AttributeCertificate objects.
+ */
+ public void addAttributeCertificates(
+ Store attrStore)
+ {
+ attrCerts.addAll(attrStore.getMatches(null));
+ }
+
+ public void setAccuracySeconds(int accuracySeconds)
+ {
+ this.accuracySeconds = accuracySeconds;
+ }
+
+ public void setAccuracyMillis(int accuracyMillis)
+ {
+ this.accuracyMillis = accuracyMillis;
+ }
+
+ public void setAccuracyMicros(int accuracyMicros)
+ {
+ this.accuracyMicros = accuracyMicros;
+ }
+
+ public void setOrdering(boolean ordering)
+ {
+ this.ordering = ordering;
+ }
+
+ public void setTSA(GeneralName tsa)
+ {
+ this.tsa = tsa;
+ }
+
+ //------------------------------------------------------------------------------
+
+ public TimeStampToken generate(
+ TimeStampRequest request,
+ BigInteger serialNumber,
+ Date genTime,
+ String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException, TSPException
+ {
+ if (signerInfoGen == null)
+ {
+ try
+ {
+ JcaSignerInfoGeneratorBuilder sigBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(provider).build());
+
+ sigBuilder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(signedAttr));
+
+ if (unsignedAttr != null)
+ {
+ sigBuilder.setUnsignedAttributeGenerator(new SimpleAttributeTableGenerator(unsignedAttr));
+ }
+
+ signerInfoGen = sigBuilder.build(new JcaContentSignerBuilder(getSigAlgorithm(key, digestOID)).setProvider(provider).build(key), cert);
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new TSPException("Error generating signing operator", e);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new TSPException("Error encoding certificate", e);
+ }
+ }
+
+ return generate(request, serialNumber, genTime);
+ }
+
+ public TimeStampToken generate(
+ TimeStampRequest request,
+ BigInteger serialNumber,
+ Date genTime)
+ throws TSPException
+ {
+ if (signerInfoGen == null)
+ {
+ throw new IllegalStateException("can only use this method with SignerInfoGenerator constructor");
+ }
+
+ ASN1ObjectIdentifier digestAlgOID = request.getMessageImprintAlgOID();
+
+ AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, new DERNull());
+ MessageImprint messageImprint = new MessageImprint(algID, request.getMessageImprintDigest());
+
+ Accuracy accuracy = null;
+ if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0)
+ {
+ ASN1Integer seconds = null;
+ if (accuracySeconds > 0)
+ {
+ seconds = new ASN1Integer(accuracySeconds);
+ }
+
+ ASN1Integer millis = null;
+ if (accuracyMillis > 0)
+ {
+ millis = new ASN1Integer(accuracyMillis);
+ }
+
+ ASN1Integer micros = null;
+ if (accuracyMicros > 0)
+ {
+ micros = new ASN1Integer(accuracyMicros);
+ }
+
+ accuracy = new Accuracy(seconds, millis, micros);
+ }
+
+ ASN1Boolean derOrdering = null;
+ if (ordering)
+ {
+ derOrdering = new ASN1Boolean(ordering);
+ }
+
+ ASN1Integer nonce = null;
+ if (request.getNonce() != null)
+ {
+ nonce = new ASN1Integer(request.getNonce());
+ }
+
+ ASN1ObjectIdentifier tsaPolicy = tsaPolicyOID;
+ if (request.getReqPolicy() != null)
+ {
+ tsaPolicy = request.getReqPolicy();
+ }
+
+ TSTInfo tstInfo = new TSTInfo(tsaPolicy,
+ messageImprint, new ASN1Integer(serialNumber),
+ new ASN1GeneralizedTime(genTime), accuracy, derOrdering,
+ nonce, tsa, request.getExtensions());
+
+ try
+ {
+ CMSSignedDataGenerator signedDataGenerator = new CMSSignedDataGenerator();
+
+ if (request.getCertReq())
+ {
+ // TODO: do we need to check certs non-empty?
+ signedDataGenerator.addCertificates(new CollectionStore(certs));
+ signedDataGenerator.addCRLs(new CollectionStore(crls));
+ signedDataGenerator.addAttributeCertificates(new CollectionStore(attrCerts));
+ }
+ else
+ {
+ signedDataGenerator.addCRLs(new CollectionStore(crls));
+ }
+
+ signedDataGenerator.addSignerInfoGenerator(signerInfoGen);
+
+ byte[] derEncodedTSTInfo = tstInfo.getEncoded(ASN1Encoding.DER);
+
+ CMSSignedData signedData = signedDataGenerator.generate(new CMSProcessableByteArray(PKCSObjectIdentifiers.id_ct_TSTInfo, derEncodedTSTInfo), true);
+
+ return new TimeStampToken(signedData);
+ }
+ catch (CMSException cmsEx)
+ {
+ throw new TSPException("Error generating time-stamp token", cmsEx);
+ }
+ catch (IOException e)
+ {
+ throw new TSPException("Exception encoding info", e);
+ }
+ }
+
+ private String getSigAlgorithm(
+ PrivateKey key,
+ String digestOID)
+ {
+ String enc = null;
+
+ if (key instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(key.getAlgorithm()))
+ {
+ enc = "RSA";
+ }
+ else if (key instanceof DSAPrivateKey || "DSA".equalsIgnoreCase(key.getAlgorithm()))
+ {
+ enc = "DSA";
+ }
+ else if ("ECDSA".equalsIgnoreCase(key.getAlgorithm()) || "EC".equalsIgnoreCase(key.getAlgorithm()))
+ {
+ enc = "ECDSA";
+ }
+ else if (key instanceof GOST3410PrivateKey || "GOST3410".equalsIgnoreCase(key.getAlgorithm()))
+ {
+ enc = "GOST3410";
+ }
+ else if ("ECGOST3410".equalsIgnoreCase(key.getAlgorithm()))
+ {
+ enc = CMSSignedGenerator.ENCRYPTION_ECGOST3410;
+ }
+
+ return TSPUtil.getDigestAlgName(digestOID) + "with" + enc;
+ }
+}