tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NameConstraints.ts (5822B)


      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 { GeneralSubtree, GeneralSubtreeJson } from "./GeneralSubtree";
      6 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      7 import * as Schema from "./Schema";
      8 
      9 const PERMITTED_SUBTREES = "permittedSubtrees";
     10 const EXCLUDED_SUBTREES = "excludedSubtrees";
     11 const CLEAR_PROPS = [
     12  PERMITTED_SUBTREES,
     13  EXCLUDED_SUBTREES
     14 ];
     15 
     16 export interface INameConstraints {
     17  permittedSubtrees?: GeneralSubtree[];
     18  excludedSubtrees?: GeneralSubtree[];
     19 }
     20 
     21 export interface NameConstraintsJson {
     22  permittedSubtrees?: GeneralSubtreeJson[];
     23  excludedSubtrees?: GeneralSubtreeJson[];
     24 }
     25 
     26 export type NameConstraintsParameters = PkiObjectParameters & Partial<INameConstraints>;
     27 
     28 /**
     29 * Represents the NameConstraints structure described in [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280)
     30 */
     31 export class NameConstraints extends PkiObject implements INameConstraints {
     32 
     33  public static override CLASS_NAME = "NameConstraints";
     34 
     35  public permittedSubtrees?: GeneralSubtree[];
     36  public excludedSubtrees?: GeneralSubtree[];
     37 
     38  /**
     39   * Initializes a new instance of the {@link NameConstraints} class
     40   * @param parameters Initialization parameters
     41   */
     42  constructor(parameters: NameConstraintsParameters = {}) {
     43    super();
     44 
     45    if (PERMITTED_SUBTREES in parameters) {
     46      this.permittedSubtrees = pvutils.getParametersValue(parameters, PERMITTED_SUBTREES, NameConstraints.defaultValues(PERMITTED_SUBTREES));
     47    }
     48    if (EXCLUDED_SUBTREES in parameters) {
     49      this.excludedSubtrees = pvutils.getParametersValue(parameters, EXCLUDED_SUBTREES, NameConstraints.defaultValues(EXCLUDED_SUBTREES));
     50    }
     51 
     52    if (parameters.schema) {
     53      this.fromSchema(parameters.schema);
     54    }
     55  }
     56 
     57  /**
     58   * Returns default values for all class members
     59   * @param memberName String name for a class member
     60   * @returns Default value
     61   */
     62  public static override defaultValues(memberName: typeof PERMITTED_SUBTREES): GeneralSubtree[];
     63  public static override defaultValues(memberName: typeof EXCLUDED_SUBTREES): GeneralSubtree[];
     64  public static override defaultValues(memberName: string): any {
     65    switch (memberName) {
     66      case PERMITTED_SUBTREES:
     67      case EXCLUDED_SUBTREES:
     68        return [];
     69      default:
     70        return super.defaultValues(memberName);
     71    }
     72  }
     73 
     74  /**
     75   * @inheritdoc
     76   * @asn ASN.1 schema
     77   * ```asn
     78   * NameConstraints ::= SEQUENCE {
     79   *    permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
     80   *    excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
     81   *```
     82   */
     83  public static override schema(parameters: Schema.SchemaParameters<{
     84    permittedSubtrees?: string;
     85    excludedSubtrees?: string;
     86  }> = {}): Schema.SchemaType {
     87    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
     88 
     89    return (new asn1js.Sequence({
     90      name: (names.blockName || EMPTY_STRING),
     91      value: [
     92        new asn1js.Constructed({
     93          optional: true,
     94          idBlock: {
     95            tagClass: 3, // CONTEXT-SPECIFIC
     96            tagNumber: 0 // [0]
     97          },
     98          value: [
     99            new asn1js.Repeated({
    100              name: (names.permittedSubtrees || EMPTY_STRING),
    101              value: GeneralSubtree.schema()
    102            })
    103          ]
    104        }),
    105        new asn1js.Constructed({
    106          optional: true,
    107          idBlock: {
    108            tagClass: 3, // CONTEXT-SPECIFIC
    109            tagNumber: 1 // [1]
    110          },
    111          value: [
    112            new asn1js.Repeated({
    113              name: (names.excludedSubtrees || EMPTY_STRING),
    114              value: GeneralSubtree.schema()
    115            })
    116          ]
    117        })
    118      ]
    119    }));
    120  }
    121 
    122  public fromSchema(schema: Schema.SchemaType): void {
    123    // Clear input data first
    124    pvutils.clearProps(schema, CLEAR_PROPS);
    125 
    126    // Check the schema is valid
    127    const asn1 = asn1js.compareSchema(schema,
    128      schema,
    129      NameConstraints.schema({
    130        names: {
    131          permittedSubtrees: PERMITTED_SUBTREES,
    132          excludedSubtrees: EXCLUDED_SUBTREES
    133        }
    134      })
    135    );
    136    AsnError.assertSchema(asn1, this.className);
    137 
    138    // Get internal properties from parsed schema
    139    if (PERMITTED_SUBTREES in asn1.result)
    140      this.permittedSubtrees = Array.from(asn1.result.permittedSubtrees, element => new GeneralSubtree({ schema: element }));
    141    if (EXCLUDED_SUBTREES in asn1.result)
    142      this.excludedSubtrees = Array.from(asn1.result.excludedSubtrees, element => new GeneralSubtree({ schema: element }));
    143  }
    144 
    145  public toSchema(): asn1js.Sequence {
    146    //#region Create array for output sequence
    147    const outputArray = [];
    148 
    149    if (this.permittedSubtrees) {
    150      outputArray.push(new asn1js.Constructed({
    151        idBlock: {
    152          tagClass: 3, // CONTEXT-SPECIFIC
    153          tagNumber: 0 // [0]
    154        },
    155        value: Array.from(this.permittedSubtrees, o => o.toSchema())
    156      }));
    157    }
    158 
    159    if (this.excludedSubtrees) {
    160      outputArray.push(new asn1js.Constructed({
    161        idBlock: {
    162          tagClass: 3, // CONTEXT-SPECIFIC
    163          tagNumber: 1 // [1]
    164        },
    165        value: Array.from(this.excludedSubtrees, o => o.toSchema())
    166      }));
    167    }
    168    //#endregion
    169 
    170    //#region Construct and return new ASN.1 schema for this object
    171    return (new asn1js.Sequence({
    172      value: outputArray
    173    }));
    174    //#endregion
    175  }
    176 
    177  public toJSON(): NameConstraintsJson {
    178    const object: NameConstraintsJson = {};
    179 
    180    if (this.permittedSubtrees) {
    181      object.permittedSubtrees = Array.from(this.permittedSubtrees, o => o.toJSON());
    182    }
    183 
    184    if (this.excludedSubtrees) {
    185      object.excludedSubtrees = Array.from(this.excludedSubtrees, o => o.toJSON());
    186    }
    187 
    188    return object;
    189  }
    190 
    191 }