tor-browser

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

ContentInfo.ts (5210B)


      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 { id_ContentType_Data, id_ContentType_EncryptedData, id_ContentType_EnvelopedData, id_ContentType_SignedData } from "./ObjectIdentifiers";
      6 import { PkiObject, PkiObjectParameters } from "./PkiObject";
      7 import * as Schema from "./Schema";
      8 
      9 const CONTENT_TYPE = "contentType";
     10 const CONTENT = "content";
     11 const CLEAR_PROPS = [CONTENT_TYPE, CONTENT];
     12 
     13 export interface IContentInfo {
     14  contentType: string;
     15  content: any;
     16 }
     17 
     18 export type ContentInfoParameters = PkiObjectParameters & Partial<IContentInfo>;
     19 
     20 export type ContentInfoSchema = Schema.SchemaParameters<{
     21  contentType?: string;
     22  content?: string;
     23 }>;
     24 
     25 export interface ContentInfoJson {
     26  contentType: string;
     27  content?: any;
     28 }
     29 
     30 /**
     31 * Represents the ContentInfo structure described in [RFC5652](https://datatracker.ietf.org/doc/html/rfc5652)
     32 */
     33 export class ContentInfo extends PkiObject implements IContentInfo {
     34 
     35  public static override CLASS_NAME = "ContentInfo";
     36  public static readonly DATA = id_ContentType_Data;
     37  public static readonly SIGNED_DATA = id_ContentType_SignedData;
     38  public static readonly ENVELOPED_DATA = id_ContentType_EnvelopedData;
     39  public static readonly ENCRYPTED_DATA = id_ContentType_EncryptedData;
     40 
     41  public contentType!: string;
     42  public content: any;
     43 
     44  /**
     45   * Initializes a new instance of the {@link ContentInfo} class
     46   * @param parameters Initialization parameters
     47   */
     48  constructor(parameters: ContentInfoParameters = {}) {
     49    super();
     50 
     51    this.contentType = pvutils.getParametersValue(parameters, CONTENT_TYPE, ContentInfo.defaultValues(CONTENT_TYPE));
     52    this.content = pvutils.getParametersValue(parameters, CONTENT, ContentInfo.defaultValues(CONTENT));
     53 
     54    if (parameters.schema) {
     55      this.fromSchema(parameters.schema);
     56    }
     57  }
     58 
     59  /**
     60   * Returns default values for all class members
     61   * @param memberName String name for a class member
     62   * @returns Default value
     63   */
     64  public static override defaultValues(memberName: typeof CONTENT_TYPE): string;
     65  public static override defaultValues(memberName: typeof CONTENT): any;
     66  public static override defaultValues(memberName: string): any {
     67    switch (memberName) {
     68      case CONTENT_TYPE:
     69        return EMPTY_STRING;
     70      case CONTENT:
     71        return new asn1js.Any();
     72      default:
     73        return super.defaultValues(memberName);
     74    }
     75  }
     76 
     77  /**
     78   * Compare values with default values for all class members
     79   * @param memberName String name for a class member
     80   * @param memberValue Value to compare with default value
     81   */
     82  static compareWithDefault<T>(memberName: string, memberValue: T): memberValue is T {
     83    switch (memberName) {
     84      case CONTENT_TYPE:
     85        return (typeof memberValue === "string" &&
     86          memberValue === this.defaultValues(CONTENT_TYPE));
     87      case CONTENT:
     88        return (memberValue instanceof asn1js.Any);
     89      default:
     90        return super.defaultValues(memberName);
     91    }
     92  }
     93 
     94  /**
     95   * @inheritdoc
     96   * @asn ASN.1 schema
     97   * ```asn
     98   * ContentInfo ::= SEQUENCE {
     99   *    contentType ContentType,
    100   *    content [0] EXPLICIT ANY DEFINED BY contentType }
    101   *```
    102   */
    103  public static override schema(parameters: ContentInfoSchema = {}): Schema.SchemaType {
    104    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});
    105 
    106    if (("optional" in names) === false) {
    107      names.optional = false;
    108    }
    109 
    110    return (new asn1js.Sequence({
    111      name: (names.blockName || "ContentInfo"),
    112      optional: names.optional,
    113      value: [
    114        new asn1js.ObjectIdentifier({ name: (names.contentType || CONTENT_TYPE) }),
    115        new asn1js.Constructed({
    116          idBlock: {
    117            tagClass: 3, // CONTEXT-SPECIFIC
    118            tagNumber: 0 // [0]
    119          },
    120          value: [new asn1js.Any({ name: (names.content || CONTENT) })] // EXPLICIT ANY value
    121        })
    122      ]
    123    }));
    124  }
    125 
    126  public fromSchema(schema: Schema.SchemaType): void {
    127    // Clear input data first
    128    pvutils.clearProps(schema, CLEAR_PROPS);
    129 
    130    // Check the schema is valid
    131    const asn1 = asn1js.compareSchema(schema,
    132      schema,
    133      ContentInfo.schema()
    134    );
    135    AsnError.assertSchema(asn1, this.className);
    136 
    137    // Get internal properties from parsed schema
    138    this.contentType = asn1.result.contentType.valueBlock.toString();
    139    this.content = asn1.result.content;
    140  }
    141 
    142  public toSchema(): asn1js.Sequence {
    143    //#region Construct and return new ASN.1 schema for this object
    144    return (new asn1js.Sequence({
    145      value: [
    146        new asn1js.ObjectIdentifier({ value: this.contentType }),
    147        new asn1js.Constructed({
    148          idBlock: {
    149            tagClass: 3, // CONTEXT-SPECIFIC
    150            tagNumber: 0 // [0]
    151          },
    152          value: [this.content] // EXPLICIT ANY value
    153        })
    154      ]
    155    }));
    156    //#endregion
    157  }
    158 
    159  public toJSON(): ContentInfoJson {
    160    const object: ContentInfoJson = {
    161      contentType: this.contentType
    162    };
    163 
    164    if (!(this.content instanceof asn1js.Any)) {
    165      object.content = this.content.toJSON();
    166    }
    167 
    168    return object;
    169  }
    170 
    171 }