Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/js/PKI.js/src/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 8 kB image not shown  

Quelle  ECPrivateKey.ts   Sprache: unbekannt

 
import * as asn1js from "asn1js";
import * as pvtsutils from "pvtsutils";
import * as pvutils from "pvutils";
import { EMPTY_STRING } from "./constants";
import { ECNamedCurves } from "./ECNamedCurves";
import { ECPublicKey, ECPublicKeyParameters } from "./ECPublicKey";
import { AsnError, ParameterError } from "./errors";
import { PkiObject, PkiObjectParameters } from "./PkiObject";
import * as Schema from "./Schema";

const VERSION = "version";
const PRIVATE_KEY = "privateKey";
const NAMED_CURVE = "namedCurve";
const PUBLIC_KEY = "publicKey";
const CLEAR_PROPS = [
  VERSION,
  PRIVATE_KEY,
  NAMED_CURVE,
  PUBLIC_KEY
];

export interface IECPrivateKey {
  version: number;
  privateKey: asn1js.OctetString;
  namedCurve?: string;
  publicKey?: ECPublicKey;
}

export type ECPrivateKeyParameters = PkiObjectParameters & Partial<IECPrivateKey> &&nbsp;{ json?: ECPrivateKeyJson; };

export interface ECPrivateKeyJson {
  crv: string;
  y?: string;
  x?: string;
  d: string;
}

/**
 * Represents the PrivateKeyInfo structure described in [RFC5915](https://datatracker.ietf.org/doc/html/rfc5915)
 */
export class ECPrivateKey extends PkiObject implements IECPrivateKey {

  public static override CLASS_NAME = "ECPrivateKey";

  public version!: number;
  public privateKey!: asn1js.OctetString;
  public namedCurve?: string;
  public publicKey?: ECPublicKey;

  /**
   * Initializes a new instance of the {@link ECPrivateKey} class
   * @param parameters Initialization parameters
   */
  constructor(parameters: ECPrivateKeyParameters = {}) {
    super();

    this.version = pvutils.getParametersValue(parameters, VERSION, ECPrivateKey.defaultValues(VERSION));
    this.privateKey = pvutils.getParametersValue(parameters, PRIVATE_KEY, ECPrivateKey.defaultValues(PRIVATE_KEY));
    if (NAMED_CURVE in parameters) {
      this.namedCurve = pvutils.getParametersValue(parameters, NAMED_CURVE, ECPrivateKey.defaultValues(NAMED_CURVE));
    }
    if (PUBLIC_KEY in parameters) {
      this.publicKey = pvutils.getParametersValue(parameters, PUBLIC_KEY, ECPrivateKey.defaultValues(PUBLIC_KEY));
    }

    if (parameters.json) {
      this.fromJSON(parameters.json);
    }

    if (parameters.schema) {
      this.fromSchema(parameters.schema);
    }
  }

  /**
   * Returns default values for all class members
   * @param memberName String name for a class member
   * @returns Default value
   */
  public static override defaultValues(memberName: typeof VERSION): 1;
  public static override defaultValues(memberName: typeof PRIVATE_KEY): asn1js.OctetString;
  public static override defaultValues(memberName: typeof NAMED_CURVE): string;
  public static override defaultValues(memberName: typeof PUBLIC_KEY): ECPublicKey;
  public static override defaultValues(memberName: string): any {
    switch (memberName) {
      case VERSION:
        return 1;
      case PRIVATE_KEY:
        return new asn1js.OctetString();
      case NAMED_CURVE:
        return EMPTY_STRING;
      case PUBLIC_KEY:
        return new ECPublicKey();
      default:
        return super.defaultValues(memberName);
    }
  }

  /**
   * Compare values with default values for all class members
   * @param memberName String name for a class member
   * @param memberValue Value to compare with default value
   */
  public static compareWithDefault(memberName: string, memberValue: any): boolean {
    switch (memberName) {
      case VERSION:
        return (memberValue === ECPrivateKey.defaultValues(memberName));
      case PRIVATE_KEY:
        return (memberValue.isEqual(ECPrivateKey.defaultValues(memberName)));
      case NAMED_CURVE:
        return (memberValue === EMPTY_STRING);
      case PUBLIC_KEY:
        return ((ECPublicKey.compareWithDefault(NAMED_CURVE, memberValue.namedCurve)) &&
          (ECPublicKey.compareWithDefault("x", memberValue.x)) &&
          (ECPublicKey.compareWithDefault("y", memberValue.y)));
      default:
        return super.defaultValues(memberName);
    }
  }

