Skip to content

Commit

Permalink
Merge pull request #1329 from meskio/session_key_bad_signature
Browse files Browse the repository at this point in the history
crypto: deal with bad signatures on session-decrypt
  • Loading branch information
dcbaker committed Nov 1, 2018
2 parents f1972c5 + 48a543a commit f942fa7
Showing 1 changed file with 28 additions and 17 deletions.
45 changes: 28 additions & 17 deletions alot/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def verify_detached(message, signature):
:param bytes signature: the OpenPGP signature to verify
:returns: a list of signatures
:rtype: list[gpg.results.Signature]
:raises: :class:`~alot.errors.GPGProblem` if the verification fails
:raises alot.errors.GPGProblem: if the verification fails
"""
ctx = gpg.core.Context()
try:
Expand All @@ -214,7 +214,7 @@ def decrypt_verify(encrypted, session_keys=None):
: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
:raises alot.errors.GPGProblem: if the decryption fails
"""
if session_keys is not None:
try:
Expand All @@ -223,16 +223,7 @@ def decrypt_verify(encrypted, session_keys=None):
pass

ctx = gpg.core.Context()
try:
plaintext, _, verify_result = ctx.decrypt(encrypted, verify=True)
sigs = verify_result.signatures
except gpg.errors.GPGMEError as e:
raise GPGProblem(str(e), code=e.getcode())
except gpg.errors.BadSignatures as e:
plaintext, _, _ = ctx.decrypt(encrypted, verify=False)
sigs = e.result.signatures

return sigs, plaintext
return _decrypt_verify_with_context(ctx, encrypted)


def _decrypt_verify_session_keys(encrypted, session_keys):
Expand All @@ -243,20 +234,40 @@ def _decrypt_verify_session_keys(encrypted, session_keys):
: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
:raises 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:
return _decrypt_verify_with_context(ctx, encrypted)
except GPGProblem:
continue
return verify_result.signatures, plaintext
raise GPGProblem("No valid session key", code=GPGCode.NOT_FOUND)


def _decrypt_verify_with_context(ctx, encrypted):
"""Decrypts the given ciphertext string using the gpg context
and returns both the signatures (if any) and the plaintext.
:param gpg.Context ctx: the gpg context
:param bytes encrypted: the mail to decrypt
:returns: the signatures and decrypted plaintext data
:rtype: tuple[list[gpg.resuit.Signature], str]
:raises alot.errors.GPGProblem: if the decryption fails
"""
try:
(plaintext, _, verify_result) = ctx.decrypt(
encrypted, verify=True)
sigs = verify_result.signatures
except gpg.errors.GPGMEError as e:
raise GPGProblem(str(e), code=e.getcode())
except gpg.errors.BadSignatures as e:
(plaintext, _, _) = ctx.decrypt(encrypted, verify=False)
sigs = e.result.signatures
return sigs, plaintext


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.
Expand Down

0 comments on commit f942fa7

Please sign in to comment.