package model.pki.crl; import model.asn1.*; import model.pki.AlgorithmIdentifier; import model.x501.Name; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Represents a CRL content: * *
 *     CertificateListContent ::= SEQUENCE {
 *      version Version OPTIONAL,
 *      -- if present, version shall be v2
 *      signature AlgorithmIdentifier{{SupportedAlgorithms}},
 *      issuer Name,
 *      thisUpdate Time,
 *      nextUpdate Time OPTIONAL,
 *      revokedCertificates SEQUENCE OF SEQUENCE {
 *        serialNumber CertificateSerialNumber,
 *        revocationDate Time,
 *        crlEntryExtensions Extensions OPTIONAL,
 *        ...} OPTIONAL,
 *      ...,
 *      ...,
 *      crlExtensions [0] Extensions OPTIONAL }
 * 
* * A CRL is a signed object published by the CA that revokes any certificates signed by this CA before their * expiration. Relying-parties should check the CRL from corresponding CDPs to see if the certificate to check is * already revoked. * Because the CA will only generate CRLs, this object won't be parsed. */ public class CertificateListContent extends ASN1Object { private final Int version = new Int(Int.TAG, null, 1); private final Name issuer; private final AlgorithmIdentifier signature; private final ASN1Time thisUpdate; private final ASN1Time nextUpdate; private final RevokedCertificate[] revokedCertificates; /** * EFFECTS: Init with tags and the given parameters. Version is always set to 1. * REQUIRES: except for nextUpdate, all other fields are non-null; items in revokedCerts should be SEQUENCE. */ public CertificateListContent(Tag tag, Tag parentTag, Name issuer, AlgorithmIdentifier signature, ASN1Time thisUpdate, ASN1Time nextUpdate, RevokedCertificate[] revokedCertificates) { super(tag, parentTag); this.issuer = issuer; this.signature = signature; this.thisUpdate = thisUpdate; this.nextUpdate = nextUpdate; this.revokedCertificates = revokedCertificates; } @Override public Byte[] encodeValueDER() { final List itemsEncoded = Arrays.stream(revokedCertificates) .map(Encodable::encodeDER) .flatMap(Arrays::stream) .collect(Collectors.toList()); return Stream.of(Arrays.asList(version.encodeDER()), Arrays.asList(issuer.encodeDER()), Arrays.asList(signature.encodeDER()), Arrays.asList(thisUpdate.encodeDER()), nextUpdate == null ? Collections.emptyList() : Arrays.asList(nextUpdate.encodeDER()), Arrays.asList(new Tag(TagClass.UNIVERSAL, true, 0x30).encodeDER()), Arrays.asList(new ASN1Length(itemsEncoded.size()).encodeDER()), itemsEncoded) .flatMap(Collection::stream) .toArray(Byte[]::new); } public Int getVersion() { return version; } public Name getIssuer() { return issuer; } public AlgorithmIdentifier getSignature() { return signature; } public ASN1Time getThisUpdate() { return thisUpdate; } public ASN1Time getNextUpdate() { return nextUpdate; } public RevokedCertificate[] getRevokedCertificates() { return revokedCertificates; } }