Skip to content

Commit

Permalink
v0.4.3 update - fixed __init__() bug not setting user fingerprint
Browse files Browse the repository at this point in the history
  • Loading branch information
rmlibre committed Dec 16, 2019
1 parent 1564124 commit 1c19060
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 47 deletions.
11 changes: 9 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# Changes for version 0.4.2
# Changes for version 0.4.3
## Known Issues
- Because of Debian [bug #930665](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930665), and related GnuPG [bug #T4393](https://dev.gnupg.org/T4393), importing keys from the default keyserver [keys.openpgp.org](https://keys.openpgp.org/) doesn't work automatically on all systems. Not without email confirmation, at least. That's because the keyserver will not publish uid information attached to a key before a user confirms access to the email address assigned to the uploaded key. And, because GnuPG folks are still holding up the merging, and back-porting, of patches that would allow GnuPG to automatically handle keys without uids gracefully. This effects the `network_import()` method specifically, but also the `text_import()` and `file_import()` methods, if they happen to be passed a key or filename argument which refers to a key without uid information. The gpg2 binary in this package can be replaced manually if a user's system has access to a patched version.
- This program may only be reliably compatible with keys that are also created with this program. That's because our terminal parsing is reliant on specific metadata to be similar across all encountered keys. It seems most keys have successfully been parsed with recent updates, though more testing is needed.
- Currently, the package is part synchronous, and part asynchronous. This is not ideal, so a decision has to be made: either to stay mixed style, or choose one consistent style.
- We're still in unstable and have to build out our test suite. Contributions welcome.
## Minor Changes
- Changed package description to name more specifically the kind of ECC keys this package handles.
## Major Changes
- Fixed bug in `__init__()` caused by the set_base_command() not being called before the base commands are used. This leading to the fingerprint for a persistent user not being set automatically.


# Changes for version 0.4.2
## Minor Changes
- Added some keyword argument names to README.rst tutorials.
- Added section in README.rst about torification.
# Major Changes
## Major Changes
- Added a check in `encrypt()` for the recipient key in the local keyring which throws if it doesn't exist. This is to prevent gnupg from using wkd to contact the network to find the key on a keyserver.
- Added a new `torify=False` kwarg to `__init__()` which prepends `"torify"` to each gpg2 command if set to `True`. This will make sure that if gnupg makes any silent connections to keyservers or the web, that they are run through tor and don't expose a users ip address inadvertently.

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
This file is part of tiny_gnupg, a small-as-possible solution for
handling GnuPG ed-25519 ECC keys.
handling GnuPG ed25519 ECC keys.

Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
Copyright © 2019-2020 Gonzo Investigatory Journalism Agency, LLC
Expand Down
20 changes: 14 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tiny_gnupg - A small-as-possible solution for handling GnuPG ECC keys.
======================================================================
tiny_gnupg - A small-as-possible solution for handling GnuPG ed25519 ECC keys.
===============================================================================
A small, simple & intuitive wrapper for creating, using and managing
GnuPG's Ed-25519 curve keys. We are in favor of reducing code size and
complexity with strong and bias defaults over flexibility in the api.
Expand Down Expand Up @@ -162,11 +162,9 @@ Networking Example
# upload, and import keys. This provides a nice, default layer of
# privacy to our communication needs. Have fun little niblets!
These networking tools work off instances of aiohttp.ClientSession. To learn more about how to use their POST and GET requests, you can read the docs here_.

# These networking tools work off instances of aiohttp.ClientSession.
# To learn more about how to use their POST and GET requests, you
# can read the docs here:
# https://docs.aiohttp.org/en/stable/client_advanced.html#client-session
.. _here: https://docs.aiohttp.org/en/stable/client_advanced.html#client-session


About Torification
Expand Down Expand Up @@ -234,6 +232,16 @@ Extras
# And secret keys, but really, keep those safe! ->
run(gpg.file_export(path=path_to_file, uid=gpg.email, secret=True))
# The keys don't have to be exported to a file. Instead they can
# be exported as strings ->
my_key = gpg.text_export(uid=gpg.fingerprint)
# So can secret keys (Be careful!) ->
my_secret_key = gpg.text_export(gpg.fingerprint, secret=True)
# And they can just as easily be imported from strings ->
gpg.text_import(key=my_key)
# When a user is done with a key, it can be deleted from the package
# keyring like this ->
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is part of tiny_gnupg, a small-as-possible solution for
# handling GnuPG ed-25519 ECC keys.
# handling GnuPG ed25519 ECC keys.
#
# Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
# Copyright © 2019-2020 Gonzo Investigatory Journalism Agency, LLC
Expand All @@ -11,7 +11,7 @@
from setuptools import setup, find_packages

description = """
tiny_gnupg - A small-as-possible solution for handling GnuPG ed-25519 ECC keys.
tiny_gnupg - A small-as-possible solution for handling GnuPG ed25519 ECC keys.
""".replace("\n", "")

with open("README.rst", "r") as readme:
Expand Down
34 changes: 27 additions & 7 deletions tests/test_tiny_gnupg.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is part of tiny_gnupg, a small-as-possible solution for
# handling GnuPG ed-25519 ECC keys.
# handling GnuPG ed25519 ECC keys.
#
# Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
# Copyright © 2019-2020 Gonzo Investigatory Journalism Agency, LLC
Expand Down Expand Up @@ -41,9 +41,29 @@ def gpg():

def test_instance(gpg):
gpg.gen_key()
test_gpg = GnuPG(gpg.username, gpg.email, gpg.passphrase)
assert gpg.username == test_gpg.username
assert gpg.email == test_gpg.email
assert gpg.passphrase == test_gpg.passphrase
assert gpg.port == test_gpg.port
assert gpg.tor_port == test_gpg.tor_port
assert gpg.home == test_gpg.home
assert gpg.executable == test_gpg.executable
assert gpg._connector == test_gpg._connector
assert gpg._session == test_gpg._session
assert gpg._search_string == test_gpg._search_string
assert gpg.keyserver == test_gpg.keyserver
assert str(gpg.port) in gpg.keyserver
assert gpg.keyserver_export_api == test_gpg.keyserver_export_api
assert gpg.keyserver_verify_api == test_gpg.keyserver_verify_api
assert gpg.searchserver == test_gpg.searchserver
assert gpg.base_command == test_gpg.base_command
assert gpg.base_passphrase_command == test_gpg.base_passphrase_command
#
assert gpg.username == "testing_user"
assert gpg.email == "[email protected]"
assert gpg.fingerprint == "" or type(gpg.fingerprint) == str
assert len(gpg.fingerprint) == 40
assert type(gpg.fingerprint) == str
assert gpg.passphrase == "test_passphrase"
assert gpg.home.endswith("gpghome")
assert gpg.executable.endswith("gpg2")
Expand Down Expand Up @@ -106,10 +126,10 @@ def test_cipher(gpg):
uid=gpg.fingerprint,
sign=False,
)
assert gpg.decrypt(encrypted_message_0) == message + "\n"
assert gpg.decrypt(encrypted_message_1) == message + "\n"
assert gpg.decrypt(encrypted_message_2) == message + "\n"
assert gpg.decrypt(encrypted_message_3) == message + "\n"
assert gpg.decrypt(encrypted_message_0) == message
assert gpg.decrypt(encrypted_message_1) == message
assert gpg.decrypt(encrypted_message_2) == message
assert gpg.decrypt(encrypted_message_3) == message
signed_message_0 = gpg.sign(message)
signed_message_1 = gpg.sign(signed_message_0)
signed_message_2 = gpg.sign(signed_message_1)
Expand Down Expand Up @@ -192,7 +212,7 @@ async def gather_looper(gpg, uid):

