tor-browser

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

KEKRecipientInfo.ts (7498B)


      1 import * as asn1js from "asn1js";
      2 import * as pvutils from "pvutils";
      3 import { KEKIdentifier, KEKIdentifierJson, KEKIdentifierSchema } from "./KEKIdentifier";
      4 import { AlgorithmIdentifier, AlgorithmIdentifierJson, AlgorithmIdentifierSchema } from "./AlgorithmIdentifier";
      5 import * as Schema from "./Schema";
      6 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      7 import { AsnError } from "./errors";
      8 import { EMPTY_BUFFER, EMPTY_STRING } from "./constants";
      9 
     10 const VERSION = "version";
     11 const KEK_ID = "kekid";
     12 const KEY_ENCRYPTION_ALGORITHM = "keyEncryptionAlgorithm";
     13 const ENCRYPTED_KEY = "encryptedKey";
     14 const PER_DEFINED_KEK = "preDefinedKEK";
     15 const CLEAR_PROPS = [
     16  VERSION,
     17  KEK_ID,
     18  KEY_ENCRYPTION_ALGORITHM,
     19  ENCRYPTED_KEY,
     20 ];
     21 
     22 export interface IKEKRecipientInfo {
     23  version: number;
     24  kekid: KEKIdentifier;
     25  keyEncryptionAlgorithm: AlgorithmIdentifier;
     26  encryptedKey: asn1js.OctetString;
     27  preDefinedKEK: ArrayBuffer;
     28 }
     29 
     30 export interface KEKRecipientInfoJson {
     31  version: number;
     32  kekid: KEKIdentifierJson;
     33  keyEncryptionAlgorithm: AlgorithmIdentifierJson;
     34  encryptedKey: asn1js.OctetStringJson;
     35 }
     36 
     37 export type KEKRecipientInfoParameters = PkiObjectParameters & Partial<IKEKRecipientInfo>;
     38 
     39 /**
     40 * Represents the KEKRecipientInfo structure described in [RFC5652](https://datatracker.ietf.org/doc/html/rfc5652)
     41 */
     42 export class KEKRecipientInfo extends PkiObject implements IKEKRecipientInfo {
     43 
     44  public static override CLASS_NAME = "KEKRecipientInfo";
     45 
     46  public version!: number;
     47  public kekid!: KEKIdentifier;
     48  public keyEncryptionAlgorithm!: AlgorithmIdentifier;
     49  public encryptedKey!: asn1js.OctetString;
     50  public preDefinedKEK!: ArrayBuffer;
     51 
     52  /**
     53   * Initializes a new instance of the {@link KEKRecipientInfo} class
     54   * @param parameters Initialization parameters
     55   */
     56  constructor(parameters: KEKRecipientInfoParameters = {}) {
     57    super();
     58 
     59    this.version = pvutils.getParametersValue(parameters, VERSION, KEKRecipientInfo.defaultValues(VERSION));
     60    this.kekid = pvutils.getParametersValue(parameters, KEK_ID, KEKRecipientInfo.defaultValues(KEK_ID));
     61    this.keyEncryptionAlgorithm = pvutils.getParametersValue(parameters, KEY_ENCRYPTION_ALGORITHM, KEKRecipientInfo.defaultValues(KEY_ENCRYPTION_ALGORITHM));
     62    this.encryptedKey = pvutils.getParametersValue(parameters, ENCRYPTED_KEY, KEKRecipientInfo.defaultValues(ENCRYPTED_KEY));
     63    this.preDefinedKEK = pvutils.getParametersValue(parameters, PER_DEFINED_KEK, KEKRecipientInfo.defaultValues(PER_DEFINED_KEK));
     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 VERSION): number;
     76  public static override defaultValues(memberName: typeof KEK_ID): KEKIdentifier;
     77  public static override defaultValues(memberName: typeof KEY_ENCRYPTION_ALGORITHM): AlgorithmIdentifier;
     78  public static override defaultValues(memberName: typeof ENCRYPTED_KEY): asn1js.OctetString;
     79  public static override defaultValues(memberName: typeof PER_DEFINED_KEK): ArrayBuffer;
     80  public static override defaultValues(memberName: string): any {
     81    switch (memberName) {
     82      case VERSION:
     83        return 0;
     84      case KEK_ID:
     85        return new KEKIdentifier();
     86      case KEY_ENCRYPTION_ALGORITHM:
     87        return new AlgorithmIdentifier();
     88      case ENCRYPTED_KEY:
     89        return new asn1js.OctetString();
     90      case PER_DEFINED_KEK:
     91        return EMPTY_BUFFER;
     92      default:
     93        return super.defaultValues(memberName);
     94    }
     95  }
     96 
     97  /**
     98   * Compare values with default values for all class members
     99   * @param memberName String name for a class member
    100   * @param memberValue Value to compare with default value
    101   */
    102  public static compareWithDefault(memberName: string, memberValue: any): boolean {
    103    switch (memberName) {
    104      case "KEKRecipientInfo":
    105        return (memberValue === KEKRecipientInfo.defaultValues(VERSION));
    106      case KEK_ID:
    107        return ((memberValue.compareWithDefault("keyIdentifier", memberValue.keyIdentifier)) &&
    108          (("date" in memberValue) === false) &&
    109          (("other" in memberValue) === false));
    110      case KEY_ENCRYPTION_ALGORITHM:
    111        return ((memberValue.algorithmId === EMPTY_STRING) && (("algorithmParams" in memberValue) === false));
    112      case ENCRYPTED_KEY:
    113        return (memberValue.isEqual(KEKRecipientInfo.defaultValues(ENCRYPTED_KEY)));
    114      case PER_DEFINED_KEK:
    115        return (memberValue.byteLength === 0);
    116      default:
    117        return super.defaultValues(memberName);
    118    }
    119  }
    120 
    121  /**
    122   * @inheritdoc
    123   * @asn ASN.1 schema
    124   * ```asn
    125   * KEKRecipientInfo ::= SEQUENCE {
    126   *    version CMSVersion,  -- always set to 4
    127   *    kekid KEKIdentifier,
    128   *    keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
    129   *    encryptedKey EncryptedKey }
    130   *```
    131   */
    132  public static override schema(parameters: Schema.SchemaParameters<{
    133    version?: string;
    134    kekid?: KEKIdentifierSchema;
    135    keyEncryptionAlgorithm?: AlgorithmIdentifierSchema;
    136    encryptedKey?: string;
    137  }> = {}): Schema.SchemaType {
    138    /**
    139     * @type {Object}
    140     * @property {string} [blockName]
    141     * @property {string} [version]
    142     * @property {string} [kekid]
    143     * @property {string} [keyEncryptionAlgorithm]
    144     * @property {string} [encryptedKey]
    145     */
    146    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    147 
    148    return (new asn1js.Sequence({
    149      name: (names.blockName || EMPTY_STRING),
    150      value: [
    151        new asn1js.Integer({ name: (names.version || EMPTY_STRING) }),
    152        KEKIdentifier.schema(names.kekid || {}),
    153        AlgorithmIdentifier.schema(names.keyEncryptionAlgorithm || {}),
    154        new asn1js.OctetString({ name: (names.encryptedKey || EMPTY_STRING) })
    155      ]
    156    }));
    157  }
    158 
    159  public fromSchema(schema: Schema.SchemaType): void {
    160    // Clear input data first
    161    pvutils.clearProps(schema, CLEAR_PROPS);
    162 
    163    // Check the schema is valid
    164    const asn1 = asn1js.compareSchema(schema,
    165      schema,
    166      KEKRecipientInfo.schema({
    167        names: {
    168          version: VERSION,
    169          kekid: {
    170            names: {
    171              blockName: KEK_ID
    172            }
    173          },
    174          keyEncryptionAlgorithm: {
    175            names: {
    176              blockName: KEY_ENCRYPTION_ALGORITHM
    177            }
    178          },
    179          encryptedKey: ENCRYPTED_KEY
    180        }
    181      })
    182    );
    183    AsnError.assertSchema(asn1, this.className);
    184 
    185    // Get internal properties from parsed schema
    186    this.version = asn1.result.version.valueBlock.valueDec;
    187    this.kekid = new KEKIdentifier({ schema: asn1.result.kekid });
    188    this.keyEncryptionAlgorithm = new AlgorithmIdentifier({ schema: asn1.result.keyEncryptionAlgorithm });
    189    this.encryptedKey = asn1.result.encryptedKey;
    190  }
    191 
    192  public toSchema(): asn1js.Sequence {
    193    // Construct and return new ASN.1 schema for this object
    194    return (new asn1js.Sequence({
    195      value: [
    196        new asn1js.Integer({ value: this.version }),
    197        this.kekid.toSchema(),
    198        this.keyEncryptionAlgorithm.toSchema(),
    199        this.encryptedKey
    200      ]
    201    }));
    202  }
    203 
    204  public toJSON(): KEKRecipientInfoJson {
    205    return {
    206      version: this.version,
    207      kekid: this.kekid.toJSON(),
    208      keyEncryptionAlgorithm: this.keyEncryptionAlgorithm.toJSON(),
    209      encryptedKey: this.encryptedKey.toJSON(),
    210    };
    211  }
    212 
    213 }