summaryrefslogtreecommitdiff
path: root/alot/crypto.py
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2017-11-15 23:12:22 +0100
committerRuben Pollan <meskio@sindominio.net>2018-10-08 11:45:29 -0500
commit01b8ff8391b0b4206ad59d4f6b9c0f5cd50cafbc (patch)
treed668f4db17e451a692c5a68e69d63fc84c1dcddd /alot/crypto.py
parent4a6711865b154152d4978e8316727f4902de3e02 (diff)
crypto: Use session-key to decrypt messages if present in the index
notmuch caches the OpenPGP session keys if configured to do so. See index.decrypt on: https://notmuchmail.org/manpages/notmuch-config-1/ Using the cached session key decryption of messages can be done without the need of having the private OpenPGP key. There is some speed up on decryption, mostly notable on long encrypted threads.
Diffstat (limited to 'alot/crypto.py')
-rw-r--r--alot/crypto.py31
1 files changed, 30 insertions, 1 deletions
diff --git a/alot/crypto.py b/alot/crypto.py
index a05db2fc..38b8727a 100644
--- a/alot/crypto.py
+++ b/alot/crypto.py
@@ -206,15 +206,22 @@ def verify_detached(message, signature):
raise GPGProblem(str(e), code=e.getcode())
-def decrypt_verify(encrypted):
+def decrypt_verify(encrypted, session_keys=None):
"""Decrypts the given ciphertext string and returns both the
signatures (if any) and the plaintext.
:param bytes encrypted: the mail to decrypt
+ :param list[str] session_keys: a list OpenPGP session keys
:returns: the signatures and decrypted plaintext data
:rtype: tuple[list[gpg.resuit.Signature], str]
:raises: :class:`~alot.errors.GPGProblem` if the decryption fails
"""
+ if session_keys is not None:
+ try:
+ return _decrypt_verify_session_keys(encrypted, session_keys)
+ except GPGProblem:
+ pass
+
ctx = gpg.core.Context()
try:
plaintext, _, verify_result = ctx.decrypt(encrypted, verify=True)
@@ -228,6 +235,28 @@ def decrypt_verify(encrypted):
return sigs, plaintext
+def _decrypt_verify_session_keys(encrypted, session_keys):
+ """Decrypts the given ciphertext string using the session_keys
+ and returns both the signatures (if any) and the plaintext.
+
+ :param bytes encrypted: the mail to decrypt
+ :param list[str] session_keys: a list OpenPGP session keys
+ :returns: the signatures and decrypted plaintext data
+ :rtype: tuple[list[gpg.resuit.Signature], str]
+ :raises: :class:`~alot.errors.GPGProblem` if the decryption fails
+ """
+ for key in session_keys:
+ ctx = gpg.core.Context()
+ ctx.set_ctx_flag("override-session-key", key)
+ try:
+ (plaintext, _, verify_result) = ctx.decrypt(
+ encrypted, verify=True)
+ except gpg.errors.GPGMEError as e:
+ continue
+ return verify_result.signatures, plaintext
+ raise GPGProblem("No valid session key", code=GPGCode.NOT_FOUND)
+
+
def validate_key(key, sign=False, encrypt=False):
"""Assert that a key is valide and optionally that it can be used for
signing or encrypting. Raise GPGProblem otherwise.