tor-browser

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

QCStatements.ts (7727B)


      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 ID = "id";
      9 const TYPE = "type";
     10 const VALUES = "values";
     11 const QC_STATEMENT_CLEAR_PROPS = [
     12  ID,
     13  TYPE
     14 ];
     15 const QC_STATEMENTS_CLEAR_PROPS = [
     16  VALUES
     17 ];
     18 
     19 export interface IQCStatement {
     20  id: string;
     21  type?: any;
     22 }
     23 
     24 export interface QCStatementJson {
     25  id: string;
     26  type?: any;
     27 }
     28 
     29 export type QCStatementParameters = PkiObjectParameters & Partial<IQCStatement>;
     30 
     31 export type QCStatementSchema = Schema.SchemaParameters<{
     32  id?: string;
     33  type?: string;
     34 }>;
     35 
     36 /**
     37 * Represents the QCStatement structure described in [RFC3739](https://datatracker.ietf.org/doc/html/rfc3739)
     38 */
     39 export class QCStatement extends PkiObject implements IQCStatement {
     40 
     41  public static override CLASS_NAME = "QCStatement";
     42 
     43  public id!: string;
     44  public type?: any;
     45 
     46  /**
     47   * Initializes a new instance of the {@link QCStatement} class
     48   * @param parameters Initialization parameters
     49   */
     50  constructor(parameters: QCStatementParameters = {}) {
     51    super();
     52 
     53    this.id = pvutils.getParametersValue(parameters, ID, QCStatement.defaultValues(ID));
     54    if (TYPE in parameters) {
     55      this.type = pvutils.getParametersValue(parameters, TYPE, QCStatement.defaultValues(TYPE));
     56    }
     57 
     58    if (parameters.schema) {
     59      this.fromSchema(parameters.schema);
     60    }
     61  }
     62 
     63  /**
     64   * Returns default values for all class members
     65   * @param memberName String name for a class member
     66   * @returns Default value
     67   */
     68  public static override defaultValues(memberName: typeof ID): string;
     69  public static override defaultValues(memberName: typeof TYPE): any;
     70  public static override defaultValues(memberName: string): any {
     71    switch (memberName) {
     72      case ID:
     73        return EMPTY_STRING;
     74      case TYPE:
     75        return new asn1js.Null();
     76      default:
     77        return super.defaultValues(memberName);
     78    }
     79  }
     80 
     81  /**
     82   * Compare values with default values for all class members
     83   * @param memberName String name for a class member
     84   * @param memberValue Value to compare with default value
     85   */
     86  public static compareWithDefault(memberName: string, memberValue: any): boolean {
     87    switch (memberName) {
     88      case ID:
     89        return (memberValue === EMPTY_STRING);
     90      case TYPE:
     91        return (memberValue instanceof asn1js.Null);
     92      default:
     93        return super.defaultValues(memberName);
     94    }
     95  }
     96 
     97  /**
     98   * @inheritdoc
     99   * @asn ASN.1 schema
    100   * ```asn
    101   * QCStatement ::= SEQUENCE {
    102   *       statementId   QC-STATEMENT.&id({SupportedStatements}),
    103   *       statementInfo QC-STATEMENT.&Type({SupportedStatements}{@statementId}) OPTIONAL
    104   *   }
    105   *```
    106   */
    107  public static override schema(parameters: QCStatementSchema = {}): Schema.SchemaType {
    108    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    109 
    110    return (new asn1js.Sequence({
    111      name: (names.blockName || EMPTY_STRING),
    112      value: [
    113        new asn1js.ObjectIdentifier({ name: (names.id || EMPTY_STRING) }),
    114        new asn1js.Any({
    115          name: (names.type || EMPTY_STRING),
    116          optional: true
    117        })
    118      ]
    119    }));
    120  }
    121 
    122  public fromSchema(schema: Schema.SchemaType): void {
    123    // Clear input data first
    124    pvutils.clearProps(schema, QC_STATEMENT_CLEAR_PROPS);
    125 
    126    // Check the schema is valid
    127    const asn1 = asn1js.compareSchema(schema,
    128      schema,
    129      QCStatement.schema({
    130        names: {
    131          id: ID,
    132          type: TYPE
    133        }
    134      })
    135    );
    136    AsnError.assertSchema(asn1, this.className);
    137 
    138    // Get internal properties from parsed schema
    139    this.id = asn1.result.id.valueBlock.toString();
    140    if (TYPE in asn1.result)
    141      this.type = asn1.result.type;
    142  }
    143 
    144  public toSchema(): asn1js.Sequence {
    145    const value = [
    146      new asn1js.ObjectIdentifier({ value: this.id })
    147    ];
    148 
    149    if (TYPE in this)
    150      value.push(this.type);
    151 
    152    // Construct and return new ASN.1 schema for this object
    153    return (new asn1js.Sequence({
    154      value,
    155    }));
    156  }
    157 
    158  public toJSON(): QCStatementJson {
    159    const object: any = {
    160      id: this.id
    161    };
    162 
    163    if (this.type) {
    164      object.type = this.type.toJSON();
    165    }
    166 
    167    return object;
    168  }
    169 
    170 }
    171 
    172 export interface IQCStatements {
    173  values: QCStatement[];
    174 }
    175 
    176 export interface QCStatementsJson {
    177  values: QCStatementJson[];
    178 }
    179 
    180 export type QCStatementsParameters = PkiObjectParameters & Partial<IQCStatements>;
    181 
    182 /**
    183 * Represents the QCStatements structure described in [RFC3739](https://datatracker.ietf.org/doc/html/rfc3739)
    184 */
    185 export class QCStatements extends PkiObject implements IQCStatements {
    186 
    187  public static override CLASS_NAME = "QCStatements";
    188 
    189  public values!: QCStatement[];
    190 
    191  /**
    192   * Initializes a new instance of the {@link QCStatement} class
    193   * @param parameters Initialization parameters
    194   */
    195  constructor(parameters: QCStatementParameters = {}) {
    196    super();
    197 
    198    this.values = pvutils.getParametersValue(parameters, VALUES, QCStatements.defaultValues(VALUES));
    199 
    200    if (parameters.schema) {
    201      this.fromSchema(parameters.schema);
    202    }
    203  }
    204 
    205  /**
    206   * Returns default values for all class members
    207   * @param memberName String name for a class member
    208   * @returns Default value
    209   */
    210  public static override defaultValues(memberName: typeof VALUES): QCStatement[];
    211  public static override defaultValues(memberName: string): any {
    212    switch (memberName) {
    213      case VALUES:
    214        return [];
    215      default:
    216        return super.defaultValues(memberName);
    217    }
    218  }
    219 
    220  /**
    221   * Compare values with default values for all class members
    222   * @param memberName String name for a class member
    223   * @param memberValue Value to compare with default value
    224   */
    225  public static compareWithDefault(memberName: string, memberValue: any): boolean {
    226    switch (memberName) {
    227      case VALUES:
    228        return (memberValue.length === 0);
    229      default:
    230        return super.defaultValues(memberName);
    231    }
    232  }
    233 
    234  /**
    235   * @inheritdoc
    236   * @asn ASN.1 schema
    237   * ```asn
    238   * QCStatements ::= SEQUENCE OF QCStatement
    239   *```
    240   */
    241  public static override schema(parameters: Schema.SchemaParameters<{
    242    values?: string;
    243    value?: QCStatementSchema;
    244  }> = {}): Schema.SchemaType {
    245    /**
    246     * @type {Object}
    247     * @property {string} [blockName]
    248     * @property {string} [values]
    249     */
    250    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    251 
    252    return (new asn1js.Sequence({
    253      name: (names.blockName || EMPTY_STRING),
    254      value: [
    255        new asn1js.Repeated({
    256          name: (names.values || EMPTY_STRING),
    257          value: QCStatement.schema(names.value || {})
    258        }),
    259      ]
    260    }));
    261  }
    262 
    263  public fromSchema(schema: Schema.SchemaType): void {
    264    // Clear input data first
    265    pvutils.clearProps(schema, QC_STATEMENTS_CLEAR_PROPS);
    266 
    267    // Check the schema is valid
    268    const asn1 = asn1js.compareSchema(schema,
    269      schema,
    270      QCStatements.schema({
    271        names: {
    272          values: VALUES
    273        }
    274      })
    275    );
    276    AsnError.assertSchema(asn1, this.className);
    277 
    278    // Get internal properties from parsed schema
    279    this.values = Array.from(asn1.result.values, element => new QCStatement({ schema: element }));
    280  }
    281 
    282  public toSchema(): asn1js.Sequence {
    283    // Construct and return new ASN.1 schema for this object
    284    return (new asn1js.Sequence({
    285      value: Array.from(this.values, o => o.toSchema())
    286    }));
    287  }
    288 
    289  public toJSON(): QCStatementsJson {
    290    return {
    291      values: Array.from(this.values, o => o.toJSON())
    292    };
    293  }
    294 
    295 }