async def looper(gpg, uid):
tasks = []
for i in range(5):
for i in range(4):
tasks.append(new_task(gpg.search(uid)))
return tasks

Expand Down
4 changes: 2 additions & 2 deletions tiny_gnupg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is part of tiny_gnupg, a small-as-possible solution for
# handling GnuPG ECC keys.
# handling GnuPG ed25519 ECC keys.
#
# Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
# Copyright © 2019-2020 Gonzo Investigatory Journalism Agency, LLC
Expand All @@ -8,6 +8,6 @@
# All rights reserved.
#

__version__ = "0.4.2"
__version__ = "0.4.3"

from .tiny_gnupg import GnuPG, __all__
54 changes: 27 additions & 27 deletions tiny_gnupg/tiny_gnupg.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is part of tiny_gnupg, a small-as-possible solution for
# handling GnuPG ECC keys.
# handling GnuPG ed25519 ECC keys.
#
# Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
# Copyright © 2019-2020 Gonzo Investigatory Journalism Agency, LLC
Expand Down Expand Up @@ -31,9 +31,9 @@ def __init__(
self.email = email
self.username = username
self.passphrase = passphrase
self.set_base_command(torify) # set before calling command()
self.set_fingerprint(email)
self.set_network_variables()
self.set_base_command(torify)

def set_homedir(self, path=HOME_PATH):
self.home = self.format_homedir(path)
Expand All @@ -51,6 +51,29 @@ def set_home_permissions(self, home):
except:
print(f"Invalid permission to modify home folder: {home}")

def set_base_command(self, torify=False):
torify = ["torify"] if torify else []
self.base_passphrase_command = torify + [
self.executable,
"--yes",
"--batch",
"--quiet",
"--homedir",
self.home,
"--pinentry-mode",
"loopback",
"--passphrase-fd",
"0",
]
self.base_command = torify + [
self.executable,
"--yes",
"--batch",
"--quiet",
"--homedir",
self.home,
]

def set_fingerprint(self, uid=""):
try:
self.fingerprint = self.key_fingerprint(uid)
Expand Down Expand Up @@ -124,29 +147,6 @@ async def post(self, url="", **kw):
async with self.network_post(url, **kw) as response:
return await response.text()

def set_base_command(self, torify=False):
torify = ["torify"] if torify else []
self.base_passphrase_command = torify + [
self.executable,
"--yes",
"--batch",
"--quiet",
"--homedir",
self.home,
"--pinentry-mode",
"loopback",
"--passphrase-fd",
"0",
]
self.base_command = torify + [
self.executable,
"--yes",
"--batch",
"--quiet",
"--homedir",
self.home,
]

def command(self, *options, with_passphrase=False):
if with_passphrase:
return self.base_passphrase_command + [*options]
Expand Down Expand Up @@ -270,7 +270,7 @@ def encrypt(self, message="", uid="", sign=True, local_user=""):
inputs = self.encode_inputs(self.passphrase, "y", message)
else:
inputs = self.encode_inputs(self.passphrase, message)
return self.read_output(command, inputs)
return self.read_output(command, inputs[:-1])

def decrypt(self, message=""):
command = self.command("-d", with_passphrase=True)
Expand All @@ -294,7 +294,7 @@ def sign(self, target="", local_user="", *, key=False):
"-as",
with_passphrase=True,
)
inputs = self.encode_inputs(self.passphrase, target)
inputs = self.encode_inputs(self.passphrase, target)[:-1]
else:
raise ValueError(f"key != boolean, {type(key)} given.")
return self.read_output(command, inputs)
Expand Down

0 comments on commit 1c19060

Please sign in to comment.