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