RecipientKeyIdentifier.ts (6359B)
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 { OtherKeyAttribute, OtherKeyAttributeJson, OtherKeyAttributeSchema } from "./OtherKeyAttribute"; 6 import { PkiObject, PkiObjectParameters } from "./PkiObject"; 7 import * as Schema from "./Schema"; 8 9 const SUBJECT_KEY_IDENTIFIER = "subjectKeyIdentifier"; 10 const DATE = "date"; 11 const OTHER = "other"; 12 const CLEAR_PROPS = [ 13 SUBJECT_KEY_IDENTIFIER, 14 DATE, 15 OTHER, 16 ]; 17 18 export interface IRecipientKeyIdentifier { 19 subjectKeyIdentifier: asn1js.OctetString; 20 date?: asn1js.GeneralizedTime; 21 other?: OtherKeyAttribute; 22 } 23 24 export interface RecipientKeyIdentifierJson { 25 subjectKeyIdentifier: asn1js.OctetStringJson; 26 date?: asn1js.BaseBlockJson; 27 other?: OtherKeyAttributeJson; 28 } 29 30 export type RecipientKeyIdentifierParameters = PkiObjectParameters & Partial<IRecipientKeyIdentifier>; 31 32 export type RecipientKeyIdentifierSchema = Schema.SchemaParameters<{ 33 subjectKeyIdentifier?: string; 34 date?: string; 35 other?: OtherKeyAttributeSchema; 36 }>; 37 38 /** 39 * Represents the RecipientKeyIdentifier structure described in [RFC5652](https://datatracker.ietf.org/doc/html/rfc5652) 40 */ 41 export class RecipientKeyIdentifier extends PkiObject implements IRecipientKeyIdentifier { 42 43 public static override CLASS_NAME = "RecipientKeyIdentifier"; 44 45 public subjectKeyIdentifier!: asn1js.OctetString; 46 public date?: asn1js.GeneralizedTime; 47 public other?: OtherKeyAttribute; 48 49 /** 50 * Initializes a new instance of the {@link RecipientKeyIdentifier} class 51 * @param parameters Initialization parameters 52 */ 53 constructor(parameters: RecipientKeyIdentifierParameters = {}) { 54 super(); 55 56 this.subjectKeyIdentifier = pvutils.getParametersValue(parameters, SUBJECT_KEY_IDENTIFIER, RecipientKeyIdentifier.defaultValues(SUBJECT_KEY_IDENTIFIER)); 57 if (DATE in parameters) { 58 this.date = pvutils.getParametersValue(parameters, DATE, RecipientKeyIdentifier.defaultValues(DATE)); 59 } 60 if (OTHER in parameters) { 61 this.other = pvutils.getParametersValue(parameters, OTHER, RecipientKeyIdentifier.defaultValues(OTHER)); 62 } 63 64 if (parameters.schema) { 65 this.fromSchema(parameters.schema); 66 } 67 } 68 69 /** 70 * Returns default values for all class members 71 * @param memberName String name for a class member 72 * @returns Default value 73 */ 74 public static override defaultValues(memberName: typeof SUBJECT_KEY_IDENTIFIER): asn1js.OctetString; 75 public static override defaultValues(memberName: typeof DATE): asn1js.GeneralizedTime; 76 public static override defaultValues(memberName: typeof OTHER): OtherKeyAttribute; 77 public static override defaultValues(memberName: string): any { 78 switch (memberName) { 79 case SUBJECT_KEY_IDENTIFIER: 80 return new asn1js.OctetString(); 81 case DATE: 82 return new asn1js.GeneralizedTime(); 83 case OTHER: 84 return new OtherKeyAttribute(); 85 default: 86 return super.defaultValues(memberName); 87 } 88 } 89 90 /** 91 * Compare values with default values for all class members 92 * @param memberName String name for a class member 93 * @param memberValue Value to compare with default value 94 */ 95 public static compareWithDefault(memberName: string, memberValue: any): boolean { 96 switch (memberName) { 97 case SUBJECT_KEY_IDENTIFIER: 98 return (memberValue.isEqual(RecipientKeyIdentifier.defaultValues(SUBJECT_KEY_IDENTIFIER))); 99 case DATE: 100 return ((memberValue.year === 0) && 101 (memberValue.month === 0) && 102 (memberValue.day === 0) && 103 (memberValue.hour === 0) && 104 (memberValue.minute === 0) && 105 (memberValue.second === 0) && 106 (memberValue.millisecond === 0)); 107 case OTHER: 108 return ((memberValue.keyAttrId === EMPTY_STRING) && (("keyAttr" in memberValue) === false)); 109 default: 110 return super.defaultValues(memberName); 111 } 112 } 113 114 /** 115 * @inheritdoc 116 * @asn ASN.1 schema 117 * ```asn 118 * RecipientKeyIdentifier ::= SEQUENCE { 119 * subjectKeyIdentifier SubjectKeyIdentifier, 120 * date GeneralizedTime OPTIONAL, 121 * other OtherKeyAttribute OPTIONAL } 122 *``` 123 */ 124 public static override schema(parameters: RecipientKeyIdentifierSchema = {}): Schema.SchemaType { 125 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 126 127 return (new asn1js.Sequence({ 128 name: (names.blockName || EMPTY_STRING), 129 value: [ 130 new asn1js.OctetString({ name: (names.subjectKeyIdentifier || EMPTY_STRING) }), 131 new asn1js.GeneralizedTime({ 132 optional: true, 133 name: (names.date || EMPTY_STRING) 134 }), 135 OtherKeyAttribute.schema(names.other || {}) 136 ] 137 })); 138 } 139 140 public fromSchema(schema: Schema.SchemaType): void { 141 // Clear input data first 142 pvutils.clearProps(schema, CLEAR_PROPS); 143 144 // Check the schema is valid 145 const asn1 = asn1js.compareSchema(schema, 146 schema, 147 RecipientKeyIdentifier.schema({ 148 names: { 149 subjectKeyIdentifier: SUBJECT_KEY_IDENTIFIER, 150 date: DATE, 151 other: { 152 names: { 153 blockName: OTHER 154 } 155 } 156 } 157 }) 158 ); 159 AsnError.assertSchema(asn1, this.className); 160 161 // Get internal properties from parsed schema 162 this.subjectKeyIdentifier = asn1.result.subjectKeyIdentifier; 163 164 if (DATE in asn1.result) 165 this.date = asn1.result.date; 166 167 if (OTHER in asn1.result) 168 this.other = new OtherKeyAttribute({ schema: asn1.result.other }); 169 } 170 171 public toSchema(): asn1js.Sequence { 172 // Create array for output sequence 173 const outputArray = []; 174 175 outputArray.push(this.subjectKeyIdentifier); 176 177 if (this.date) { 178 outputArray.push(this.date); 179 } 180 181 if (this.other) { 182 outputArray.push(this.other.toSchema()); 183 } 184 185 // Construct and return new ASN.1 schema for this object 186 return (new asn1js.Sequence({ 187 value: outputArray 188 })); 189 } 190 191 public toJSON(): RecipientKeyIdentifierJson { 192 const res: any = { 193 subjectKeyIdentifier: this.subjectKeyIdentifier.toJSON() 194 }; 195 196 if (this.date) { 197 res.date = this.date.toJSON(); 198 } 199 200 if (this.other) { 201 res.other = this.other.toJSON(); 202 } 203 204 return res; 205 } 206 207 }