-
Notifications
You must be signed in to change notification settings - Fork 688
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pretty_bad_protocol: Support exporting encrypted secret keys
As part of the Sequoia migration, we want to export secret keys out of the GPG keyring and into our new database storage. So, have the gpg.export_keys() function accept a passphrase to export encrypted keys that GPG wants a passphrase for. Internally we switch it to use the `_handle_io` function since that has support for taking passphrases; the one weird thing is that it requires an input file (e.g. if you were encrypting a file) but since there's no input here an empty temporary file works just fine. For whatever reason I couldn't get a simple `p.stdin.write(passphrase)` to work, it would hang on stdout, which is probably related to the pre-existing comment about "stdout will be empty in case of failure"... A new test generates a new GPG key pair, exports the public and secret keys from the keyring and then encrypts and decrypts a message using Sequoia to test compatibility. It also checks a few error cases like invalid fingerprint and missing secret key. Refs #6802.
- Loading branch information
Showing
3 changed files
with
67 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from pathlib import Path | ||
|
||
import pretty_bad_protocol as gnupg | ||
|
||
import redwood | ||
|
||
|
||
def test_gpg_export_keys(tmp_path): | ||
gpg = gnupg.GPG( | ||
binary="gpg2", | ||
homedir=str(tmp_path), | ||
options=["--pinentry-mode loopback", "--trust-model direct"], | ||
) | ||
passphrase = "correcthorsebatterystaple" | ||
gen_key_input = gpg.gen_key_input( | ||
passphrase=passphrase, | ||
name_email="[email protected]", | ||
key_type="RSA", | ||
key_length=4096, | ||
name_real="example", | ||
) | ||
fingerprint = gpg.gen_key(gen_key_input) | ||
print(fingerprint) | ||
public_key = gpg.export_keys(fingerprint) | ||
assert public_key.startswith("-----BEGIN PGP PUBLIC KEY BLOCK-----") | ||
secret_key = gpg.export_keys(fingerprint, secret=True, passphrase=passphrase) | ||
assert secret_key.startswith("-----BEGIN PGP PRIVATE KEY BLOCK-----") | ||
|
||
# Now verify the exported key pair is usable by Sequoia | ||
message = "GPG to Sequoia-PGP, yippe!" | ||
ciphertext = tmp_path / "encrypted.asc" | ||
redwood.encrypt_message([public_key], message, ciphertext) | ||
decrypted = redwood.decrypt(ciphertext.read_bytes(), secret_key, passphrase) | ||
assert decrypted == message | ||
|
||
# Test some failure cases for exporting the secret key: | ||
# bad passphrase | ||
assert gpg.export_keys(fingerprint, secret=True, passphrase="wrong") == "" | ||
# exporting a non-existent secret key (import just the public key and try to export) | ||
journalist_public_key = ( | ||
Path(__file__).parent / "files" / "test_journalist_key.pub" | ||
).read_text() | ||
journalist_fingerprint = gpg.import_keys(journalist_public_key).fingerprints[0] | ||
assert gpg.export_keys(journalist_fingerprint, secret=True, passphrase=passphrase) == "" |