OriginatorIdentifierOrKey.ts (6104B)
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 { IssuerAndSerialNumber } from "./IssuerAndSerialNumber"; 6 import { OriginatorPublicKey } from "./OriginatorPublicKey"; 7 import { PkiObject, PkiObjectParameters } from "./PkiObject"; 8 import * as Schema from "./Schema"; 9 10 const VARIANT = "variant"; 11 const VALUE = "value"; 12 const CLEAR_PROPS = [ 13 "blockName", 14 ]; 15 16 export interface IOriginatorIdentifierOrKey { 17 variant: number; 18 value?: any; 19 } 20 21 export interface OriginatorIdentifierOrKeyJson { 22 variant: number; 23 value?: any; 24 } 25 26 export type OriginatorIdentifierOrKeyParameters = PkiObjectParameters & Partial<IOriginatorIdentifierOrKey>; 27 28 export type OriginatorIdentifierOrKeySchema = Schema.SchemaParameters; 29 30 /** 31 * Represents the OriginatorIdentifierOrKey structure described in [RFC5652](https://datatracker.ietf.org/doc/html/rfc5652) 32 */ 33 export class OriginatorIdentifierOrKey extends PkiObject implements IOriginatorIdentifierOrKey { 34 35 public static override CLASS_NAME = "OriginatorIdentifierOrKey"; 36 37 public variant!: number; 38 public value?: any; 39 40 /** 41 * Initializes a new instance of the {@link OriginatorIdentifierOrKey} class 42 * @param parameters Initialization parameters 43 */ 44 constructor(parameters: OriginatorIdentifierOrKeyParameters = {}) { 45 super(); 46 47 this.variant = pvutils.getParametersValue(parameters, VARIANT, OriginatorIdentifierOrKey.defaultValues(VARIANT)); 48 if (VALUE in parameters) { 49 this.value = pvutils.getParametersValue(parameters, VALUE, OriginatorIdentifierOrKey.defaultValues(VALUE)); 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 VARIANT): number; 63 public static override defaultValues(memberName: typeof VALUE): any; 64 public static override defaultValues(memberName: string): any { 65 switch (memberName) { 66 case VARIANT: 67 return (-1); 68 case VALUE: 69 return {}; 70 default: 71 return super.defaultValues(memberName); 72 } 73 } 74 75 /** 76 * Compare values with default values for all class members 77 * @param memberName String name for a class member 78 * @param memberValue Value to compare with default value 79 */ 80 public static compareWithDefault(memberName: string, memberValue: any): boolean { 81 switch (memberName) { 82 case VARIANT: 83 return (memberValue === (-1)); 84 case VALUE: 85 return (Object.keys(memberValue).length === 0); 86 default: 87 return super.defaultValues(memberName); 88 } 89 } 90 91 /** 92 * @inheritdoc 93 * @asn ASN.1 schema 94 * ```asn 95 * OriginatorIdentifierOrKey ::= CHOICE { 96 * issuerAndSerialNumber IssuerAndSerialNumber, 97 * subjectKeyIdentifier [0] SubjectKeyIdentifier, 98 * originatorKey [1] OriginatorPublicKey } 99 *``` 100 */ 101 public static override schema(parameters: OriginatorIdentifierOrKeySchema = {}): Schema.SchemaType { 102 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 103 104 return (new asn1js.Choice({ 105 value: [ 106 IssuerAndSerialNumber.schema({ 107 names: { 108 blockName: (names.blockName || EMPTY_STRING) 109 } 110 }), 111 new asn1js.Primitive({ 112 idBlock: { 113 tagClass: 3, // CONTEXT-SPECIFIC 114 tagNumber: 0 // [0] 115 }, 116 name: (names.blockName || EMPTY_STRING) 117 }), 118 new asn1js.Constructed({ 119 idBlock: { 120 tagClass: 3, // CONTEXT-SPECIFIC 121 tagNumber: 1 // [1] 122 }, 123 name: (names.blockName || EMPTY_STRING), 124 value: OriginatorPublicKey.schema().valueBlock.value 125 }) 126 ] 127 })); 128 } 129 130 public fromSchema(schema: Schema.SchemaType): void { 131 // Clear input data first 132 pvutils.clearProps(schema, CLEAR_PROPS); 133 134 // Check the schema is valid 135 const asn1 = asn1js.compareSchema(schema, 136 schema, 137 OriginatorIdentifierOrKey.schema({ 138 names: { 139 blockName: "blockName" 140 } 141 }) 142 ); 143 AsnError.assertSchema(asn1, this.className); 144 145 //#region Get internal properties from parsed schema 146 if (asn1.result.blockName.idBlock.tagClass === 1) { 147 this.variant = 1; 148 this.value = new IssuerAndSerialNumber({ schema: asn1.result.blockName }); 149 } 150 else { 151 if (asn1.result.blockName.idBlock.tagNumber === 0) { 152 //#region Create "OCTETSTRING" from "ASN1_PRIMITIVE" 153 asn1.result.blockName.idBlock.tagClass = 1; // UNIVERSAL 154 asn1.result.blockName.idBlock.tagNumber = 4; // OCTETSTRING 155 //#endregion 156 157 this.variant = 2; 158 this.value = asn1.result.blockName; 159 } 160 else { 161 this.variant = 3; 162 this.value = new OriginatorPublicKey({ 163 schema: new asn1js.Sequence({ 164 value: asn1.result.blockName.valueBlock.value 165 }) 166 }); 167 } 168 } 169 //#endregion 170 } 171 172 public toSchema(): asn1js.BaseBlock<any> { 173 //#region Construct and return new ASN.1 schema for this object 174 switch (this.variant) { 175 case 1: 176 return this.value.toSchema(); 177 case 2: 178 this.value.idBlock.tagClass = 3; // CONTEXT-SPECIFIC 179 this.value.idBlock.tagNumber = 0; // [0] 180 181 return this.value; 182 case 3: 183 { 184 const _schema = this.value.toSchema(); 185 186 _schema.idBlock.tagClass = 3; // CONTEXT-SPECIFIC 187 _schema.idBlock.tagNumber = 1; // [1] 188 189 return _schema; 190 } 191 default: 192 return new asn1js.Any() as any; 193 } 194 //#endregion 195 } 196 197 public toJSON(): OriginatorIdentifierOrKeyJson { 198 const res: OriginatorIdentifierOrKeyJson = { 199 variant: this.variant 200 }; 201 202 if ((this.variant === 1) || (this.variant === 2) || (this.variant === 3)) { 203 res.value = this.value.toJSON(); 204 } 205 206 return res; 207 } 208 209 }