  /**
   * @inheritdoc
   * @asn ASN.1 schema
   * ```asn
   * ECPrivateKey ::= SEQUENCE {
   * version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
   * privateKey     OCTET STRING,
   * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
   * publicKey  [1] BIT STRING OPTIONAL
   * }
   *```
   */
  public static override schema(parameters: Schema.SchemaParameters<{
    version?: string;
    privateKey?: string;
    namedCurve?: string;
    publicKey?: string;
  }> = {}): Schema.SchemaType {
    const names = pvutils.getParametersValue<NonNullable<typeof parameters.names>>(parameters, "names", {});

    return (new asn1js.Sequence({
      name: (names.blockName || EMPTY_STRING),
      value: [
        new asn1js.Integer({ name: (names.version || EMPTY_STRING) }),
        new asn1js.OctetString({ name: (names.privateKey || EMPTY_STRING) }),
        new asn1js.Constructed({
          optional: true,
          idBlock: {
            tagClass: 3, // CONTEXT-SPECIFIC
            tagNumber: 0 // [0]
          },
          value: [
            new asn1js.ObjectIdentifier({ name: (names.namedCurve || EMPTY_STRING) })
          ]
        }),
        new asn1js.Constructed({
          optional: true,
          idBlock: {
            tagClass: 3, // CONTEXT-SPECIFIC
            tagNumber: 1 // [1]
          },
          value: [
            new asn1js.BitString({ name: (names.publicKey || EMPTY_STRING) })
          ]
        })
      ]
    }));
  }

  public fromSchema(schema: Schema.SchemaType): void {
    // Clear input data first
    pvutils.clearProps(schema, CLEAR_PROPS);

    // Check the schema is valid
    const asn1 = asn1js.compareSchema(schema,
      schema,
      ECPrivateKey.schema({
        names: {
          version: VERSION,
          privateKey: PRIVATE_KEY,
          namedCurve: NAMED_CURVE,
          publicKey: PUBLIC_KEY
        }
      })
    );
    AsnError.assertSchema(asn1, this.className);

    //#region Get internal properties from parsed schema
    this.version = asn1.result.version.valueBlock.valueDec;
    this.privateKey = asn1.result.privateKey;

    if (NAMED_CURVE in asn1.result) {
      this.namedCurve = asn1.result.namedCurve.valueBlock.toString();
    }

    if (PUBLIC_KEY in asn1.result) {
      const publicKeyData: ECPublicKeyParameters = { schema: asn1.result.publicKey.valueBlock.valueHex };
      if (NAMED_CURVE in this) {
        publicKeyData.namedCurve = this.namedCurve;
      }

      this.publicKey = new ECPublicKey(publicKeyData);
    }
    //#endregion
  }

  public toSchema(): asn1js.Sequence {
    const outputArray: any = [
      new asn1js.Integer({ value: this.version }),
      this.privateKey
    ];

    if (this.namedCurve) {
      outputArray.push(new asn1js.Constructed({
        idBlock: {
          tagClass: 3, // CONTEXT-SPECIFIC
          tagNumber: 0 // [0]
        },
        value: [
          new asn1js.ObjectIdentifier({ value: this.namedCurve })
        ]
      }));
    }

    if (this.publicKey) {
      outputArray.push(new asn1js.Constructed({
        idBlock: {
          tagClass: 3, // CONTEXT-SPECIFIC
          tagNumber: 1 // [1]
        },
        value: [
          new asn1js.BitString({ valueHex: this.publicKey.toSchema().toBER(false) })
        ]
      }));
    }

    return new asn1js.Sequence({
      value: outputArray
    });
  }

  public toJSON(): ECPrivateKeyJson {
    if (!this.namedCurve || ECPrivateKey.compareWithDefault(NAMED_CURVE, this.namedCurve)) {
      throw new Error("Not enough information for making JSON: absent \"namedCurve\" value");
    }

    const curve = ECNamedCurves.find(this.namedCurve);

    const privateKeyJSON: ECPrivateKeyJson = {
      crv: curve ? curve.name : this.namedCurve,
      d: pvtsutils.Convert.ToBase64Url(this.privateKey.valueBlock.valueHexView),
    };

    if (this.publicKey) {
      const publicKeyJSON = this.publicKey.toJSON();

      privateKeyJSON.x = publicKeyJSON.x;
      privateKeyJSON.y = publicKeyJSON.y;
    }

    return privateKeyJSON;
  }

  /**
   * Converts JSON value into current object
   * @param json JSON object
   */
  public fromJSON(json: any): void {
    ParameterError.assert("json", json, "crv", "d");

    let coordinateLength = 0;

    const curve = ECNamedCurves.find(json.crv);
    if (curve) {
      this.namedCurve = curve.id;
      coordinateLength = curve.size;
    }

    const convertBuffer = pvtsutils.Convert.FromBase64Url(json.d);

    if (convertBuffer.byteLength < coordinateLength) {
      const buffer = new ArrayBuffer(coordinateLength);
      const view = new Uint8Array(buffer);
      const convertBufferView = new Uint8Array(convertBuffer);
      view.set(convertBufferView, 1);

      this.privateKey = new asn1js.OctetString({ valueHex: buffer });
    } else {
      this.privateKey = new asn1js.OctetString({ valueHex: convertBuffer.slice(0, coordinateLength) });
    }

    if (json.x && json.y) {
      this.publicKey = new ECPublicKey({ json });
    }
  }

}

[ Dauer der Verarbeitung: 0.28 Sekunden  (vorverarbeitet)  ]