AuthorityKeyIdentifier.ts (7579B)
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 { GeneralName, GeneralNameJson } from "./GeneralName"; 6 import { PkiObject, PkiObjectParameters } from "./PkiObject"; 7 import * as Schema from "./Schema"; 8 9 const KEY_IDENTIFIER = "keyIdentifier"; 10 const AUTHORITY_CERT_ISSUER = "authorityCertIssuer"; 11 const AUTHORITY_CERT_SERIAL_NUMBER = "authorityCertSerialNumber"; 12 const CLEAR_PROPS = [ 13 KEY_IDENTIFIER, 14 AUTHORITY_CERT_ISSUER, 15 AUTHORITY_CERT_SERIAL_NUMBER, 16 ]; 17 18 export interface IAuthorityKeyIdentifier { 19 keyIdentifier?: asn1js.OctetString; 20 authorityCertIssuer?: GeneralName[]; 21 authorityCertSerialNumber?: asn1js.Integer; 22 } 23 24 export type AuthorityKeyIdentifierParameters = PkiObjectParameters & Partial<IAuthorityKeyIdentifier>; 25 26 export interface AuthorityKeyIdentifierJson { 27 keyIdentifier?: asn1js.OctetStringJson; 28 authorityCertIssuer?: GeneralNameJson[]; 29 authorityCertSerialNumber?: asn1js.IntegerJson; 30 } 31 32 /** 33 * Represents the AuthorityKeyIdentifier structure described in [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280) 34 */ 35 export class AuthorityKeyIdentifier extends PkiObject implements IAuthorityKeyIdentifier { 36 37 public static override CLASS_NAME = "AuthorityKeyIdentifier"; 38 39 public keyIdentifier?: asn1js.OctetString; 40 public authorityCertIssuer?: GeneralName[]; 41 public authorityCertSerialNumber?: asn1js.Integer; 42 43 /** 44 * Initializes a new instance of the {@link AuthorityKeyIdentifier} class 45 * @param parameters Initialization parameters 46 */ 47 constructor(parameters: AuthorityKeyIdentifierParameters = {}) { 48 super(); 49 50 if (KEY_IDENTIFIER in parameters) { 51 this.keyIdentifier = pvutils.getParametersValue(parameters, KEY_IDENTIFIER, AuthorityKeyIdentifier.defaultValues(KEY_IDENTIFIER)); 52 } 53 if (AUTHORITY_CERT_ISSUER in parameters) { 54 this.authorityCertIssuer = pvutils.getParametersValue(parameters, AUTHORITY_CERT_ISSUER, AuthorityKeyIdentifier.defaultValues(AUTHORITY_CERT_ISSUER)); 55 } 56 if (AUTHORITY_CERT_SERIAL_NUMBER in parameters) { 57 this.authorityCertSerialNumber = pvutils.getParametersValue(parameters, AUTHORITY_CERT_SERIAL_NUMBER, AuthorityKeyIdentifier.defaultValues(AUTHORITY_CERT_SERIAL_NUMBER)); 58 } 59 60 if (parameters.schema) { 61 this.fromSchema(parameters.schema); 62 } 63 } 64 65 /** 66 * Returns default values for all class members 67 * @param memberName String name for a class member 68 * @returns Default value 69 */ 70 public static override defaultValues(memberName: typeof KEY_IDENTIFIER): asn1js.OctetString; 71 public static override defaultValues(memberName: typeof AUTHORITY_CERT_ISSUER): GeneralName[]; 72 public static override defaultValues(memberName: typeof AUTHORITY_CERT_SERIAL_NUMBER): asn1js.Integer; 73 public static override defaultValues(memberName: string): any { 74 switch (memberName) { 75 case KEY_IDENTIFIER: 76 return new asn1js.OctetString(); 77 case AUTHORITY_CERT_ISSUER: 78 return []; 79 case AUTHORITY_CERT_SERIAL_NUMBER: 80 return new asn1js.Integer(); 81 default: 82 return super.defaultValues(memberName); 83 } 84 } 85 86 /** 87 * @inheritdoc 88 * @asn ASN.1 schema 89 * ```asn 90 * AuthorityKeyIdentifier OID ::= 2.5.29.35 91 * 92 * AuthorityKeyIdentifier ::= SEQUENCE { 93 * keyIdentifier [0] KeyIdentifier OPTIONAL, 94 * authorityCertIssuer [1] GeneralNames OPTIONAL, 95 * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } 96 * 97 * KeyIdentifier ::= OCTET STRING 98 *``` 99 */ 100 public static override schema(parameters: Schema.SchemaParameters<{ 101 keyIdentifier?: string; 102 authorityCertIssuer?: string; 103 authorityCertSerialNumber?: string; 104 }> = {}): Schema.SchemaType { 105 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 106 107 return (new asn1js.Sequence({ 108 name: (names.blockName || EMPTY_STRING), 109 value: [ 110 new asn1js.Primitive({ 111 name: (names.keyIdentifier || EMPTY_STRING), 112 optional: true, 113 idBlock: { 114 tagClass: 3, // CONTEXT-SPECIFIC 115 tagNumber: 0 // [0] 116 } 117 }), 118 new asn1js.Constructed({ 119 optional: true, 120 idBlock: { 121 tagClass: 3, // CONTEXT-SPECIFIC 122 tagNumber: 1 // [1] 123 }, 124 value: [ 125 new asn1js.Repeated({ 126 name: (names.authorityCertIssuer || EMPTY_STRING), 127 value: GeneralName.schema() 128 }) 129 ] 130 }), 131 new asn1js.Primitive({ 132 name: (names.authorityCertSerialNumber || EMPTY_STRING), 133 optional: true, 134 idBlock: { 135 tagClass: 3, // CONTEXT-SPECIFIC 136 tagNumber: 2 // [2] 137 } 138 }) 139 ] 140 })); 141 } 142 143 public fromSchema(schema: Schema.SchemaType): void { 144 // Clear input data first 145 pvutils.clearProps(schema, CLEAR_PROPS); 146 147 // Check the schema is valid 148 const asn1 = asn1js.compareSchema(schema, 149 schema, 150 AuthorityKeyIdentifier.schema({ 151 names: { 152 keyIdentifier: KEY_IDENTIFIER, 153 authorityCertIssuer: AUTHORITY_CERT_ISSUER, 154 authorityCertSerialNumber: AUTHORITY_CERT_SERIAL_NUMBER 155 } 156 }) 157 ); 158 AsnError.assertSchema(asn1, this.className); 159 160 // Get internal properties from parsed schema 161 if (KEY_IDENTIFIER in asn1.result) 162 this.keyIdentifier = new asn1js.OctetString({ valueHex: asn1.result.keyIdentifier.valueBlock.valueHex }); 163 164 if (AUTHORITY_CERT_ISSUER in asn1.result) 165 this.authorityCertIssuer = Array.from(asn1.result.authorityCertIssuer, o => new GeneralName({ schema: o })); 166 167 if (AUTHORITY_CERT_SERIAL_NUMBER in asn1.result) 168 this.authorityCertSerialNumber = new asn1js.Integer({ valueHex: asn1.result.authorityCertSerialNumber.valueBlock.valueHex }); 169 //#endregion 170 } 171 172 public toSchema(): asn1js.Sequence { 173 //#region Create array for output sequence 174 const outputArray = []; 175 176 if (this.keyIdentifier) { 177 outputArray.push(new asn1js.Primitive({ 178 idBlock: { 179 tagClass: 3, // CONTEXT-SPECIFIC 180 tagNumber: 0 // [0] 181 }, 182 valueHex: this.keyIdentifier.valueBlock.valueHexView 183 })); 184 } 185 186 if (this.authorityCertIssuer) { 187 outputArray.push(new asn1js.Constructed({ 188 idBlock: { 189 tagClass: 3, // CONTEXT-SPECIFIC 190 tagNumber: 1 // [1] 191 }, 192 value: Array.from(this.authorityCertIssuer, o => o.toSchema()) 193 })); 194 } 195 196 if (this.authorityCertSerialNumber) { 197 outputArray.push(new asn1js.Primitive({ 198 idBlock: { 199 tagClass: 3, // CONTEXT-SPECIFIC 200 tagNumber: 2 // [2] 201 }, 202 valueHex: this.authorityCertSerialNumber.valueBlock.valueHexView 203 })); 204 } 205 //#endregion 206 207 //#region Construct and return new ASN.1 schema for this object 208 return (new asn1js.Sequence({ 209 value: outputArray 210 })); 211 //#endregion 212 } 213 214 public toJSON(): AuthorityKeyIdentifierJson { 215 const object: AuthorityKeyIdentifierJson = {}; 216 217 if (this.keyIdentifier) { 218 object.keyIdentifier = this.keyIdentifier.toJSON(); 219 } 220 if (this.authorityCertIssuer) { 221 object.authorityCertIssuer = Array.from(this.authorityCertIssuer, o => o.toJSON()); 222 } 223 if (this.authorityCertSerialNumber) { 224 object.authorityCertSerialNumber = this.authorityCertSerialNumber.toJSON(); 225 } 226 227 return object; 228 } 229 230 }