Successfully decrypts but returns ok = false, status = " " and returncode = 0
nickolasclarke opened this issue · 2 comments
Describe the bug
A clear and concise description of what the bug is.
I am attempting to decrypt file that appears to successfully decrypt with legible data in decrypted.data
, but still results in decrypted.ok == false
, decrypted.status == '
and decrypted.returncode == 0
.
I am decrypting a file that is being read from a temporary file with:
def decrypt(encrypted_data, keypair, passphrase=None):
"""
decrypt and return a pgp encrypted payload
Args:
input_data: the pgp encrypted data
keypair: the private key to be used to decrypt
It is a encoded string because we expect to extract this from an AWS
secret
passphrase: the passphrase for the keypair, if any.
Returns:
decrypted data
"""
# Load keys, decrypt file
with tempfile.TemporaryDirectory(".gpg") as gnupghome:
gpg = gnupg.GPG(gnupghome=gnupghome)
gpg.encoding = ENCODING
result = gpg.import_keys(keypair)
if result.returncode != 0:
raise Exception(f"Could not import keys: {result.stderr}")
fp = result.fingerprints[0]
gpg.trust_keys(fp, "TRUST_ULTIMATE")
decrypted = gpg.decrypt(encrypted_data, passphrase=passphrase)
error_msg = f"Could not decrypt data: {decrypted.status}\n{decrypted.stderr}"
#If the file cannot be MDC verified, ignore and try again.
if not decrypted.ok and "--ignore-mdc-error" in decrypted.stderr:
try:
decrypted = gpg.decrypt(
encrypted_data, passphrase=passphrase, extra_args=["--ignore-mdc-error"]
)
logger.warn("Decryption was forced to fail, decrypted with --ignore-mdc-error")
except Exception as e:
raise Exception(error_msg, e)
if not decrypted.ok:
raise Exception(error_msg)
return decrypted.data.decode()
#file_path is generator of files read from an sftp and placed locally.
with open(file_path, "r+") as f:
decrypted_data = decrypt(f.read(), pgp_secret_key)
f.seek(0)
f.write(decrypted_data)
f.close()
Running this through debugger, I extracted the exact gpg command being passed by the library and it appears to decrypt and exit as expected.
gpg --status-fd 2 --no-tty -vv --fixed-list-mode --batch --with-colons --homedir /tmp/tmpshjftsk6.gpg --decrypt /tmp/tmp8zvy5hqe/my_file.csv.gpg
gpg: armor: BEGIN PGP MESSAGE
gpg: armor header: Version: BCPG v1.60
# off=0 ctb=cb tag=11 hlen=3 plen=1604 new-ctb
:literal data packet:
mode b (62), created 1664574847, name="my_file.csv",
raw data: 1549 bytes
gpg: original file name='my_file.csv'
[GNUPG:] PLAINTEXT 62 1664574847 my_file.csv
[GNUPG:] PLAINTEXT_LENGTH 1549
<private data redacted>
I've included a screenshot of the VSCode debugger state for the decrypted
object at the point of failure.
To Reproduce
Steps to reproduce the behavior:
- Go to '...'
- Click on '....'
- Scroll down to '....'
- See error
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Environment
- OS, including version
- Ubuntu 20.04.5 LTS
- Version of this library
- 0.5.0
- gpg --version
gpg (GnuPG) 2.2.19
libgcrypt 1.8.5
Additional information
Add any other information about the problem here.
Looking more into how you are handling handle state, it looks like STDERR output doesnt contain any of the general status codes you are expecting update ok
and status
if I'm understanding how handle_status()
is used. Is that correct? Should you always expect to get an DECRYPTION_OKAY
or another header to denote success?
GNUPG:] PLAINTEXT 62 1664574847 my_file.csv
[GNUPG:] PLAINTEXT_LENGTH 1549
Yes, we expect to see specific signals from gpg
to indicate that an operation has succeeded. Version 2.2.19 is quite old (current LTS version is 2.2.39, libgcrypt LTS is at 1.8.9) and gpg
often has regressions in its behaviour. Can you upgrade to a later gpg
version and see if that works? I think this is a gpg
bug, but as there are much newer versions of gpg 2.2.x available, the problem may already have been fixed there. So I'll close the issue here, as I don't think this is a python-gnupg
bug.