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