tor-browser

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

RecipientIdentifier.ts (5525B)


      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 { IssuerAndSerialNumber, IssuerAndSerialNumberJson } from "./IssuerAndSerialNumber";
      6 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      7 import * as Schema from "./Schema";
      8 
      9 const VARIANT = "variant";
     10 const VALUE = "value";
     11 const CLEAR_PROPS = [
     12  "blockName"
     13 ];
     14 
     15 export interface IRecipientIdentifier {
     16  variant: number;
     17  value: IssuerAndSerialNumber | asn1js.OctetString;
     18 }
     19 
     20 export interface RecipientIdentifierJson {
     21  variant: number;
     22  value?: IssuerAndSerialNumberJson | asn1js.OctetStringJson;
     23 }
     24 
     25 export type RecipientIdentifierParameters = PkiObjectParameters & Partial<IRecipientIdentifier>;
     26 
     27 export type RecipientIdentifierSchema = Schema.SchemaParameters;
     28 
     29 /**
     30 * Represents the RecipientIdentifier structure described in [RFC5652](https://datatracker.ietf.org/doc/html/rfc5652)
     31 */
     32 export class RecipientIdentifier extends PkiObject implements IRecipientIdentifier {
     33 
     34  public static override CLASS_NAME = "RecipientIdentifier";
     35 
     36  public variant!: number;
     37  public value!: IssuerAndSerialNumber | asn1js.OctetString;
     38 
     39  /**
     40   * Initializes a new instance of the {@link RecipientIdentifier} class
     41   * @param parameters Initialization parameters
     42   */
     43  constructor(parameters: RecipientIdentifierParameters = {}) {
     44    super();
     45 
     46    this.variant = pvutils.getParametersValue(parameters, VARIANT, RecipientIdentifier.defaultValues(VARIANT));
     47    if (VALUE in parameters) {
     48      this.value = pvutils.getParametersValue(parameters, VALUE, RecipientIdentifier.defaultValues(VALUE));
     49    }
     50 
     51    if (parameters.schema) {
     52      this.fromSchema(parameters.schema);
     53    }
     54  }
     55 
     56  /**
     57   * Returns default values for all class members
     58   * @param memberName String name for a class member
     59   * @returns Default value
     60   */
     61  public static override defaultValues(memberName: typeof VARIANT): number;
     62  public static override defaultValues(memberName: typeof VALUE): any;
     63  public static override defaultValues(memberName: string): any {
     64    switch (memberName) {
     65      case VARIANT:
     66        return (-1);
     67      case VALUE:
     68        return {};
     69      default:
     70        return super.defaultValues(memberName);
     71    }
     72  }
     73 
     74  /**
     75   * Compare values with default values for all class members
     76   * @param memberName String name for a class member
     77   * @param memberValue Value to compare with default value
     78   */
     79  public static compareWithDefault(memberName: string, memberValue: any): boolean {
     80    switch (memberName) {
     81      case VARIANT:
     82        return (memberValue === (-1));
     83      case VALUE:
     84        return (Object.keys(memberValue).length === 0);
     85      default:
     86        return super.defaultValues(memberName);
     87    }
     88  }
     89 
     90  /**
     91   * @inheritdoc
     92   * @asn ASN.1 schema
     93   * ```asn
     94   * RecipientIdentifier ::= CHOICE {
     95   *    issuerAndSerialNumber IssuerAndSerialNumber,
     96   *    subjectKeyIdentifier [0] SubjectKeyIdentifier }
     97   *
     98   * SubjectKeyIdentifier ::= OCTET STRING
     99   *```
    100   */
    101  public static override schema(parameters: RecipientIdentifierSchema = {}): Schema.SchemaType {
    102    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    103 
    104    return (new asn1js.Choice({
    105      value: [
    106        IssuerAndSerialNumber.schema({
    107          names: {
    108            blockName: (names.blockName || EMPTY_STRING)
    109          }
    110        }),
    111        new asn1js.Primitive({
    112          name: (names.blockName || EMPTY_STRING),
    113          idBlock: {
    114            tagClass: 3, // CONTEXT-SPECIFIC
    115            tagNumber: 0 // [0]
    116          }
    117        })
    118      ]
    119    }));
    120  }
    121 
    122  public fromSchema(schema: Schema.SchemaType): void {
    123    // Clear input data first
    124    pvutils.clearProps(schema, CLEAR_PROPS);
    125 
    126    // Check the schema is valid
    127    const asn1 = asn1js.compareSchema(schema,
    128      schema,
    129      RecipientIdentifier.schema({
    130        names: {
    131          blockName: "blockName"
    132        }
    133      })
    134    );
    135    AsnError.assertSchema(asn1, this.className);
    136 
    137    // Get internal properties from parsed schema
    138    if (asn1.result.blockName.idBlock.tagClass === 1) {
    139      this.variant = 1;
    140      this.value = new IssuerAndSerialNumber({ schema: asn1.result.blockName });
    141    } else {
    142      this.variant = 2;
    143      this.value = new asn1js.OctetString({ valueHex: asn1.result.blockName.valueBlock.valueHex });
    144    }
    145  }
    146 
    147  public toSchema(): asn1js.BaseBlock<any> {
    148    // Construct and return new ASN.1 schema for this object
    149    switch (this.variant) {
    150      case 1:
    151        if (!(this.value instanceof IssuerAndSerialNumber)) {
    152          throw new Error("Incorrect type of RecipientIdentifier.value. It should be IssuerAndSerialNumber.");
    153        }
    154        return this.value.toSchema();
    155      case 2:
    156        if (!(this.value instanceof asn1js.OctetString)) {
    157          throw new Error("Incorrect type of RecipientIdentifier.value. It should be ASN.1 OctetString.");
    158        }
    159        return new asn1js.Primitive({
    160          idBlock: {
    161            tagClass: 3, // CONTEXT-SPECIFIC
    162            tagNumber: 0 // [0]
    163          },
    164          valueHex: this.value.valueBlock.valueHexView
    165        });
    166      default:
    167        return new asn1js.Any() as any;
    168    }
    169  }
    170 
    171  public toJSON(): RecipientIdentifierJson {
    172    const res: RecipientIdentifierJson = {
    173      variant: this.variant
    174    };
    175 
    176    if ((this.variant === 1 || this.variant === 2) && this.value) {
    177      res.value = this.value.toJSON();
    178    }
    179 
    180    return res;
    181  }
    182 
    183 }