diff options
Diffstat (limited to 'crypto/j2me/org/bouncycastle/tsp/TimeStampTokenGenerator.java')
-rw-r--r-- | crypto/j2me/org/bouncycastle/tsp/TimeStampTokenGenerator.java | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/crypto/j2me/org/bouncycastle/tsp/TimeStampTokenGenerator.java b/crypto/j2me/org/bouncycastle/tsp/TimeStampTokenGenerator.java new file mode 100644 index 000000000..bc7b8d581 --- /dev/null +++ b/crypto/j2me/org/bouncycastle/tsp/TimeStampTokenGenerator.java @@ -0,0 +1,280 @@ +package org.bouncycastle.tsp; + +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; + +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.oiw.OIWObjectIdentifiers; +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.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.operator.DigestCalculator; +import org.bouncycastle.operator.OperatorCreationException; + +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; + + 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( + DigestCalculator sha1DigestCalculator, + final SignerInfoGenerator signerInfoGen, + ASN1ObjectIdentifier tsaPolicy) + throws IllegalArgumentException, TSPException + { + this.signerInfoGen = signerInfoGen; + this.tsaPolicyOID = tsaPolicy; + + if (!sha1DigestCalculator.getAlgorithmIdentifier().getAlgorithm().equals(OIWObjectIdentifiers.idSHA1)) + { + throw new IllegalArgumentException("Digest calculator must be for SHA-1"); + } + + if (!signerInfoGen.hasAssociatedCertificate()) + { + throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate"); + } + + TSPUtil.validateCertificate(signerInfoGen.getAssociatedCertificate()); + + try + { + OutputStream dOut = sha1DigestCalculator.getOutputStream(); + + dOut.write(signerInfoGen.getAssociatedCertificate().getEncoded()); + + dOut.close(); + + final ESSCertID essCertid = new ESSCertID(sha1DigestCalculator.getDigest()); + + 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 (IOException e) + { + throw new TSPException("Exception processing certificate.", 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) + 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); + } + } +} |