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