diff options
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/x509/V2TBSCertListGenerator.java')
-rw-r--r-- | core/src/main/java/org/spongycastle/asn1/x509/V2TBSCertListGenerator.java | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/x509/V2TBSCertListGenerator.java b/core/src/main/java/org/spongycastle/asn1/x509/V2TBSCertListGenerator.java new file mode 100644 index 00000000..8419470a --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/x509/V2TBSCertListGenerator.java @@ -0,0 +1,281 @@ +package org.spongycastle.asn1.x509; + +import java.io.IOException; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1GeneralizedTime; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.ASN1UTCTime; +import org.spongycastle.asn1.DEROctetString; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.x500.X500Name; + +/** + * Generator for Version 2 TBSCertList structures. + * <pre> + * TBSCertList ::= SEQUENCE { + * version Version OPTIONAL, + * -- if present, shall be v2 + * signature AlgorithmIdentifier, + * issuer Name, + * thisUpdate Time, + * nextUpdate Time OPTIONAL, + * revokedCertificates SEQUENCE OF SEQUENCE { + * userCertificate CertificateSerialNumber, + * revocationDate Time, + * crlEntryExtensions Extensions OPTIONAL + * -- if present, shall be v2 + * } OPTIONAL, + * crlExtensions [0] EXPLICIT Extensions OPTIONAL + * -- if present, shall be v2 + * } + * </pre> + * + * <b>Note: This class may be subject to change</b> + */ +public class V2TBSCertListGenerator +{ + private ASN1Integer version = new ASN1Integer(1); + private AlgorithmIdentifier signature; + private X500Name issuer; + private Time thisUpdate, nextUpdate=null; + private Extensions extensions = null; + private ASN1EncodableVector crlentries = new ASN1EncodableVector(); + + private final static ASN1Sequence[] reasons; + + static + { + reasons = new ASN1Sequence[11]; + + reasons[0] = createReasonExtension(CRLReason.unspecified); + reasons[1] = createReasonExtension(CRLReason.keyCompromise); + reasons[2] = createReasonExtension(CRLReason.cACompromise); + reasons[3] = createReasonExtension(CRLReason.affiliationChanged); + reasons[4] = createReasonExtension(CRLReason.superseded); + reasons[5] = createReasonExtension(CRLReason.cessationOfOperation); + reasons[6] = createReasonExtension(CRLReason.certificateHold); + reasons[7] = createReasonExtension(7); // 7 -> unknown + reasons[8] = createReasonExtension(CRLReason.removeFromCRL); + reasons[9] = createReasonExtension(CRLReason.privilegeWithdrawn); + reasons[10] = createReasonExtension(CRLReason.aACompromise); + } + + public V2TBSCertListGenerator() + { + } + + + public void setSignature( + AlgorithmIdentifier signature) + { + this.signature = signature; + } + + /** + * @deprecated use X500Name method + */ + public void setIssuer( + X509Name issuer) + { + this.issuer = X500Name.getInstance(issuer.toASN1Primitive()); + } + + public void setIssuer(X500Name issuer) + { + this.issuer = issuer; + } + + public void setThisUpdate( + ASN1UTCTime thisUpdate) + { + this.thisUpdate = new Time(thisUpdate); + } + + public void setNextUpdate( + ASN1UTCTime nextUpdate) + { + this.nextUpdate = new Time(nextUpdate); + } + + public void setThisUpdate( + Time thisUpdate) + { + this.thisUpdate = thisUpdate; + } + + public void setNextUpdate( + Time nextUpdate) + { + this.nextUpdate = nextUpdate; + } + + public void addCRLEntry( + ASN1Sequence crlEntry) + { + crlentries.add(crlEntry); + } + + public void addCRLEntry(ASN1Integer userCertificate, ASN1UTCTime revocationDate, int reason) + { + addCRLEntry(userCertificate, new Time(revocationDate), reason); + } + + public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, int reason) + { + addCRLEntry(userCertificate, revocationDate, reason, null); + } + + public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, int reason, ASN1GeneralizedTime invalidityDate) + { + if (reason != 0) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + if (reason < reasons.length) + { + if (reason < 0) + { + throw new IllegalArgumentException("invalid reason value: " + reason); + } + v.add(reasons[reason]); + } + else + { + v.add(createReasonExtension(reason)); + } + + if (invalidityDate != null) + { + v.add(createInvalidityDateExtension(invalidityDate)); + } + + internalAddCRLEntry(userCertificate, revocationDate, new DERSequence(v)); + } + else if (invalidityDate != null) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(createInvalidityDateExtension(invalidityDate)); + + internalAddCRLEntry(userCertificate, revocationDate, new DERSequence(v)); + } + else + { + addCRLEntry(userCertificate, revocationDate, null); + } + } + + private void internalAddCRLEntry(ASN1Integer userCertificate, Time revocationDate, ASN1Sequence extensions) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(userCertificate); + v.add(revocationDate); + + if (extensions != null) + { + v.add(extensions); + } + + addCRLEntry(new DERSequence(v)); + } + + public void addCRLEntry(ASN1Integer userCertificate, Time revocationDate, Extensions extensions) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(userCertificate); + v.add(revocationDate); + + if (extensions != null) + { + v.add(extensions); + } + + addCRLEntry(new DERSequence(v)); + } + + public void setExtensions( + X509Extensions extensions) + { + setExtensions(Extensions.getInstance(extensions)); + } + + public void setExtensions( + Extensions extensions) + { + this.extensions = extensions; + } + + public TBSCertList generateTBSCertList() + { + if ((signature == null) || (issuer == null) || (thisUpdate == null)) + { + throw new IllegalStateException("Not all mandatory fields set in V2 TBSCertList generator."); + } + + ASN1EncodableVector v = new ASN1EncodableVector(); + + v.add(version); + v.add(signature); + v.add(issuer); + + v.add(thisUpdate); + if (nextUpdate != null) + { + v.add(nextUpdate); + } + + // Add CRLEntries if they exist + if (crlentries.size() != 0) + { + v.add(new DERSequence(crlentries)); + } + + if (extensions != null) + { + v.add(new DERTaggedObject(0, extensions)); + } + + return new TBSCertList(new DERSequence(v)); + } + + private static ASN1Sequence createReasonExtension(int reasonCode) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + CRLReason crlReason = CRLReason.lookup(reasonCode); + + try + { + v.add(Extension.reasonCode); + v.add(new DEROctetString(crlReason.getEncoded())); + } + catch (IOException e) + { + throw new IllegalArgumentException("error encoding reason: " + e); + } + + return new DERSequence(v); + } + + private static ASN1Sequence createInvalidityDateExtension(ASN1GeneralizedTime invalidityDate) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + try + { + v.add(Extension.invalidityDate); + v.add(new DEROctetString(invalidityDate.getEncoded())); + } + catch (IOException e) + { + throw new IllegalArgumentException("error encoding reason: " + e); + } + + return new DERSequence(v); + } +} |