tor-browser

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

Request.ts (5842B)


      1 import * as asn1js from "asn1js";
      2 import * as pvutils from "pvutils";
      3 import { CertID, CertIDJson, CertIDSchema } from "./CertID";
      4 import { EMPTY_STRING } from "./constants";
      5 import { AsnError } from "./errors";
      6 import { Extension, ExtensionJson } from "./Extension";
      7 import { Extensions, ExtensionsSchema } from "./Extensions";
      8 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      9 import * as Schema from "./Schema";
     10 
     11 const REQ_CERT = "reqCert";
     12 const SINGLE_REQUEST_EXTENSIONS = "singleRequestExtensions";
     13 const CLEAR_PROPS = [
     14  REQ_CERT,
     15  SINGLE_REQUEST_EXTENSIONS,
     16 ];
     17 
     18 export interface IRequest {
     19  reqCert: CertID;
     20  singleRequestExtensions?: Extension[];
     21 }
     22 
     23 export interface RequestJson {
     24  reqCert: CertIDJson;
     25  singleRequestExtensions?: ExtensionJson[];
     26 }
     27 
     28 export type RequestParameters = PkiObjectParameters & Partial<IRequest>;
     29 
     30 export type RequestSchema = Schema.SchemaParameters<{
     31  reqCert?: CertIDSchema;
     32  extensions?: ExtensionsSchema;
     33  singleRequestExtensions?: string;
     34 }>;
     35 
     36 /**
     37 * Represents an Request described in [RFC6960](https://datatracker.ietf.org/doc/html/rfc6960)
     38 */
     39 export class Request extends PkiObject implements IRequest {
     40 
     41  public static override CLASS_NAME = "Request";
     42 
     43  public reqCert!: CertID;
     44  public singleRequestExtensions?: Extension[];
     45 
     46  /**
     47   * Initializes a new instance of the {@link Request} class
     48   * @param parameters Initialization parameters
     49   */
     50  constructor(parameters: RequestParameters = {}) {
     51    super();
     52 
     53    this.reqCert = pvutils.getParametersValue(parameters, REQ_CERT, Request.defaultValues(REQ_CERT));
     54    if (SINGLE_REQUEST_EXTENSIONS in parameters) {
     55      this.singleRequestExtensions = pvutils.getParametersValue(parameters, SINGLE_REQUEST_EXTENSIONS, Request.defaultValues(SINGLE_REQUEST_EXTENSIONS));
     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 REQ_CERT): CertID;
     69  public static override defaultValues(memberName: typeof SINGLE_REQUEST_EXTENSIONS): Extension[];
     70  public static override defaultValues(memberName: string): any {
     71    switch (memberName) {
     72      case REQ_CERT:
     73        return new CertID();
     74      case SINGLE_REQUEST_EXTENSIONS:
     75        return [];
     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 REQ_CERT:
     89        return (memberValue.isEqual(Request.defaultValues(memberName)));
     90      case SINGLE_REQUEST_EXTENSIONS:
     91        return (memberValue.length === 0);
     92      default:
     93        return super.defaultValues(memberName);
     94    }
     95  }
     96 
     97  /**
     98   * @inheritdoc
     99   * @asn ASN.1 schema
    100   * ```asn
    101   * Request ::= SEQUENCE {
    102   *    reqCert                     CertID,
    103   *    singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
    104   *```
    105   */
    106  public static override schema(parameters: RequestSchema = {}): Schema.SchemaType {
    107    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    108 
    109    return (new asn1js.Sequence({
    110      name: (names.blockName || EMPTY_STRING),
    111      value: [
    112        CertID.schema(names.reqCert || {}),
    113        new asn1js.Constructed({
    114          optional: true,
    115          idBlock: {
    116            tagClass: 3, // CONTEXT-SPECIFIC
    117            tagNumber: 0 // [0]
    118          },
    119          value: [Extensions.schema(names.extensions || {
    120            names: {
    121              blockName: (names.singleRequestExtensions || EMPTY_STRING)
    122            }
    123          })]
    124        })
    125      ]
    126    }));
    127  }
    128 
    129  public fromSchema(schema: Schema.SchemaType): void {
    130    // Clear input data first
    131    pvutils.clearProps(schema, CLEAR_PROPS);
    132 
    133    // Check the schema is valid
    134    const asn1 = asn1js.compareSchema(schema,
    135      schema,
    136      Request.schema({
    137        names: {
    138          reqCert: {
    139            names: {
    140              blockName: REQ_CERT
    141            }
    142          },
    143          extensions: {
    144            names: {
    145              blockName: SINGLE_REQUEST_EXTENSIONS
    146            }
    147          }
    148        }
    149      })
    150    );
    151    AsnError.assertSchema(asn1, this.className);
    152 
    153    // Get internal properties from parsed schema
    154    this.reqCert = new CertID({ schema: asn1.result.reqCert });
    155    if (SINGLE_REQUEST_EXTENSIONS in asn1.result) {
    156      this.singleRequestExtensions = Array.from(asn1.result.singleRequestExtensions.valueBlock.value, element => new Extension({ schema: element }));
    157    }
    158  }
    159 
    160  public toSchema(): asn1js.Sequence {
    161    //#region Create array for output sequence
    162    const outputArray = [];
    163 
    164    outputArray.push(this.reqCert.toSchema());
    165 
    166    if (this.singleRequestExtensions) {
    167      outputArray.push(new asn1js.Constructed({
    168        optional: true,
    169        idBlock: {
    170          tagClass: 3, // CONTEXT-SPECIFIC
    171          tagNumber: 0 // [0]
    172        },
    173        value: [
    174          new asn1js.Sequence({
    175            value: Array.from(this.singleRequestExtensions, o => o.toSchema())
    176          })
    177        ]
    178      }));
    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(): RequestJson {
    190    const res: RequestJson = {
    191      reqCert: this.reqCert.toJSON()
    192    };
    193 
    194    if (this.singleRequestExtensions) {
    195      res.singleRequestExtensions = Array.from(this.singleRequestExtensions, o => o.toJSON());
    196    }
    197 
    198    return res;
    199  }
    200 
    201 }