CRLBag.ts (5502B)
1 import * as asn1js from "asn1js"; 2 import * as pvutils from "pvutils"; 3 import { CertificateRevocationList } from "./CertificateRevocationList"; 4 import { EMPTY_STRING } from "./constants"; 5 import { AsnError } from "./errors"; 6 import { id_CRLBag_X509CRL } from "./ObjectIdentifiers"; 7 import { PkiObject, PkiObjectParameters } from "./PkiObject"; 8 import * as Schema from "./Schema"; 9 10 const CRL_ID = "crlId"; 11 const CRL_VALUE = "crlValue"; 12 const PARSED_VALUE = "parsedValue"; 13 const CLEAR_PROPS = [ 14 CRL_ID, 15 CRL_VALUE, 16 ]; 17 18 export interface ICRLBag { 19 crlId: string; 20 crlValue: any; 21 parsedValue?: any; 22 certValue?: any; 23 } 24 25 export interface CRLBagJson { 26 crlId: string; 27 crlValue: any; 28 } 29 30 export type CRLBagParameters = PkiObjectParameters & Partial<ICRLBag>; 31 32 /** 33 * Represents the CRLBag structure described in [RFC7292](https://datatracker.ietf.org/doc/html/rfc7292) 34 */ 35 export class CRLBag extends PkiObject implements ICRLBag { 36 37 public static override CLASS_NAME = "CRLBag"; 38 39 public crlId!: string; 40 public crlValue: any; 41 public parsedValue?: any; 42 public certValue?: any; 43 44 /** 45 * Initializes a new instance of the {@link CRLBag} class 46 * @param parameters Initialization parameters 47 */ 48 constructor(parameters: CRLBagParameters = {}) { 49 super(); 50 51 this.crlId = pvutils.getParametersValue(parameters, CRL_ID, CRLBag.defaultValues(CRL_ID)); 52 this.crlValue = pvutils.getParametersValue(parameters, CRL_VALUE, CRLBag.defaultValues(CRL_VALUE)); 53 if (PARSED_VALUE in parameters) { 54 this.parsedValue = pvutils.getParametersValue(parameters, PARSED_VALUE, CRLBag.defaultValues(PARSED_VALUE)); 55 } 56 if (parameters.schema) { 57 this.fromSchema(parameters.schema); 58 } 59 } 60 61 /** 62 * Returns default values for all class members 63 * @param memberName String name for a class member 64 * @returns Default value 65 */ 66 public static override defaultValues(memberName: typeof CRL_ID): string; 67 public static override defaultValues(memberName: typeof CRL_VALUE): any; 68 public static override defaultValues(memberName: typeof PARSED_VALUE): any; 69 public static override defaultValues(memberName: string): any { 70 switch (memberName) { 71 case CRL_ID: 72 return EMPTY_STRING; 73 case CRL_VALUE: 74 return (new asn1js.Any()); 75 case PARSED_VALUE: 76 return {}; 77 default: 78 return super.defaultValues(memberName); 79 } 80 } 81 82 /** 83 * Compare values with default values for all class members 84 * @param memberName String name for a class member 85 * @param memberValue Value to compare with default value 86 */ 87 public static compareWithDefault(memberName: string, memberValue: any): boolean { 88 switch (memberName) { 89 case CRL_ID: 90 return (memberValue === EMPTY_STRING); 91 case CRL_VALUE: 92 return (memberValue instanceof asn1js.Any); 93 case PARSED_VALUE: 94 return ((memberValue instanceof Object) && (Object.keys(memberValue).length === 0)); 95 default: 96 return super.defaultValues(memberName); 97 } 98 } 99 100 /** 101 * @inheritdoc 102 * @asn ASN.1 schema 103 * ```asn 104 * CRLBag ::= SEQUENCE { 105 * crlId BAG-TYPE.&id ({CRLTypes}), 106 * crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId}) 107 *} 108 *``` 109 */ 110 public static override schema(parameters: Schema.SchemaParameters<{ 111 id?: string; 112 value?: string; 113 }> = {}): Schema.SchemaType { 114 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 115 116 return (new asn1js.Sequence({ 117 name: (names.blockName || EMPTY_STRING), 118 value: [ 119 new asn1js.ObjectIdentifier({ name: (names.id || "id") }), 120 new asn1js.Constructed({ 121 idBlock: { 122 tagClass: 3, // CONTEXT-SPECIFIC 123 tagNumber: 0 // [0] 124 }, 125 value: [new asn1js.Any({ name: (names.value || "value") })] // EXPLICIT ANY value 126 }) 127 ] 128 })); 129 } 130 131 public fromSchema(schema: Schema.SchemaType): void { 132 // Clear input data first 133 pvutils.clearProps(schema, CLEAR_PROPS); 134 135 // Check the schema is valid 136 const asn1 = asn1js.compareSchema(schema, 137 schema, 138 CRLBag.schema({ 139 names: { 140 id: CRL_ID, 141 value: CRL_VALUE 142 } 143 }) 144 ); 145 AsnError.assertSchema(asn1, this.className); 146 147 // Get internal properties from parsed schema 148 this.crlId = asn1.result.crlId.valueBlock.toString(); 149 this.crlValue = asn1.result.crlValue; 150 151 switch (this.crlId) { 152 case id_CRLBag_X509CRL: // x509CRL 153 { 154 this.parsedValue = CertificateRevocationList.fromBER(this.certValue.valueBlock.valueHex); 155 } 156 break; 157 default: 158 throw new Error(`Incorrect CRL_ID value in CRLBag: ${this.crlId}`); 159 } 160 } 161 162 public toSchema(): asn1js.Sequence { 163 // Construct and return new ASN.1 schema for this object 164 if (this.parsedValue) { 165 this.crlId = id_CRLBag_X509CRL; 166 this.crlValue = new asn1js.OctetString({ valueHex: this.parsedValue.toSchema().toBER(false) }); 167 } 168 169 return (new asn1js.Sequence({ 170 value: [ 171 new asn1js.ObjectIdentifier({ value: this.crlId }), 172 new asn1js.Constructed({ 173 idBlock: { 174 tagClass: 3, // CONTEXT-SPECIFIC 175 tagNumber: 0 // [0] 176 }, 177 value: [this.crlValue.toSchema()] 178 }) 179 ] 180 })); 181 } 182 183 public toJSON(): CRLBagJson { 184 return { 185 crlId: this.crlId, 186 crlValue: this.crlValue.toJSON() 187 }; 188 } 189 190 }