Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion emails/signers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def __init__(self, selector: str, domain: str, key: str | bytes | IO[bytes] | No
# Normalize to bytes
privkey_bytes = privkey if isinstance(privkey, bytes) else str(privkey).encode()

# Validate key by attempting to parse it
# Validate key upfront; dkim.sign() re-parses PEM on each call
# but the cost is negligible vs the RSA operation (~0ms vs ~2.5ms).
try:
dkim.crypto.parse_pem_private_key(privkey_bytes)
except UnparsableKeyError as exc:
Expand Down
16 changes: 16 additions & 0 deletions emails/testsuite/message/test_dkim.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ def test_dkim_as_bytes():
assert b'DKIM-Signature: ' in result


def test_dkim_sign_after_error():
"""After a sign error with ignore_sign_errors, normal signing still works."""
priv_key, pub_key = _generate_key(length=1024)

# First: sign with invalid include_headers (missing From), error ignored
m1 = Message(**common_email_data())
m1.dkim(key=priv_key, selector='_dkim', domain='somewhere.net',
ignore_sign_errors=True, include_headers=['To'])
m1.as_string() # should not raise

# Second: normal sign with same key must still work
m2 = Message(**common_email_data())
m2.dkim(key=priv_key, selector='_dkim', domain='somewhere.net')
assert _check_dkim(m2, pub_key)


def test_dkim_sign_twice():

# Test #44:
Expand Down
1 change: 1 addition & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ python-dateutil
requests
premailer>=2.8.3
puremagic
dkimpy
Loading