tor-browser

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

RSASSAPSSParams.ts (8951B)


      1 import * as asn1js from "asn1js";
      2 import * as pvutils from "pvutils";
      3 import { AlgorithmIdentifier, AlgorithmIdentifierJson, AlgorithmIdentifierSchema } from "./AlgorithmIdentifier";
      4 import { EMPTY_STRING } from "./constants";
      5 import { AsnError } from "./errors";
      6 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      7 import * as Schema from "./Schema";
      8 
      9 const HASH_ALGORITHM = "hashAlgorithm";
     10 const MASK_GEN_ALGORITHM = "maskGenAlgorithm";
     11 const SALT_LENGTH = "saltLength";
     12 const TRAILER_FIELD = "trailerField";
     13 const CLEAR_PROPS = [
     14  HASH_ALGORITHM,
     15  MASK_GEN_ALGORITHM,
     16  SALT_LENGTH,
     17  TRAILER_FIELD
     18 ];
     19 
     20 export interface IRSASSAPSSParams {
     21  /**
     22   * Algorithms of hashing (DEFAULT sha1)
     23   */
     24  hashAlgorithm: AlgorithmIdentifier;
     25  /**
     26   * Salt length (DEFAULT 20)
     27   */
     28  maskGenAlgorithm: AlgorithmIdentifier;
     29  /**
     30   * Salt length (DEFAULT 20)
     31   */
     32  saltLength: number;
     33  /**
     34   * (DEFAULT 1)
     35   */
     36  trailerField: number;
     37 }
     38 
     39 export interface RSASSAPSSParamsJson {
     40  hashAlgorithm?: AlgorithmIdentifierJson;
     41  maskGenAlgorithm?: AlgorithmIdentifierJson;
     42  saltLength?: number;
     43  trailerField?: number;
     44 }
     45 
     46 export type RSASSAPSSParamsParameters = PkiObjectParameters & Partial<IRSASSAPSSParams>;
     47 
     48 /**
     49 * Represents the RSASSAPSSParams structure described in [RFC4055](https://datatracker.ietf.org/doc/html/rfc4055)
     50 */
     51 export class RSASSAPSSParams extends PkiObject implements IRSASSAPSSParams {
     52 
     53  public static override CLASS_NAME = "RSASSAPSSParams";
     54 
     55  public hashAlgorithm!: AlgorithmIdentifier;
     56  public maskGenAlgorithm!: AlgorithmIdentifier;
     57  public saltLength!: number;
     58  public trailerField!: number;
     59 
     60  /**
     61   * Initializes a new instance of the {@link RSASSAPSSParams} class
     62   * @param parameters Initialization parameters
     63   */
     64  constructor(parameters: RSASSAPSSParamsParameters = {}) {
     65    super();
     66 
     67    this.hashAlgorithm = pvutils.getParametersValue(parameters, HASH_ALGORITHM, RSASSAPSSParams.defaultValues(HASH_ALGORITHM));
     68    this.maskGenAlgorithm = pvutils.getParametersValue(parameters, MASK_GEN_ALGORITHM, RSASSAPSSParams.defaultValues(MASK_GEN_ALGORITHM));
     69    this.saltLength = pvutils.getParametersValue(parameters, SALT_LENGTH, RSASSAPSSParams.defaultValues(SALT_LENGTH));
     70    this.trailerField = pvutils.getParametersValue(parameters, TRAILER_FIELD, RSASSAPSSParams.defaultValues(TRAILER_FIELD));
     71 
     72    if (parameters.schema) {
     73      this.fromSchema(parameters.schema);
     74    }
     75  }
     76 
     77  /**
     78   * Returns default values for all class members
     79   * @param memberName String name for a class member
     80   * @returns Default value
     81   */
     82  public static override defaultValues(memberName: typeof HASH_ALGORITHM): AlgorithmIdentifier;
     83  public static override defaultValues(memberName: typeof MASK_GEN_ALGORITHM): AlgorithmIdentifier;
     84  public static override defaultValues(memberName: typeof SALT_LENGTH): number;
     85  public static override defaultValues(memberName: typeof TRAILER_FIELD): number;
     86  public static override defaultValues(memberName: string): any {
     87    switch (memberName) {
     88      case HASH_ALGORITHM:
     89        return new AlgorithmIdentifier({
     90          algorithmId: "1.3.14.3.2.26", // SHA-1
     91          algorithmParams: new asn1js.Null()
     92        });
     93      case MASK_GEN_ALGORITHM:
     94        return new AlgorithmIdentifier({
     95          algorithmId: "1.2.840.113549.1.1.8", // MGF1
     96          algorithmParams: (new AlgorithmIdentifier({
     97            algorithmId: "1.3.14.3.2.26", // SHA-1
     98            algorithmParams: new asn1js.Null()
     99          })).toSchema()
    100        });
    101      case SALT_LENGTH:
    102        return 20;
    103      case TRAILER_FIELD:
    104        return 1;
    105      default:
    106        return super.defaultValues(memberName);
    107    }
    108  }
    109 
    110  /**
    111   * @inheritdoc
    112   * @asn ASN.1 schema
    113   * ```asn
    114   * RSASSA-PSS-params ::= Sequence  {
    115   *    hashAlgorithm      [0] HashAlgorithm DEFAULT sha1Identifier,
    116   *    maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
    117   *    saltLength         [2] Integer DEFAULT 20,
    118   *    trailerField       [3] Integer DEFAULT 1  }
    119   *```
    120   */
    121  public static override schema(parameters: Schema.SchemaParameters<{
    122    hashAlgorithm?: AlgorithmIdentifierSchema;
    123    maskGenAlgorithm?: AlgorithmIdentifierSchema;
    124    saltLength?: string;
    125    trailerField?: string;
    126  }> = {}): Schema.SchemaType {
    127    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    128 
    129    return (new asn1js.Sequence({
    130      name: (names.blockName || EMPTY_STRING),
    131      value: [
    132        new asn1js.Constructed({
    133          idBlock: {
    134            tagClass: 3, // CONTEXT-SPECIFIC
    135            tagNumber: 0 // [0]
    136          },
    137          optional: true,
    138          value: [AlgorithmIdentifier.schema(names.hashAlgorithm || {})]
    139        }),
    140        new asn1js.Constructed({
    141          idBlock: {
    142            tagClass: 3, // CONTEXT-SPECIFIC
    143            tagNumber: 1 // [1]
    144          },
    145          optional: true,
    146          value: [AlgorithmIdentifier.schema(names.maskGenAlgorithm || {})]
    147        }),
    148        new asn1js.Constructed({
    149          idBlock: {
    150            tagClass: 3, // CONTEXT-SPECIFIC
    151            tagNumber: 2 // [2]
    152          },
    153          optional: true,
    154          value: [new asn1js.Integer({ name: (names.saltLength || EMPTY_STRING) })]
    155        }),
    156        new asn1js.Constructed({
    157          idBlock: {
    158            tagClass: 3, // CONTEXT-SPECIFIC
    159            tagNumber: 3 // [3]
    160          },
    161          optional: true,
    162          value: [new asn1js.Integer({ name: (names.trailerField || EMPTY_STRING) })]
    163        })
    164      ]
    165    }));
    166  }
    167 
    168  public fromSchema(schema: Schema.SchemaType): void {
    169    // Clear input data first
    170    pvutils.clearProps(schema, CLEAR_PROPS);
    171 
    172    // Check the schema is valid
    173    const asn1 = asn1js.compareSchema(schema,
    174      schema,
    175      RSASSAPSSParams.schema({
    176        names: {
    177          hashAlgorithm: {
    178            names: {
    179              blockName: HASH_ALGORITHM
    180            }
    181          },
    182          maskGenAlgorithm: {
    183            names: {
    184              blockName: MASK_GEN_ALGORITHM
    185            }
    186          },
    187          saltLength: SALT_LENGTH,
    188          trailerField: TRAILER_FIELD
    189        }
    190      })
    191    );
    192    AsnError.assertSchema(asn1, this.className);
    193 
    194    // Get internal properties from parsed schema
    195    if (HASH_ALGORITHM in asn1.result)
    196      this.hashAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.hashAlgorithm });
    197 
    198    if (MASK_GEN_ALGORITHM in asn1.result)
    199      this.maskGenAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.maskGenAlgorithm });
    200 
    201    if (SALT_LENGTH in asn1.result)
    202      this.saltLength = asn1.result.saltLength.valueBlock.valueDec;
    203 
    204    if (TRAILER_FIELD in asn1.result)
    205      this.trailerField = asn1.result.trailerField.valueBlock.valueDec;
    206  }
    207 
    208  public toSchema(): asn1js.Sequence {
    209    //#region Create array for output sequence
    210    const outputArray = [];
    211 
    212    if (!this.hashAlgorithm.isEqual(RSASSAPSSParams.defaultValues(HASH_ALGORITHM))) {
    213      outputArray.push(new asn1js.Constructed({
    214        idBlock: {
    215          tagClass: 3, // CONTEXT-SPECIFIC
    216          tagNumber: 0 // [0]
    217        },
    218        value: [this.hashAlgorithm.toSchema()]
    219      }));
    220    }
    221 
    222    if (!this.maskGenAlgorithm.isEqual(RSASSAPSSParams.defaultValues(MASK_GEN_ALGORITHM))) {
    223      outputArray.push(new asn1js.Constructed({
    224        idBlock: {
    225          tagClass: 3, // CONTEXT-SPECIFIC
    226          tagNumber: 1 // [1]
    227        },
    228        value: [this.maskGenAlgorithm.toSchema()]
    229      }));
    230    }
    231 
    232    if (this.saltLength !== RSASSAPSSParams.defaultValues(SALT_LENGTH)) {
    233      outputArray.push(new asn1js.Constructed({
    234        idBlock: {
    235          tagClass: 3, // CONTEXT-SPECIFIC
    236          tagNumber: 2 // [2]
    237        },
    238        value: [new asn1js.Integer({ value: this.saltLength })]
    239      }));
    240    }
    241 
    242    if (this.trailerField !== RSASSAPSSParams.defaultValues(TRAILER_FIELD)) {
    243      outputArray.push(new asn1js.Constructed({
    244        idBlock: {
    245          tagClass: 3, // CONTEXT-SPECIFIC
    246          tagNumber: 3 // [3]
    247        },
    248        value: [new asn1js.Integer({ value: this.trailerField })]
    249      }));
    250    }
    251    //#endregion
    252 
    253    //#region Construct and return new ASN.1 schema for this object
    254    return (new asn1js.Sequence({
    255      value: outputArray
    256    }));
    257    //#endregion
    258  }
    259 
    260  public toJSON(): RSASSAPSSParamsJson {
    261    const res: RSASSAPSSParamsJson = {};
    262 
    263    if (!this.hashAlgorithm.isEqual(RSASSAPSSParams.defaultValues(HASH_ALGORITHM))) {
    264      res.hashAlgorithm = this.hashAlgorithm.toJSON();
    265    }
    266 
    267    if (!this.maskGenAlgorithm.isEqual(RSASSAPSSParams.defaultValues(MASK_GEN_ALGORITHM))) {
    268      res.maskGenAlgorithm = this.maskGenAlgorithm.toJSON();
    269    }
    270 
    271    if (this.saltLength !== RSASSAPSSParams.defaultValues(SALT_LENGTH)) {
    272      res.saltLength = this.saltLength;
    273    }
    274 
    275    if (this.trailerField !== RSASSAPSSParams.defaultValues(TRAILER_FIELD)) {
    276      res.trailerField = this.trailerField;
    277    }
    278 
    279    return res;
    280  }
    281 
    282 }