package model.pki.cert; import annotations.Assoc; import model.asn1.*; import model.asn1.exceptions.ParseException; import model.asn1.parsing.BytesReader; import java.util.Arrays; import java.util.Collection; import java.util.stream.Stream; /** * Represents the following ASN.1 structure: *
 *     Validity ::= SEQUENCE {
 *         notBefore Time,
 *         notAfter Time,
 *         ...
 *     }
 *
 *     Time ::= CHOICE {
 *         utcTime UTCTime,
 *         generalizedTime GeneralizedTime
 *     }
 * 
* It describes the validity period of the certificate. */ public class Validity extends ASN1Object { /** * The certificate is not valid before that time. */ @Assoc(partOf = true) private final ASN1Time notBefore; /** * The certificate is not valid after that time. */ @Assoc(partOf = true) private final ASN1Time notAfter; /** * EFFECTS: Init with the given tag, parentTag, notBefore, and notAfter. For more info on tag and parentTag, see * {@link ASN1Object}. * REQUIRES: notBefore and notAfter are either UTCTime or GeneralizedTime. */ public Validity(Tag tag, Tag parentTag, ASN1Time notBefore, ASN1Time notAfter) { super(tag, parentTag); this.notBefore = notBefore; this.notAfter = notAfter; } /** * EFFECTS: Parse input DER. * Throws {@link ASN1Object} if invalid: * - Any fields missing (info, algorithm, signature) * - Any fields having an incorrect tag (as seen in the ASN.1 definition) * - Any fields with encoding instructions that violate implicit / explicit encoding rules * - Other issues found during parsing the object, like early EOF (see {@link ASN1Object}) * MODIFIES: this, encoded */ public Validity(BytesReader encoded, boolean hasParentTag) throws ParseException { super(encoded, hasParentTag); if (encoded.detectTag(GeneralizedTime.TAG)) { this.notBefore = new GeneralizedTime(encoded, false); this.notBefore.getTag().enforce(GeneralizedTime.TAG); } else { this.notBefore = new UtcTime(encoded, false); this.notBefore.getTag().enforce(UtcTime.TAG); } if (encoded.detectTag(GeneralizedTime.TAG)) { this.notAfter = new GeneralizedTime(encoded, false); this.notAfter.getTag().enforce(GeneralizedTime.TAG); } else { this.notAfter = new UtcTime(encoded, false); this.notAfter.getTag().enforce(UtcTime.TAG); } } /** * EFFECTS: Encode into ordered DER. */ @Override public Byte[] encodeValueDER() { return Stream.of(Arrays.asList(notBefore.encodeDER()), Arrays.asList(notAfter.encodeDER())) .flatMap(Collection::stream) .toArray(Byte[]::new); } public ASN1Time getNotBefore() { return notBefore; } public ASN1Time getNotAfter() { return notAfter; } }