tor-browser

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

MessageImprint.ts (5762B)


      1 import * as asn1js from "asn1js";
      2 import * as pvutils from "pvutils";
      3 import { AlgorithmIdentifier, AlgorithmIdentifierJson, AlgorithmIdentifierSchema } from "./AlgorithmIdentifier";
      4 import { AsnError } from "./errors";
      5 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      6 import * as Schema from "./Schema";
      7 import * as common from "./common";
      8 import { EMPTY_STRING } from "./constants";
      9 
     10 export const HASH_ALGORITHM = "hashAlgorithm";
     11 export const HASHED_MESSAGE = "hashedMessage";
     12 const CLEAR_PROPS = [
     13  HASH_ALGORITHM,
     14  HASHED_MESSAGE,
     15 ];
     16 
     17 export interface IMessageImprint {
     18  hashAlgorithm: AlgorithmIdentifier;
     19  hashedMessage: asn1js.OctetString;
     20 }
     21 
     22 export interface MessageImprintJson {
     23  hashAlgorithm: AlgorithmIdentifierJson;
     24  hashedMessage: asn1js.OctetStringJson;
     25 }
     26 
     27 export type MessageImprintParameters = PkiObjectParameters & Partial<IMessageImprint>;
     28 
     29 export type MessageImprintSchema = Schema.SchemaParameters<{
     30  hashAlgorithm?: AlgorithmIdentifierSchema;
     31  hashedMessage?: string;
     32 }>;
     33 
     34 /**
     35 * Represents the MessageImprint structure described in [RFC3161](https://www.ietf.org/rfc/rfc3161.txt)
     36 */
     37 export class MessageImprint extends PkiObject implements IMessageImprint {
     38 
     39  public static override CLASS_NAME = "MessageImprint";
     40 
     41  /**
     42   * Creates and fills a new instance of {@link MessageImprint}
     43   * @param hashAlgorithm
     44   * @param message
     45   * @param crypto Crypto engine
     46   * @returns New instance of {@link MessageImprint}
     47   */
     48  public static async create(hashAlgorithm: string, message: BufferSource, crypto = common.getCrypto(true)): Promise<MessageImprint> {
     49    const hashAlgorithmOID = crypto.getOIDByAlgorithm({ name: hashAlgorithm }, true, "hashAlgorithm");
     50 
     51    const hashedMessage = await crypto.digest(hashAlgorithm, message);
     52 
     53    const res = new MessageImprint({
     54      hashAlgorithm: new AlgorithmIdentifier({
     55        algorithmId: hashAlgorithmOID,
     56        algorithmParams: new asn1js.Null(),
     57      }),
     58      hashedMessage: new asn1js.OctetString({ valueHex: hashedMessage })
     59    });
     60 
     61    return res;
     62  }
     63 
     64  public hashAlgorithm!: AlgorithmIdentifier;
     65  public hashedMessage!: asn1js.OctetString;
     66 
     67  /**
     68   * Initializes a new instance of the {@link MessageImprint} class
     69   * @param parameters Initialization parameters
     70   */
     71  constructor(parameters: MessageImprintParameters = {}) {
     72    super();
     73 
     74    this.hashAlgorithm = pvutils.getParametersValue(parameters, HASH_ALGORITHM, MessageImprint.defaultValues(HASH_ALGORITHM));
     75    this.hashedMessage = pvutils.getParametersValue(parameters, HASHED_MESSAGE, MessageImprint.defaultValues(HASHED_MESSAGE));
     76 
     77    if (parameters.schema) {
     78      this.fromSchema(parameters.schema);
     79    }
     80  }
     81 
     82  /**
     83   * Returns default values for all class members
     84   * @param memberName String name for a class member
     85   * @returns Default value
     86   */
     87  public static override defaultValues(memberName: typeof HASH_ALGORITHM): AlgorithmIdentifier;
     88  public static override defaultValues(memberName: typeof HASHED_MESSAGE): asn1js.OctetString;
     89  public static override defaultValues(memberName: string): any {
     90    switch (memberName) {
     91      case HASH_ALGORITHM:
     92        return new AlgorithmIdentifier();
     93      case HASHED_MESSAGE:
     94        return new asn1js.OctetString();
     95      default:
     96        return super.defaultValues(memberName);
     97    }
     98  }
     99 
    100  /**
    101   * Compare values with default values for all class members
    102   * @param memberName String name for a class member
    103   * @param memberValue Value to compare with default value
    104   */
    105  public static compareWithDefault(memberName: string, memberValue: any): boolean {
    106    switch (memberName) {
    107      case HASH_ALGORITHM:
    108        return ((memberValue.algorithmId === EMPTY_STRING) && (("algorithmParams" in memberValue) === false));
    109      case HASHED_MESSAGE:
    110        return (memberValue.isEqual(MessageImprint.defaultValues(memberName)) === 0);
    111      default:
    112        return super.defaultValues(memberName);
    113    }
    114  }
    115 
    116  /**
    117   * @inheritdoc
    118   * @asn ASN.1 schema
    119   * ```asn
    120   * MessageImprint ::= SEQUENCE  {
    121   *    hashAlgorithm                AlgorithmIdentifier,
    122   *    hashedMessage                OCTET STRING  }
    123   *```
    124   */
    125  public static override schema(parameters: MessageImprintSchema = {}): Schema.SchemaType {
    126    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    127 
    128    return (new asn1js.Sequence({
    129      name: (names.blockName || EMPTY_STRING),
    130      value: [
    131        AlgorithmIdentifier.schema(names.hashAlgorithm || {}),
    132        new asn1js.OctetString({ name: (names.hashedMessage || EMPTY_STRING) })
    133      ]
    134    }));
    135  }
    136 
    137  public fromSchema(schema: Schema.SchemaType): void {
    138    // Clear input data first
    139    pvutils.clearProps(schema, CLEAR_PROPS);
    140 
    141    // Check the schema is valid
    142    const asn1 = asn1js.compareSchema(schema,
    143      schema,
    144      MessageImprint.schema({
    145        names: {
    146          hashAlgorithm: {
    147            names: {
    148              blockName: HASH_ALGORITHM
    149            }
    150          },
    151          hashedMessage: HASHED_MESSAGE
    152        }
    153      })
    154    );
    155    AsnError.assertSchema(asn1, this.className);
    156 
    157    // Get internal properties from parsed schema
    158    this.hashAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.hashAlgorithm });
    159    this.hashedMessage = asn1.result.hashedMessage;
    160  }
    161 
    162  public toSchema(): asn1js.Sequence {
    163    //#region Construct and return new ASN.1 schema for this object
    164    return (new asn1js.Sequence({
    165      value: [
    166        this.hashAlgorithm.toSchema(),
    167        this.hashedMessage
    168      ]
    169    }));
    170    //#endregion
    171  }
    172 
    173  public toJSON(): MessageImprintJson {
    174    return {
    175      hashAlgorithm: this.hashAlgorithm.toJSON(),
    176      hashedMessage: this.hashedMessage.toJSON(),
    177    };
    178  }
    179 
    180 }