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