Open pajuscz opened 2 years ago
The key I am trying to import is:
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQdGBGJy/wcBEAC6IvcYBmhTnFZNi+qYMTwPf2pixNx6IWUQZaGlbEBStuSucWZ2
MuAVDeL1+ahOUanResjfLgk0ivZ5ZykfDR4wrW9gqoahLFFu2Xb2S6eyIaba2Phm
Z+0xOLOdtambrxZDuN+/NCZoXE2EpZcVyeR4tiN1GrjNqF7jMwYBL8tjPGc1gLu+
When I do gpg --import import.key
I am prompted for passpharse,
When I use GPG.import_keys()
I don't know how to pass the passpharse and as a result I am getting:
'1' (4560127240) = {str} 'Invalid Certificate'
'0' (4563316368) = {str} 'No specific reason given'
'3' (4561059072) = {str} 'Certificate Chain too long'
'2' (4559698000) = {str} 'Issuer Certificate missing'
'4' (4561059112) = {str} 'Error storing certificate'
'17' (4570749568) = {str} 'Contains private key'
'16' (4570747448) = {str} 'Contains private key'
'1' (4560127240) = {str} 'Entirely new key'
'0' (4563316368) = {str} 'Not actually changed'
'2' (4559698000) = {str} 'New user IDs'
'4' (4561059112) = {str} 'New signatures'
'8' (4563315368) = {str} 'New subkeys'
u'gpg: no valid OpenPGP data found.
[GNUPG:] NODATA 1
gpg: Total number processed: 0
[GNUPG:] IMPORT_RES 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
'
The actual stacktrace with exception is here:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "lib/python2.7/site-packages/pretty_bad_protocol/_meta.py", line 670, in _read_response
result._handle_status(keyword, value)
File "/lib/python2.7/site-packages/pretty_bad_protocol/_parsers.py", line 1304, in _handle_status
raise ValueError("Unknown status message: %r" % key)
ValueError: Unknown status message: u'USERID_HINT'
Exception in thread Thread-47:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/lib/python2.7/site-packages/pretty_bad_protocol/_meta.py", line 670, in _read_response
result._handle_status(keyword, value)
File "lib/python2.7/site-packages/pretty_bad_protocol/_parsers.py", line 1304, in _handle_status
raise ValueError("Unknown status message: %r" % key)
ValueError: Unknown status message: u'USERID_HINT'
I am using options=['--yes', '--pinentry-mode loopback']
when initializing the GPG object if that helps.
If I don't use it - there is no error, nor exception but the secret key is not imported - only the public key.
Hi @pajuscz , I ran into this issue as well. You can simply pass passphrase
to the _handle_io()
as it is an already an available parameter when self._handle_io() is called within decrypt_files()
Changes made within gnupg.py:
def import_keys(self, key_data, passphrase=False):
and
self._handle_io(['--import'], data, result, passphrase, binary=True)
I tested these changes on my machine and I had a few unknown statuses which I had to patch as well within _parsers.py
but after that I had no issues importing keys with passphrases. The other solution would be likely to import keys with no passphrase.
def import_keys(self, key_data, passphrase=False):
"""
Import the key_data into our keyring.
>>> import shutil
>>> shutil.rmtree("doctests")
>>> gpg = gnupg.GPG(homedir="doctests")
>>> inpt = gpg.gen_key_input()
>>> key1 = gpg.gen_key(inpt)
>>> print1 = str(key1.fingerprint)
>>> pubkey1 = gpg.export_keys(print1)
>>> seckey1 = gpg.export_keys(print1,secret=True)
>>> key2 = gpg.gen_key(inpt)
>>> print2 = key2.fingerprint
>>> seckeys = gpg.list_keys(secret=True)
>>> pubkeys = gpg.list_keys()
>>> assert print1 in seckeys.fingerprints
>>> assert print1 in pubkeys.fingerprints
>>> str(gpg.delete_keys(print1))
'Must delete secret key first'
>>> str(gpg.delete_keys(print1,secret=True))
'ok'
>>> str(gpg.delete_keys(print1))
'ok'
>>> pubkeys = gpg.list_keys()
>>> assert not print1 in pubkeys.fingerprints
>>> result = gpg.import_keys(pubkey1)
>>> pubkeys = gpg.list_keys()
>>> seckeys = gpg.list_keys(secret=True)
>>> assert not print1 in seckeys.fingerprints
>>> assert print1 in pubkeys.fingerprints
>>> result = gpg.import_keys(seckey1)
>>> assert result
>>> seckeys = gpg.list_keys(secret=True)
>>> assert print1 in seckeys.fingerprints
"""
## xxx need way to validate that key_data is actually a valid GPG key
## it might be possible to use --list-packets and parse the output
result = self._result_map['import'](self)
log.info('Importing: %r', key_data[:256])
data = _make_binary_stream(key_data, self._encoding)
self._handle_io(['--import'], data, result, passphrase, binary=True)
data.close()
return result
I came across this while looking into this closed issue: https://github.com/isislovecruft/python-gnupg/issues/194
I wasn't able to import private key with passpharse using the same method. What happens is that public key is imported, but not the secret key - I cannot decrypt data after I do the import.
While looking into the code I don't think it is possible to import a key using passpharse, because the passpharse is set to False by default.
The _handle_io:
def _handle_io(self, args, file, result, passphrase=False, binary=False):
called from
import_keys(self, key_data)
is called in this fashion:self._handle_io(['--import'], data, result, binary=True)
I don't see a way to pass passphase there.When I 'hard-code' the passphasee into the
self._handle_io(['--import'], data, result, passphrase='secret', binary=True)
It works as expected. I think there should be a posibility to pass passpharse as an argument into GPG.import_keys()