diff --git a/ChangeLog b/ChangeLog index 6bae25a..d209716 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ Version 1.0.0 since, although rare, they are RFC 6376 specified (LP: #1851862) - Drop usage of pymilter Milter.dns in dnsplug since it doesn't support havine a timeout passed to it + - Can binascii related key format errors (LP: #1854477) 2019-10-07 Version 0.9.5 - Ignore unknown service types in key records (LP: #1847020) diff --git a/dkim/__init__.py b/dkim/__init__.py index d3f1fb0..9846598 100644 --- a/dkim/__init__.py +++ b/dkim/__init__.py @@ -37,6 +37,7 @@ import hashlib import logging import re import time +import binascii # only needed for arc try: @@ -688,6 +689,9 @@ class DomainSigner(object): except KeyFormatError as e: self.logger.error("%s" % e) return False + except binascii.Error as e: + self.logger.error('KeyFormatError: {0}'.format(e)) + return False # RFC 8460 MAY ignore signatures without tlsrpt Service Type if self.tlsrpt == 'strict' and not self.seqtlsrpt: diff --git a/dkim/tests/data/rfc6376.signed.rsa.msg b/dkim/tests/data/rfc6376.signed.rsa.msg new file mode 100644 index 0000000..7b470b3 --- /dev/null +++ b/dkim/tests/data/rfc6376.signed.rsa.msg @@ -0,0 +1,20 @@ +DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; + d=football.example.com; i=@football.example.com; + q=dns/txt; s=test; t=1527915362; h=from : to : subject : + date : message-id : from : subject : date; + bh=4bLNXImK9drULnmePzZNEBleUanJCX5PIsDIFoH4KTQ=; + b=icKcLSEZYXJ95flvWE8FT6hl5iqd8MC/LEKYH0QjsqYy6MO/4pgVNCZH + l/RAXAuADxE/40Fg7uTlxwwD1hjN2Ple6J//cJfslBdDOq6zTVbne1dqtl + NOat7iamJ1AfRqyG+ja7a2AZsrpUuJ7VA6O+0zRYPqpwMEkEFIzI9i/Xk= +From: Joe SixPack +To: Suzie Q +Subject: Is dinner ready? +Date: Fri, 11 Jul 2003 21:00:37 -0700 (PDT) +Message-ID: <20030712040037.46341.5F8J@football.example.com> + +Hi. + +We lost the game. Are you hungry yet? + +Joe. + diff --git a/dkim/tests/test_dkim.py b/dkim/tests/test_dkim.py index 578c260..9aa452c 100644 --- a/dkim/tests/test_dkim.py +++ b/dkim/tests/test_dkim.py @@ -59,6 +59,7 @@ class TestSignAndVerify(unittest.TestCase): self.message = read_test_data("test.message") self.message3 = read_test_data("rfc6376.msg") self.message4 = read_test_data("rfc6376.signed.msg") + self.message5 = read_test_data("rfc6376.signed.rsa.msg") self.key = read_test_data("test.private") self.rfckey = read_test_data("rfc8032_7_1.key") @@ -177,6 +178,24 @@ p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=""" self.assertTrue(domain in _dns_responses,domain) return _dns_responses[domain] + def dnsfunc6(self, domain, timeout=5): + sample_dns = """\ +k=rsa; \ +p=MFwwDQYJKoZIhvNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ +b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" + + _dns_responses = { + 'test._domainkey.football.example.com.': sample_dns, + 'brisbane._domainkey.football.example.com.': """v=DKIM1; k=ed25519; \ +p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=""" + } + try: + domain = domain.decode('ascii') + except UnicodeDecodeError: + return None + self.assertTrue(domain in _dns_responses,domain) + return _dns_responses[domain] + def test_verifies(self): # A message verifies after being signed. for header_algo in (b"simple", b"relaxed"): @@ -208,6 +227,12 @@ p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=""" res = d.verify(dnsfunc=self.dnsfunc5) self.assertTrue(res) + def test_catch_bad_key(self): + # Raise correct error for defective public key. + d = dkim.DKIM(self.message5) + res = d.verify(dnsfunc=self.dnsfunc6) + self.assertFalse(res) + def test_verifies_lflinesep(self): # A message verifies after being signed. for header_algo in (b"simple", b"relaxed"):