File

src/app/_pgp/pgp-signer.ts

Index

Methods

Methods

digest
digest()
Returns : string
import {MutableKeyStore} from '@app/_pgp/pgp-key-store';
import {LoggingService} from '@app/_services/logging.service';

const openpgp = require('openpgp');

interface Signable {
  digest(): string;
}

type Signature = {
  engine: string
  algo: string
  data: string
  digest: string;
};

interface Signer {
  onsign(signature: Signature): void;
  onverify(flag: boolean): void;
  fingerprint(): string;
  prepare(material: Signable): boolean;
  verify(digest: string, signature: Signature): void;
  sign(digest: string): Promise<void>;
}

class PGPSigner implements Signer {

  engine = 'pgp';
  algo = 'sha256';
  dgst: string;
  signature: Signature;
  keyStore: MutableKeyStore;
  onsign: (signature: Signature) => void;
  onverify: (flag: boolean) => void;
  loggingService: LoggingService;

  constructor(keyStore: MutableKeyStore) {
    this.keyStore = keyStore;
    this.onsign = (signature: Signature) => {};
    this.onverify = (flag: boolean) => {};
  }

  public fingerprint(): string {
    return this.keyStore.getFingerprint();
  }

  public prepare(material: Signable): boolean {
    this.dgst = material.digest();
    return true;
  }

  public verify(digest: string, signature: Signature): void {
    openpgp.signature.readArmored(signature.data).then((sig) => {
      const opts = {
        message: openpgp.cleartext.fromText(digest),
        publicKeys: this.keyStore.getTrustedKeys(),
        signature: sig,
      };
      openpgp.verify(opts).then((v) => {
        let i = 0;
        for (i = 0; i < v.signatures.length; i++) {
          const s = v.signatures[i];
          if (s.valid) {
            this.onverify(s);
            return;
          }
        }
        this.loggingService.sendErrorLevelMessage(`Checked ${i} signature(s) but none valid`, this, {error: '404 Not found!'});
        this.onverify(false);
      });
    }).catch((e) => {
      this.loggingService.sendErrorLevelMessage(e.message, this, {error: e});
      this.onverify(false);
    });
  }

  public async sign(digest: string): Promise<void> {
    const m = openpgp.cleartext.fromText(digest);
    const pk = this.keyStore.getPrivateKey();
    if (!pk.isDecrypted()) {
      const password = window.prompt('password');
      await pk.decrypt(password);
    }
    const opts = {
      message: m,
      privateKeys: [pk],
      detached: true,
    };
    openpgp.sign(opts).then((s) => {
      this.signature = {
        engine: this.engine,
        algo: this.algo,
        data: s.signature,
        // TODO: fix for browser later
        digest,
      };
      this.onsign(this.signature);
    }).catch((e) => {
      this.loggingService.sendErrorLevelMessage(e.message, this, {error: e});
      this.onsign(undefined);
    });
  }
}

export {
  Signable,
  Signature,
  Signer,
  PGPSigner
};

result-matching ""

    No results matching ""