From 0dfd1ec7127ca4b6f3f73027512ec6f9cf4fcbec Mon Sep 17 00:00:00 2001 From: q Date: Wed, 31 Jul 2024 16:31:08 +0300 Subject: [PATCH] new version with passphrase detection --- Bakefile | 20 ++++++++++++++++++++ qgpg/__init__.py | 32 +++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/Bakefile b/Bakefile index 2f6d567..944f5a8 100644 --- a/Bakefile +++ b/Bakefile @@ -37,6 +37,7 @@ test_encrypt() { # Run encryption code set -e GPGPASS=secret @ qgpg -k --key key2 + qgpg -i --key key2 @ qgpg -e --key key2.pub datadir/folder1/1testfile @ qgpg -e --key key2.pub datadir/folder1/1testfile datadir/1testfile.encrypted.gpg @ qgpg -e --key key2.pub -r datadir @@ -46,6 +47,25 @@ test_encrypt() { @ hash-update -t sha1 -f sha1sum.txt -r datadir } +test_encrypt_no_phrase() { + # Prepare + cd ~/tmp/ + . useve-runner + useve qgpg + rm -fr key2* datadir datadir.encrypted datadir.plain sha1sum.txt + @ mkdir -p datadir + @ dd if=/dev/random of=datadir/testfile bs=3024 count=102400 + # Run encryption code + set -e + GPGPASS="" @ qgpg -k --key key2 + qgpg -i --key key2 + @ qgpg -e --key key2.pub -r datadir datadir.encrypted + @ qgpg -d --key key2 -r datadir.encrypted datadir.plain + @ hash-update -t sha1 -f sha1sum.txt -r datadir datadir.encrypted datadir.plain + cat sha1sum.txt +} + + test_decrypt() { cd ~/tmp/ . useve-runner diff --git a/qgpg/__init__.py b/qgpg/__init__.py index bd69cf1..b5167b5 100644 --- a/qgpg/__init__.py +++ b/qgpg/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -__version__ = "20240730.0" +__version__ = "20240731.0" import argparse import os @@ -246,6 +246,7 @@ class Processor: self.gpg.encoding = "utf-8" self.symmetric = self.opts.key is None self.suffix = ".gpg" + self.has_phrase = None self.phrase = None if self.opts.command == "keygen": @@ -259,6 +260,7 @@ class Processor: if self.opts.command in ("encrypt", "decrypt"): if not self.symmetric: import_result = self.gpg.import_keys_file(self.opts.key) + self.check_key_phrase(import_result.fingerprints[0]) filelist = self.get_filelist(self.opts.path, self.opts.recursive, self.opts.command) if self.opts.command == "encrypt": @@ -282,6 +284,17 @@ class Processor: self.homedir.cleanup() + def check_key_phrase(self, fingerprint): + """Set self.has_phrase to True, if imported private key requires passphrase""" + + if self.symmetric: + return + + self.has_phrase = self.gpg.export_keys(fingerprint, True, passphrase="") == "" + if not self.has_phrase: + # When no passphrase, it needs to be something, not empty. + self.phrase = " " + def set_phrase(self, twice=False): """Sets self.phrase. if `twice` asks user for phrase twice.""" if not self.phrase is None: @@ -302,12 +315,17 @@ class Processor: if phrase2 != self.phrase: print("Passphrases do not match!") sys.exit(1) - if self.phrase == "" and self.symmetric: - print("Symmetric passphrase required!") - sys.exit(1) + if self.phrase == "": + if self.symmetric: + print("Symmetric passphrase required!") + sys.exit(1) + else: + if self.opts.command == "decrypt": + # for asymmetric decryption, phrase needs to be set non-zero even if no passphrase used + self.phrase = " " def get_filelist(self, root, recurse, direction): - """returns a file list: if encrypting, lists files without .gpg, if decrytping, lists files with .gpg""" + """returns a file list: if encrypting, lists files without .gpg, if decrypting, lists files with .gpg""" if not recurse: if os.path.isfile(root): return [root] @@ -364,6 +382,7 @@ class Processor: key_type = "NA" if key.get("type") == "sec": key_type = "Private" + self.check_key_phrase(key.get("fingerprint")) if key.get("type") == "pub": key_type = "Public" @@ -381,6 +400,9 @@ Type: {key_type} Date: {key_date} KeyLength: {key.get('length')}""" ) + if key_type == "Private": + print(f"HasPhrase: {self.has_phrase}") + return import_result = self.gpg.import_keys_file(self.opts.key) if len(import_result.fingerprints) == 0: