def gpg_encrypt( fd_in, path_out, sender_key_info, recipient_key_infos, passphrase=None, config_dir=None ):
    """
    Encrypt a stream of data for a set of keys.
    @sender_key_info should be a dict with
    {
        'key_id': ...
        'key_data': ...
        'app_name'; ...
    }
    Return {'status': True} on success
    Return {'error': ...} on error
    """

    if config_dir is None:
        config_dir = get_config_dir()

    # ingest keys 
    tmpdir = make_gpg_tmphome( prefix="encrypt", config_dir=config_dir )
    for key_info in recipient_key_infos:
        res = gpg_stash_key( "encrypt", key_info['key_data'], config_dir=config_dir, gpghome=tmpdir )
        if res is None:
            shutil.rmtree(tmpdir)
            return {'error': 'Failed to stash key %s' % key_info['key_id']}

    # copy over our key
    try:
        sender_privkey = gpg_export_key( sender_key_info['app_name'], sender_key_info['key_id'], include_private=True, config_dir=config_dir )
    except Exception, e:
        log.exception(e)
        shutil.rmtree(tmpdir)
        return {'error': 'No such private key'}

    res = gpg_stash_key( "encrypt", sender_privkey, config_dir=config_dir, gpghome=tmpdir )
    if res is None:
        shutil.rmtree(tmpdir)
        return {'error': 'Failed to load sender private key'}

    recipient_key_ids = [r['key_id'] for r in recipient_key_infos]

    # do the encryption
    gpg = gnupg.GPG( homedir=tmpdir )
    res = gpg.encrypt_file( fd_in, recipient_key_ids, sign=sender_key_info['key_id'], passphrase=passphrase, output=path_out, always_trust=True )
    shutil.rmtree(tmpdir)

    if res.status != 'encryption ok':
        log.debug("encrypt_file error: %s" % res.__dict__)
        log.debug("recipients: %s" % recipient_key_ids)
        log.debug("signer: %s" % sender_key_info['key_id'])
        return {'error': 'Failed to encrypt data'}
    
    return {'status': True}
Encrypt a stream of data for a set of keys.
    @sender_key_info should be a dict with
    {
        'key_id': ...
        'key_data': ...
        'app_name'; ...
    }
    Return {'status': True} on success
    Return {'error': ...} on error