docs: def gpg_decrypt( fd_in, path_out, sender_key_info, my_key_info, passphrase=None, config_dir=None ):
      """
      Decrypt a stream of data using key info 
      for a private key we own.
      @my_key_info and @sender_key_info should be data returned by gpg_app_get_key
      {
          'key_id': ...
          'key_data': ...
          'app_name': ...
      }
      Return {'status': True, 'sig': ...} on success
      Return {'status': True} on succes
      Return {'error': ...} on error
      """
  
      if config_dir is None:
          config_dir = get_config_dir()
  
      # ingest keys 
      tmpdir = make_gpg_tmphome( prefix="decrypt", config_dir=config_dir )
      res = gpg_stash_key( "decrypt", sender_key_info['key_data'], config_dir=config_dir, gpghome=tmpdir )
      if res is None:
          shutil.rmtree(tmpdir)
          return {'error': 'Failed to stash key %s' % sender_key_info['key_id']}
  
      try:
          my_privkey = gpg_export_key( my_key_info['app_name'], my_key_info['key_id'], include_private=True, config_dir=config_dir )
      except:
          shutil.rmtree(tmpdir)
          return {'error': 'Failed to load local private key for %s' % my_key_info['key_id']}
  
      res = gpg_stash_key( "decrypt", my_privkey, config_dir=config_dir, gpghome=tmpdir )
      if res is None:
          shutil.rmtree(tmpdir)
          return {'error': 'Failed to load private key'}
  
      # do the decryption 
      gpg = gnupg.GPG( homedir=tmpdir )
      res = gpg.decrypt_file( fd_in, passphrase=passphrase, output=path_out, always_trust=True )
      shutil.rmtree(tmpdir)
  
      if res.status != 'decryption ok':
          log.debug("decrypt_file: %s" % res.__dict__)
          return {'error': 'Failed to decrypt data'}
  
      log.debug("decryption succeeded from keys in %s" % config_dir)
      return {'status': True}