tor-browser

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

AlgorithmIdentifier.ts (6070B)


      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 ALGORITHM_ID = "algorithmId";
      9 const ALGORITHM_PARAMS = "algorithmParams";
     10 const ALGORITHM = "algorithm";
     11 const PARAMS = "params";
     12 const CLEAR_PROPS = [
     13  ALGORITHM,
     14  PARAMS
     15 ];
     16 
     17 export interface IAlgorithmIdentifier {
     18  /**
     19   * ObjectIdentifier for algorithm (string representation)
     20   */
     21  algorithmId: string;
     22  /**
     23   * Any algorithm parameters
     24   */
     25  algorithmParams?: any;
     26 }
     27 
     28 export type AlgorithmIdentifierParameters = PkiObjectParameters & Partial<IAlgorithmIdentifier>;
     29 
     30 /**
     31 * JSON representation of {@link AlgorithmIdentifier}
     32 */
     33 export interface AlgorithmIdentifierJson {
     34  algorithmId: string;
     35  algorithmParams?: any;
     36 }
     37 
     38 export type AlgorithmIdentifierSchema = Schema.SchemaParameters<{
     39  algorithmIdentifier?: string;
     40  algorithmParams?: string;
     41 }>;
     42 
     43 /**
     44 * Represents the AlgorithmIdentifier structure described in [RFC5280](https://datatracker.ietf.org/doc/html/rfc5280)
     45 */
     46 export class AlgorithmIdentifier extends PkiObject implements IAlgorithmIdentifier {
     47 
     48  public static override CLASS_NAME = "AlgorithmIdentifier";
     49 
     50  public algorithmId!: string;
     51  public algorithmParams?: any;
     52 
     53  /**
     54   * Initializes a new instance of the {@link AlgorithmIdentifier} class
     55   * @param parameters Initialization parameters
     56   */
     57  constructor(parameters: AlgorithmIdentifierParameters = {}) {
     58    super();
     59 
     60    this.algorithmId = pvutils.getParametersValue(parameters, ALGORITHM_ID, AlgorithmIdentifier.defaultValues(ALGORITHM_ID));
     61    if (ALGORITHM_PARAMS in parameters) {
     62      this.algorithmParams = pvutils.getParametersValue(parameters, ALGORITHM_PARAMS, AlgorithmIdentifier.defaultValues(ALGORITHM_PARAMS));
     63    }
     64 
     65    if (parameters.schema) {
     66      this.fromSchema(parameters.schema);
     67    }
     68  }
     69 
     70  /**
     71   * Returns default values for all class members
     72   * @param memberName String name for a class member
     73   * @returns Default value
     74   */
     75  public static override defaultValues(memberName: typeof ALGORITHM_ID): string;
     76  public static override defaultValues(memberName: typeof ALGORITHM_PARAMS): any;
     77  public static override defaultValues(memberName: string): any {
     78    switch (memberName) {
     79      case ALGORITHM_ID:
     80        return EMPTY_STRING;
     81      case ALGORITHM_PARAMS:
     82        return new asn1js.Any();
     83      default:
     84        return super.defaultValues(memberName);
     85    }
     86  }
     87 
     88  /**
     89   * Compares values with default values for all class members
     90   * @param memberName String name for a class member
     91   * @param memberValue Value to compare with default value
     92   */
     93  static compareWithDefault(memberName: string, memberValue: any): boolean {
     94    switch (memberName) {
     95      case ALGORITHM_ID:
     96        return (memberValue === EMPTY_STRING);
     97      case ALGORITHM_PARAMS:
     98        return (memberValue instanceof asn1js.Any);
     99      default:
    100        return super.defaultValues(memberName);
    101    }
    102  }
    103 
    104  /**
    105   * @inheritdoc
    106   * @asn ASN.1 schema
    107   * ```asn
    108   * AlgorithmIdentifier ::= Sequence  {
    109   *    algorithm               OBJECT IDENTIFIER,
    110   *    parameters              ANY DEFINED BY algorithm OPTIONAL  }
    111   *```
    112   */
    113  public static override schema(parameters: AlgorithmIdentifierSchema = {}): any {
    114    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    115 
    116    return (new asn1js.Sequence({
    117      name: (names.blockName || EMPTY_STRING),
    118      optional: (names.optional || false),
    119      value: [
    120        new asn1js.ObjectIdentifier({ name: (names.algorithmIdentifier || EMPTY_STRING) }),
    121        new asn1js.Any({ name: (names.algorithmParams || EMPTY_STRING), optional: true })
    122      ]
    123    }));
    124  }
    125 
    126  public fromSchema(schema: Schema.SchemaType): void {
    127    // Clear input data first
    128    pvutils.clearProps(schema, CLEAR_PROPS);
    129 
    130    // Check the schema is valid
    131    const asn1 = asn1js.compareSchema(schema,
    132      schema,
    133      AlgorithmIdentifier.schema({
    134        names: {
    135          algorithmIdentifier: ALGORITHM,
    136          algorithmParams: PARAMS
    137        }
    138      })
    139    );
    140    AsnError.assertSchema(asn1, this.className);
    141 
    142    // Get internal properties from parsed schema
    143    this.algorithmId = asn1.result.algorithm.valueBlock.toString();
    144    if (PARAMS in asn1.result) {
    145      this.algorithmParams = asn1.result.params;
    146    }
    147  }
    148 
    149  public toSchema(): asn1js.Sequence {
    150    // Create array for output sequence
    151    const outputArray = [];
    152    outputArray.push(new asn1js.ObjectIdentifier({ value: this.algorithmId }));
    153    if (this.algorithmParams && !(this.algorithmParams instanceof asn1js.Any)) {
    154      outputArray.push(this.algorithmParams);
    155    }
    156 
    157    // Construct and return new ASN.1 schema for this object
    158    return (new asn1js.Sequence({
    159      value: outputArray
    160    }));
    161  }
    162 
    163  public toJSON(): AlgorithmIdentifierJson {
    164    const object: AlgorithmIdentifierJson = {
    165      algorithmId: this.algorithmId
    166    };
    167 
    168    if (this.algorithmParams && !(this.algorithmParams instanceof asn1js.Any)) {
    169      object.algorithmParams = this.algorithmParams.toJSON();
    170    }
    171 
    172    return object;
    173  }
    174 
    175  /**
    176   * Checks that two "AlgorithmIdentifiers" are equal
    177   * @param algorithmIdentifier
    178   */
    179  public isEqual(algorithmIdentifier: unknown): boolean {
    180    //#region Check input type
    181    if (!(algorithmIdentifier instanceof AlgorithmIdentifier)) {
    182      return false;
    183    }
    184    //#endregion
    185 
    186    //#region Check "algorithm_id"
    187    if (this.algorithmId !== algorithmIdentifier.algorithmId) {
    188      return false;
    189    }
    190    //#endregion
    191 
    192    //#region Check "algorithm_params"
    193    if (this.algorithmParams) {
    194      if (algorithmIdentifier.algorithmParams) {
    195        return JSON.stringify(this.algorithmParams) === JSON.stringify(algorithmIdentifier.algorithmParams);
    196      }
    197 
    198      return false;
    199    }
    200 
    201    if (algorithmIdentifier.algorithmParams) {
    202      return false;
    203    }
    204    //#endregion
    205 
    206    return true;
    207  }
    208 
    209 }