@namespace("keybase.1")

protocol pgp {
  import idl "common.avdl";
  import idl "identify_common.avdl";

  enum SignMode {
    ATTACHED_0,
    DETACHED_1,
    CLEAR_2
  }

  record PGPSignOptions {
    string keyQuery;
    SignMode mode;
    boolean binaryIn;
    boolean binaryOut;
  }

  // Return a source that we should be writing to.
  void pgpSign(int sessionID, Stream source, Stream sink, PGPSignOptions opts);

  /**
    Download PGP keys for tracked users and update the local GPG keyring.
    If usernames is nonempty, update only those users.
    */
  void pgpPull(int sessionID, array<string> userAsserts);

  record PGPEncryptOptions {
    array<string> recipients; // user assertions
    boolean noSign;
    boolean noSelf;
    boolean binaryOut;
    string keyQuery;
  }

  void pgpEncrypt(int sessionID, Stream source, Stream sink, PGPEncryptOptions opts);

  /**
    PGPSigVerification is returned by pgpDecrypt and pgpVerify with information
    about a the signature verification. If isSigned is false, there was no
    signature, and the rest of the fields should be ignored.
    */
  record PGPSigVerification {
    boolean isSigned; // true if message was signed
    boolean verified; // true if signature verified
    User signer; // who signed it
    PublicKey signKey; // the pub key that signed it
  }

  record PGPDecryptOptions {
    boolean assertSigned;
    string signedBy; // assert that signature made by this user
  }

  PGPSigVerification pgpDecrypt(int sessionID, Stream source, Stream sink, PGPDecryptOptions opts);

  record PGPVerifyOptions {
    string signedBy; // assert that signature made by this user
    bytes signature; // detached signature data (binary or armored), can be empty
  }

  PGPSigVerification pgpVerify(int sessionID, Stream source, PGPVerifyOptions opts);

  void pgpImport(int sessionID, bytes key, boolean pushSecret);

  record KeyInfo {
    string fingerprint;
    string key;
    string desc;
  }

  // If 'secret' is true, you get at most one key back.
  record PGPQuery {
    boolean secret;
    string query;
    boolean exactMatch;
  }

  /**
    Exports active PGP keys. Only allows armored export.
    */
  array<KeyInfo> pgpExport(int sessionID, PGPQuery options);
  array<KeyInfo> pgpExportByFingerprint(int sessionID, PGPQuery options);
  array<KeyInfo> pgpExportByKID(int sessionID, PGPQuery options);

  @lint("ignore")
  record PGPCreateUids {
    boolean useDefault;
    array<PGPIdentity> ids;
  }

  @lint("ignore")
  void pgpKeyGen(int sessionID, int primaryBits, int subkeyBits, PGPCreateUids createUids, boolean allowMulti, boolean doExport, boolean pushSecret);

  @lint("ignore")
  void pgpKeyGenDefault(int sessionID, PGPCreateUids createUids);

  void pgpDeletePrimary(int sessionID);

  /**
    Select an existing key and add to Keybase.
    */
  void pgpSelect(int sessionID, string fingerprintQuery, boolean allowMulti, boolean skipImport, boolean onlyImport);

  /**
    Push updated key(s) to the server.
    */
  void pgpUpdate(int sessionID, boolean all, array<string> fingerprints);

  /**
    Export all pgp keys in lksec, then if doPurge is true, remove the keys from lksec.
    */
  record PGPPurgeRes {
    array<string> filenames;
  }
  PGPPurgeRes pgpPurge(int sessionID, boolean doPurge);

  /**
    Dismiss the PGP unlock via secret_store_file notification.
    */
  void pgpStorageDismiss(int sessionID);
}
