PrivateKeyUsagePeriod.ts (5447B)
1 import * as asn1js from "asn1js"; 2 import * as pvutils from "pvutils"; 3 import { EMPTY_STRING } from "./constants"; 4 import { AsnError } from "./errors"; 5 import { PkiObject, PkiObjectParameters } from "./PkiObject"; 6 import * as Schema from "./Schema"; 7 8 const NOT_BEFORE = "notBefore"; 9 const NOT_AFTER = "notAfter"; 10 const CLEAR_PROPS = [ 11 NOT_BEFORE, 12 NOT_AFTER 13 ]; 14 15 export interface IPrivateKeyUsagePeriod { 16 notBefore?: Date; 17 notAfter?: Date; 18 } 19 20 export interface PrivateKeyUsagePeriodJson { 21 notBefore?: Date; 22 notAfter?: Date; 23 } 24 25 export type PrivateKeyUsagePeriodParameters = PkiObjectParameters & Partial<IPrivateKeyUsagePeriod>; 26 27 /** 28 * Represents the PrivateKeyUsagePeriod structure described in [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280) 29 */ 30 export class PrivateKeyUsagePeriod extends PkiObject implements IPrivateKeyUsagePeriod { 31 32 public static override CLASS_NAME = "PrivateKeyUsagePeriod"; 33 34 public notBefore?: Date; 35 public notAfter?: Date; 36 37 /** 38 * Initializes a new instance of the {@link PrivateKeyUsagePeriod} class 39 * @param parameters Initialization parameters 40 */ 41 constructor(parameters: PrivateKeyUsagePeriodParameters = {}) { 42 super(); 43 44 if (NOT_BEFORE in parameters) { 45 this.notBefore = pvutils.getParametersValue(parameters, NOT_BEFORE, PrivateKeyUsagePeriod.defaultValues(NOT_BEFORE)); 46 } 47 48 if (NOT_AFTER in parameters) { 49 this.notAfter = pvutils.getParametersValue(parameters, NOT_AFTER, PrivateKeyUsagePeriod.defaultValues(NOT_AFTER)); 50 } 51 52 if (parameters.schema) { 53 this.fromSchema(parameters.schema); 54 } 55 } 56 57 /** 58 * Returns default values for all class members 59 * @param memberName String name for a class member 60 * @returns Default value 61 */ 62 public static override defaultValues(memberName: typeof NOT_BEFORE): Date; 63 public static override defaultValues(memberName: typeof NOT_AFTER): Date; 64 public static override defaultValues(memberName: string): any { 65 switch (memberName) { 66 case NOT_BEFORE: 67 return new Date(); 68 case NOT_AFTER: 69 return new Date(); 70 default: 71 return super.defaultValues(memberName); 72 } 73 } 74 75 /** 76 * @inheritdoc 77 * @asn ASN.1 schema 78 * ```asn 79 * PrivateKeyUsagePeriod OID ::= 2.5.29.16 80 * 81 * PrivateKeyUsagePeriod ::= SEQUENCE { 82 * notBefore [0] GeneralizedTime OPTIONAL, 83 * notAfter [1] GeneralizedTime OPTIONAL } 84 * -- either notBefore or notAfter MUST be present 85 *``` 86 */ 87 public static override schema(parameters: Schema.SchemaParameters<{ 88 notBefore?: string; 89 notAfter?: string; 90 }> = {}): Schema.SchemaType { 91 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 92 93 return (new asn1js.Sequence({ 94 name: (names.blockName || EMPTY_STRING), 95 value: [ 96 new asn1js.Primitive({ 97 name: (names.notBefore || EMPTY_STRING), 98 optional: true, 99 idBlock: { 100 tagClass: 3, // CONTEXT-SPECIFIC 101 tagNumber: 0 // [0] 102 } 103 }), 104 new asn1js.Primitive({ 105 name: (names.notAfter || EMPTY_STRING), 106 optional: true, 107 idBlock: { 108 tagClass: 3, // CONTEXT-SPECIFIC 109 tagNumber: 1 // [1] 110 } 111 }) 112 ] 113 })); 114 } 115 116 public fromSchema(schema: Schema.SchemaType): void { 117 // Clear input data first 118 pvutils.clearProps(schema, CLEAR_PROPS); 119 120 // Check the schema is valid 121 const asn1 = asn1js.compareSchema(schema, 122 schema, 123 PrivateKeyUsagePeriod.schema({ 124 names: { 125 notBefore: NOT_BEFORE, 126 notAfter: NOT_AFTER 127 } 128 }) 129 ); 130 AsnError.assertSchema(asn1, this.className); 131 132 // Get internal properties from parsed schema 133 if (NOT_BEFORE in asn1.result) { 134 const localNotBefore = new asn1js.GeneralizedTime(); 135 localNotBefore.fromBuffer(asn1.result.notBefore.valueBlock.valueHex); 136 this.notBefore = localNotBefore.toDate(); 137 } 138 if (NOT_AFTER in asn1.result) { 139 const localNotAfter = new asn1js.GeneralizedTime({ valueHex: asn1.result.notAfter.valueBlock.valueHex }); 140 localNotAfter.fromBuffer(asn1.result.notAfter.valueBlock.valueHex); 141 this.notAfter = localNotAfter.toDate(); 142 } 143 } 144 145 public toSchema(): asn1js.Sequence { 146 //#region Create array for output sequence 147 const outputArray = []; 148 149 if (NOT_BEFORE in this) { 150 outputArray.push(new asn1js.Primitive({ 151 idBlock: { 152 tagClass: 3, // CONTEXT-SPECIFIC 153 tagNumber: 0 // [0] 154 }, 155 valueHex: (new asn1js.GeneralizedTime({ valueDate: this.notBefore })).valueBlock.valueHexView 156 })); 157 } 158 159 if (NOT_AFTER in this) { 160 outputArray.push(new asn1js.Primitive({ 161 idBlock: { 162 tagClass: 3, // CONTEXT-SPECIFIC 163 tagNumber: 1 // [1] 164 }, 165 valueHex: (new asn1js.GeneralizedTime({ valueDate: this.notAfter })).valueBlock.valueHexView 166 })); 167 } 168 //#endregion 169 170 //#region Construct and return new ASN.1 schema for this object 171 return (new asn1js.Sequence({ 172 value: outputArray 173 })); 174 //#endregion 175 } 176 177 public toJSON(): PrivateKeyUsagePeriodJson { 178 const res: PrivateKeyUsagePeriodJson = {}; 179 180 if (this.notBefore) { 181 res.notBefore = this.notBefore; 182 } 183 184 if (this.notAfter) { 185 res.notAfter = this.notAfter; 186 } 187 188 return res; 189 } 190 191 }