tor-browser

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

MacData.ts (5691B)


      1 import * as asn1js from "asn1js";
      2 import * as pvutils from "pvutils";
      3 import { EMPTY_STRING } from "./constants";
      4 import { DigestInfo, DigestInfoJson, DigestInfoSchema } from "./DigestInfo";
      5 import { AsnError } from "./errors";
      6 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      7 import * as Schema from "./Schema";
      8 
      9 const MAC = "mac";
     10 const MAC_SALT = "macSalt";
     11 const ITERATIONS = "iterations";
     12 const CLEAR_PROPS = [
     13  MAC,
     14  MAC_SALT,
     15  ITERATIONS
     16 ];
     17 
     18 export interface IMacData {
     19  mac: DigestInfo;
     20  macSalt: asn1js.OctetString;
     21  iterations?: number;
     22 }
     23 
     24 export interface MacDataJson {
     25  mac: DigestInfoJson;
     26  macSalt: asn1js.OctetStringJson;
     27  iterations?: number;
     28 }
     29 
     30 export type MacDataParameters = PkiObjectParameters & Partial<IMacData>;
     31 
     32 export type MacDataSchema = Schema.SchemaParameters<{
     33  mac?: DigestInfoSchema;
     34  macSalt?: string;
     35  iterations?: string;
     36 }>;
     37 
     38 /**
     39 * Represents the MacData structure described in [RFC7292](https://datatracker.ietf.org/doc/html/rfc7292)
     40 */
     41 export class MacData extends PkiObject implements IMacData {
     42 
     43  public static override CLASS_NAME = "MacData";
     44 
     45  public mac!: DigestInfo;
     46  public macSalt!: asn1js.OctetString;
     47  public iterations?: number;
     48 
     49  /**
     50   * Initializes a new instance of the {@link MacData} class
     51   * @param parameters Initialization parameters
     52   */
     53  constructor(parameters: MacDataParameters = {}) {
     54    super();
     55 
     56    this.mac = pvutils.getParametersValue(parameters, MAC, MacData.defaultValues(MAC));
     57    this.macSalt = pvutils.getParametersValue(parameters, MAC_SALT, MacData.defaultValues(MAC_SALT));
     58    if (ITERATIONS in parameters) {
     59      this.iterations = pvutils.getParametersValue(parameters, ITERATIONS, MacData.defaultValues(ITERATIONS));
     60    }
     61 
     62    if (parameters.schema) {
     63      this.fromSchema(parameters.schema);
     64    }
     65  }
     66 
     67  /**
     68   * Returns default values for all class members
     69   * @param memberName String name for a class member
     70   * @returns Default value
     71   */
     72  public static override defaultValues(memberName: typeof MAC): DigestInfo;
     73  public static override defaultValues(memberName: typeof MAC_SALT): asn1js.OctetString;
     74  public static override defaultValues(memberName: typeof ITERATIONS): number;
     75  public static override defaultValues(memberName: string): any {
     76    switch (memberName) {
     77      case MAC:
     78        return new DigestInfo();
     79      case MAC_SALT:
     80        return new asn1js.OctetString();
     81      case ITERATIONS:
     82        return 1;
     83      default:
     84        return super.defaultValues(memberName);
     85    }
     86  }
     87 
     88  /**
     89   * Compare 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  public static compareWithDefault(memberName: string, memberValue: any): boolean {
     94    switch (memberName) {
     95      case MAC:
     96        return ((DigestInfo.compareWithDefault("digestAlgorithm", memberValue.digestAlgorithm)) &&
     97          (DigestInfo.compareWithDefault("digest", memberValue.digest)));
     98      case MAC_SALT:
     99        return (memberValue.isEqual(MacData.defaultValues(memberName)));
    100      case ITERATIONS:
    101        return (memberValue === MacData.defaultValues(memberName));
    102      default:
    103        return super.defaultValues(memberName);
    104    }
    105  }
    106 
    107  /**
    108   * @inheritdoc
    109   * @asn ASN.1 schema
    110   * ```asn
    111   * MacData ::= SEQUENCE {
    112   *    mac           DigestInfo,
    113   *    macSalt       OCTET STRING,
    114   *    iterations    INTEGER DEFAULT 1
    115   *    -- Note: The default is for historical reasons and its use is
    116   *    -- deprecated. A higher value, like 1024 is recommended.
    117   *    }
    118   *```
    119   */
    120  public static override schema(parameters: MacDataSchema = {}): Schema.SchemaType {
    121    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    122 
    123    return (new asn1js.Sequence({
    124      name: (names.blockName || EMPTY_STRING),
    125      optional: (names.optional || true),
    126      value: [
    127        DigestInfo.schema(names.mac || {
    128          names: {
    129            blockName: MAC
    130          }
    131        }),
    132        new asn1js.OctetString({ name: (names.macSalt || MAC_SALT) }),
    133        new asn1js.Integer({
    134          optional: true,
    135          name: (names.iterations || ITERATIONS)
    136        })
    137      ]
    138    }));
    139  }
    140 
    141  public fromSchema(schema: Schema.SchemaType): void {
    142    // Clear input data first
    143    pvutils.clearProps(schema, CLEAR_PROPS);
    144 
    145    // Check the schema is valid
    146    const asn1 = asn1js.compareSchema(schema,
    147      schema,
    148      MacData.schema({
    149        names: {
    150          mac: {
    151            names: {
    152              blockName: MAC
    153            }
    154          },
    155          macSalt: MAC_SALT,
    156          iterations: ITERATIONS
    157        }
    158      })
    159    );
    160    AsnError.assertSchema(asn1, this.className);
    161 
    162    // Get internal properties from parsed schema
    163    this.mac = new DigestInfo({ schema: asn1.result.mac });
    164    this.macSalt = asn1.result.macSalt;
    165    if (ITERATIONS in asn1.result)
    166      this.iterations = asn1.result.iterations.valueBlock.valueDec;
    167  }
    168 
    169  public toSchema(): asn1js.Sequence {
    170    //#region Construct and return new ASN.1 schema for this object
    171    const outputArray: any[] = [
    172      this.mac.toSchema(),
    173      this.macSalt
    174    ];
    175 
    176    if (this.iterations !== undefined) {
    177      outputArray.push(new asn1js.Integer({ value: this.iterations }));
    178    }
    179 
    180    return (new asn1js.Sequence({
    181      value: outputArray
    182    }));
    183    //#endregion
    184  }
    185 
    186  public toJSON(): MacDataJson {
    187    const res: MacDataJson = {
    188      mac: this.mac.toJSON(),
    189      macSalt: this.macSalt.toJSON(),
    190    };
    191 
    192    if (this.iterations !== undefined) {
    193      res.iterations = this.iterations;
    194    }
    195 
    196    return res;
    197  }
    198 
    199 }