SecretBag.ts (4698B)
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 { PkiObject, PkiObjectParameters } from "./PkiObject"; 6 import * as Schema from "./Schema"; 7 8 const SECRET_TYPE_ID = "secretTypeId"; 9 const SECRET_VALUE = "secretValue"; 10 const CLEAR_PROPS = [ 11 SECRET_TYPE_ID, 12 SECRET_VALUE, 13 ]; 14 15 export interface ISecretBag { 16 secretTypeId: string; 17 secretValue: Schema.SchemaCompatible; 18 } 19 20 export interface SecretBagJson { 21 secretTypeId: string; 22 secretValue: asn1js.BaseBlockJson; 23 } 24 25 export type SecretBagParameters = PkiObjectParameters & Partial<ISecretBag>; 26 27 /** 28 * Represents the SecretBag structure described in [RFC7292](https://datatracker.ietf.org/doc/html/rfc7292) 29 */ 30 export class SecretBag extends PkiObject implements ISecretBag { 31 32 public static override CLASS_NAME = "SecretBag"; 33 34 public secretTypeId!: string; 35 public secretValue!: Schema.SchemaCompatible; 36 37 /** 38 * Initializes a new instance of the {@link SecretBag} class 39 * @param parameters Initialization parameters 40 */ 41 constructor(parameters: SecretBagParameters = {}) { 42 super(); 43 44 this.secretTypeId = pvutils.getParametersValue(parameters, SECRET_TYPE_ID, SecretBag.defaultValues(SECRET_TYPE_ID)); 45 this.secretValue = pvutils.getParametersValue(parameters, SECRET_VALUE, SecretBag.defaultValues(SECRET_VALUE)); 46 47 if (parameters.schema) { 48 this.fromSchema(parameters.schema); 49 } 50 } 51 52 /** 53 * Returns default values for all class members 54 * @param memberName String name for a class member 55 * @returns Default value 56 */ 57 public static override defaultValues(memberName: typeof SECRET_TYPE_ID): string; 58 public static override defaultValues(memberName: typeof SECRET_VALUE): Schema.SchemaCompatible; 59 public static override defaultValues(memberName: string): any { 60 switch (memberName) { 61 case SECRET_TYPE_ID: 62 return EMPTY_STRING; 63 case SECRET_VALUE: 64 return (new asn1js.Any()); 65 default: 66 return super.defaultValues(memberName); 67 } 68 } 69 70 /** 71 * Compare values with default values for all class members 72 * @param memberName String name for a class member 73 * @param memberValue Value to compare with default value 74 */ 75 public static compareWithDefault(memberName: string, memberValue: any): boolean { 76 switch (memberName) { 77 case SECRET_TYPE_ID: 78 return (memberValue === EMPTY_STRING); 79 case SECRET_VALUE: 80 return (memberValue instanceof asn1js.Any); 81 default: 82 return super.defaultValues(memberName); 83 } 84 } 85 86 /** 87 * @inheritdoc 88 * @asn ASN.1 schema 89 * ```asn 90 * SecretBag ::= SEQUENCE { 91 * secretTypeId BAG-TYPE.&id ({SecretTypes}), 92 * secretValue [0] EXPLICIT BAG-TYPE.&Type ({SecretTypes}{@secretTypeId}) 93 * } 94 *``` 95 */ 96 public static override schema(parameters: Schema.SchemaParameters<{ 97 id?: string; 98 value?: string; 99 }> = {}): Schema.SchemaType { 100 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 101 102 return (new asn1js.Sequence({ 103 name: (names.blockName || EMPTY_STRING), 104 value: [ 105 new asn1js.ObjectIdentifier({ name: (names.id || "id") }), 106 new asn1js.Constructed({ 107 idBlock: { 108 tagClass: 3, // CONTEXT-SPECIFIC 109 tagNumber: 0 // [0] 110 }, 111 value: [new asn1js.Any({ name: (names.value || "value") })] // EXPLICIT ANY value 112 }) 113 ] 114 })); 115 } 116 117 public fromSchema(schema: Schema.SchemaType): void { 118 // Clear input data first 119 pvutils.clearProps(schema, CLEAR_PROPS); 120 121 // Check the schema is valid 122 const asn1 = asn1js.compareSchema(schema, 123 schema, 124 SecretBag.schema({ 125 names: { 126 id: SECRET_TYPE_ID, 127 value: SECRET_VALUE 128 } 129 }) 130 ); 131 AsnError.assertSchema(asn1, this.className); 132 133 // Get internal properties from parsed schema 134 this.secretTypeId = asn1.result.secretTypeId.valueBlock.toString(); 135 this.secretValue = asn1.result.secretValue; 136 } 137 138 public toSchema(): asn1js.Sequence { 139 // Construct and return new ASN.1 schema for this object 140 return (new asn1js.Sequence({ 141 value: [ 142 new asn1js.ObjectIdentifier({ value: this.secretTypeId }), 143 new asn1js.Constructed({ 144 idBlock: { 145 tagClass: 3, // CONTEXT-SPECIFIC 146 tagNumber: 0 // [0] 147 }, 148 value: [this.secretValue.toSchema()] 149 }) 150 ] 151 })); 152 } 153 154 public toJSON(): SecretBagJson { 155 return { 156 secretTypeId: this.secretTypeId, 157 secretValue: this.secretValue.toJSON() 158 }; 159 } 160 161 }