Decryption with passphrase hangs unless output is specified

Issue #85 invalid
Andy Freeland
created an issue

gpg.decrypt_file(fp, passphrase='foo') hangs indefinitely with GPG 2.2, but gpg.decrypt_file(fp, passphrase='foo', output='test.txt') decrypts as expected.

Using python-gnupg==0.4.1, Python 2.7.12.

$ gpg --version
gpg (GnuPG) 2.2.0
libgcrypt 1.8.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /Users/andy/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Comments (5)

  1. Andy Freeland reporter

    Hmm, I can actually reproduce with GPG 2.0.28 as well:

    gpg (GnuPG) 2.0.28
    libgcrypt 1.5.3
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    Home: ~/.gnupg
    Supported algorithms:
    Pubkey: RSA, ELG, DSA
    Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
            CAMELLIA128, CAMELLIA192, CAMELLIA256
    Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
    Compression: Uncompressed, ZIP, ZLIB, BZIP2
    

    Interestingly, the files seem to be decrypting successfully, because if I ctrl-C the process python-gnupg's debug outputs some of the chunks of the file.

    Here's my application code:

    gpg = gnupg.GPG(
        gpgbinary='gpg',
        gnupghome='path/to/homedir',
    )
    decrypted = gpg.decrypt_file(
       fp,
       passphrase='some passphrase',
    )
    
  2. Vinay Sajip repo owner

    I created the following script:

    import logging
    import os
    import pprint
    import sys
    
    from gnupg import GPG
    
    
    def generate_key(gpg, first_name, last_name, domain, passphrase=None):
        "Generate a key"
        params = {
            'Key-Type': 'DSA',
            'Key-Length': 1024,
            'Subkey-Type': 'ELG-E',
            'Subkey-Length': 2048,
            'Name-Comment': 'A test user',
            'Expire-Date': 0,
        }
        options = gpg.options or []
        if '--debug-quick-random' in options or '--quick-random' in options:
            # If using the fake RNG, a key isn't regarded as valid
            # unless its comment has the text (insecure!) in it.
            params['Name-Comment'] = 'A test user (insecure!)'
        params['Name-Real'] = '%s %s' % (first_name, last_name)
        params['Name-Email'] = ("%s.%s@%s" % (first_name, last_name,
                                              domain)).lower()
        if passphrase is None:
            passphrase = ("%s%s" % (first_name[0], last_name)).lower()
        params['Passphrase'] = passphrase
        cmd = gpg.gen_key_input(**params)
        return gpg.gen_key(cmd)
    
    def main():
        gpg = os.environ.get('GPGBINARY', 'gpg')
        g = GPG(gnupghome='keys', gpgbinary=gpg)
        if len(sys.argv) > 1 and sys.argv[1] == 'make':
            key = generate_key(g, 'Andrew', 'Able', 'test.com', 'aable')
            pprint.pprint(g.list_keys())
        else:
            print(g.version)
            with open('enc.bin', 'rb') as fp:
                decrypted = g.decrypt_file(fp, passphrase='aable')
            print(decrypted)
        print('Done.')
    
    if __name__ == '__main__':
        logging.basicConfig(level=logging.DEBUG, filename='testdecrypt.log',
                            filemode='w', format='%(message)s')
        try:
            rc = main()
        except Exception as e:
            print('Failed: %s' % e)
            rc = 1
        sys.exit(rc)
    

    Then, ensuring that python-gnupg is on the Python path, I ran the following:

    $ mkdir keys
    $ python testdecrypt.py make
    

    The keys subdirectory is populated with a new test key. I then used the following to encrypt some data:

    $ echo -n Hello, world! | gpg --encrypt --homedir keys -r able > enc.bin
    

    This creates an encrypted file in enc.bin. I then ran the following commands to decrypt, with gpg and gpg2:

    $ python testdecrypt.py
    (1, 4, 22)
    Hello, world!
    Done.
    $ GPGBINARY=gpg2 python testdecrypt.py
    (2, 0, 30)
    Hello, world!
    Done.
    
  3. Vinay Sajip repo owner

    I ran the above script on Linux and OS X and encountered no errors. So marking as invalid - you will need to try with the attached script and reopen with more information if it doesn't work on your system.

  4. Log in to comment