PolicyConstraints.ts (6144B)
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 REQUIRE_EXPLICIT_POLICY = "requireExplicitPolicy"; 9 const INHIBIT_POLICY_MAPPING = "inhibitPolicyMapping"; 10 const CLEAR_PROPS = [ 11 REQUIRE_EXPLICIT_POLICY, 12 INHIBIT_POLICY_MAPPING, 13 ]; 14 15 export interface IPolicyConstraints { 16 requireExplicitPolicy?: number; 17 inhibitPolicyMapping?: number; 18 } 19 20 export interface PolicyConstraintsJson { 21 requireExplicitPolicy?: number; 22 inhibitPolicyMapping?: number; 23 } 24 25 export type PolicyConstraintsParameters = PkiObjectParameters & Partial<IPolicyConstraints>; 26 27 /** 28 * Represents the PolicyConstraints structure described in [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280) 29 */ 30 export class PolicyConstraints extends PkiObject implements IPolicyConstraints { 31 32 public static override CLASS_NAME = "PolicyConstraints"; 33 34 public requireExplicitPolicy?: number; 35 public inhibitPolicyMapping?: number; 36 37 /** 38 * Initializes a new instance of the {@link PolicyConstraints} class 39 * @param parameters Initialization parameters 40 */ 41 constructor(parameters: PolicyConstraintsParameters = {}) { 42 super(); 43 44 if (REQUIRE_EXPLICIT_POLICY in parameters) { 45 this.requireExplicitPolicy = pvutils.getParametersValue(parameters, REQUIRE_EXPLICIT_POLICY, PolicyConstraints.defaultValues(REQUIRE_EXPLICIT_POLICY)); 46 } 47 if (INHIBIT_POLICY_MAPPING in parameters) { 48 this.inhibitPolicyMapping = pvutils.getParametersValue(parameters, INHIBIT_POLICY_MAPPING, PolicyConstraints.defaultValues(INHIBIT_POLICY_MAPPING)); 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 REQUIRE_EXPLICIT_POLICY): number; 62 public static override defaultValues(memberName: typeof INHIBIT_POLICY_MAPPING): number; 63 public static override defaultValues(memberName: string): any { 64 switch (memberName) { 65 case REQUIRE_EXPLICIT_POLICY: 66 return 0; 67 case INHIBIT_POLICY_MAPPING: 68 return 0; 69 default: 70 return super.defaultValues(memberName); 71 } 72 } 73 74 /** 75 * @inheritdoc 76 * @asn ASN.1 schema 77 * ```asn 78 * PolicyConstraints ::= SEQUENCE { 79 * requireExplicitPolicy [0] SkipCerts OPTIONAL, 80 * inhibitPolicyMapping [1] SkipCerts OPTIONAL } 81 * 82 * SkipCerts ::= INTEGER (0..MAX) 83 *``` 84 */ 85 public static override schema(parameters: Schema.SchemaParameters<{ 86 requireExplicitPolicy?: string; 87 inhibitPolicyMapping?: string; 88 }> = {}): Schema.SchemaType { 89 const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {}); 90 91 return (new asn1js.Sequence({ 92 name: (names.blockName || EMPTY_STRING), 93 value: [ 94 new asn1js.Primitive({ 95 name: (names.requireExplicitPolicy || EMPTY_STRING), 96 optional: true, 97 idBlock: { 98 tagClass: 3, // CONTEXT-SPECIFIC 99 tagNumber: 0 // [0] 100 } 101 }), // IMPLICIT integer value 102 new asn1js.Primitive({ 103 name: (names.inhibitPolicyMapping || EMPTY_STRING), 104 optional: true, 105 idBlock: { 106 tagClass: 3, // CONTEXT-SPECIFIC 107 tagNumber: 1 // [1] 108 } 109 }) // IMPLICIT integer value 110 ] 111 })); 112 } 113 114 public fromSchema(schema: Schema.SchemaType): void { 115 // Clear input data first 116 pvutils.clearProps(schema, CLEAR_PROPS); 117 118 // Check the schema is valid 119 const asn1 = asn1js.compareSchema(schema, 120 schema, 121 PolicyConstraints.schema({ 122 names: { 123 requireExplicitPolicy: REQUIRE_EXPLICIT_POLICY, 124 inhibitPolicyMapping: INHIBIT_POLICY_MAPPING 125 } 126 }) 127 ); 128 AsnError.assertSchema(asn1, this.className); 129 130 //#region Get internal properties from parsed schema 131 if (REQUIRE_EXPLICIT_POLICY in asn1.result) { 132 const field1 = asn1.result.requireExplicitPolicy; 133 134 field1.idBlock.tagClass = 1; // UNIVERSAL 135 field1.idBlock.tagNumber = 2; // INTEGER 136 137 const ber1 = field1.toBER(false); 138 const int1 = asn1js.fromBER(ber1); 139 AsnError.assert(int1, "Integer"); 140 141 this.requireExplicitPolicy = (int1.result as asn1js.Integer).valueBlock.valueDec; 142 } 143 144 if (INHIBIT_POLICY_MAPPING in asn1.result) { 145 const field2 = asn1.result.inhibitPolicyMapping; 146 147 field2.idBlock.tagClass = 1; // UNIVERSAL 148 field2.idBlock.tagNumber = 2; // INTEGER 149 150 const ber2 = field2.toBER(false); 151 const int2 = asn1js.fromBER(ber2); 152 AsnError.assert(int2, "Integer"); 153 154 this.inhibitPolicyMapping = (int2.result as asn1js.Integer).valueBlock.valueDec; 155 } 156 //#endregion 157 } 158 159 public toSchema(): asn1js.Sequence { 160 //#region Create correct values for output sequence 161 const outputArray = []; 162 163 if (REQUIRE_EXPLICIT_POLICY in this) { 164 const int1 = new asn1js.Integer({ value: this.requireExplicitPolicy }); 165 166 int1.idBlock.tagClass = 3; // CONTEXT-SPECIFIC 167 int1.idBlock.tagNumber = 0; // [0] 168 169 outputArray.push(int1); 170 } 171 172 if (INHIBIT_POLICY_MAPPING in this) { 173 const int2 = new asn1js.Integer({ value: this.inhibitPolicyMapping }); 174 175 int2.idBlock.tagClass = 3; // CONTEXT-SPECIFIC 176 int2.idBlock.tagNumber = 1; // [1] 177 178 outputArray.push(int2); 179 } 180 //#endregion 181 182 //#region Construct and return new ASN.1 schema for this object 183 return (new asn1js.Sequence({ 184 value: outputArray 185 })); 186 //#endregion 187 } 188 189 public toJSON(): PolicyConstraintsJson { 190 const res: PolicyConstraintsJson = {}; 191 192 if (REQUIRE_EXPLICIT_POLICY in this) { 193 res.requireExplicitPolicy = this.requireExplicitPolicy; 194 } 195 196 if (INHIBIT_POLICY_MAPPING in this) { 197 res.inhibitPolicyMapping = this.inhibitPolicyMapping; 198 } 199 200 return res; 201 } 202 203 }