diff --git a/ChangeLog b/ChangeLog index 6b26243..8b75013 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +UNRELEASED Version 0.7.1 + - Update ed25519 tests, including using sample keys from RFC 8032 Section + 7.1 and the sample message from RFC 6376 2018-02-07 Version 0.7.0 - Initial ed25519 implementation based on draft-ietf-dcrup-dkim-crypto experimental - IETF draft, design not finalized, See README for details diff --git a/dkim/tests/data/rfc6376.msg b/dkim/tests/data/rfc6376.msg new file mode 100644 index 0000000..1a12d42 --- /dev/null +++ b/dkim/tests/data/rfc6376.msg @@ -0,0 +1,12 @@ +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/data/rfc8032_7_1.key b/dkim/tests/data/rfc8032_7_1.key new file mode 100644 index 0000000..a95446c --- /dev/null +++ b/dkim/tests/data/rfc8032_7_1.key @@ -0,0 +1 @@ +nWGxne/9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A= diff --git a/dkim/tests/test_dkim_ed25519.py b/dkim/tests/test_dkim_ed25519.py index 6c95570..cf4cc9a 100644 --- a/dkim/tests/test_dkim_ed25519.py +++ b/dkim/tests/test_dkim_ed25519.py @@ -54,7 +54,9 @@ class TestSignAndVerify(unittest.TestCase): def setUp(self): self.message = read_test_data("ed25519test.msg") self.message2 = read_test_data("ed25519test2.msg") + self.message3 = read_test_data("rfc6376.msg") self.key = read_test_data("ed25519test.key") + self.rfckey = read_test_data("rfc8032_7_1.key") def dnsfunc(self, domain): sample_dns = """\ @@ -63,11 +65,11 @@ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""" _dns_responses = { 'example._domainkey.canonical.com.': sample_dns, - 'test._domainkey.example.com.': """v=DKIM1; k=ed25519; \ + 'test._domainkey.example.net.': """v=DKIM1; k=ed25519; \ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", - '20120113._domainkey.gmail.com.': """k=ed25519; \ -p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", - 'sed._domainkey.test.ex.': read_test_data("eximtest.dns") + 'sed._domainkey.test.ex.': read_test_data("eximtest.dns"), + 'brisbane._domainkey.football.example.com.': """v=DKIM1; k=ed25519; \ +p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=""" } try: domain = domain.decode('ascii') @@ -81,17 +83,28 @@ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", for header_algo in (b"simple", b"relaxed"): for body_algo in (b"simple", b"relaxed"): sig = dkim.sign( - self.message, b"test", b"example.com", self.key, + self.message, b"test", b"example.net", self.key, canonicalize=(header_algo, body_algo), signature_algorithm=b'ed25519-sha256') res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc) self.assertTrue(res) + def test_rfc8032_verifies(self): + # A message using RFC 8032 sample keys verifies after being signed. + for header_algo in (b"simple", b"relaxed"): + for body_algo in (b"simple", b"relaxed"): + sig = dkim.sign( + self.message3, b"brisbane", b"football.example.com", self.rfckey, + canonicalize=(header_algo, body_algo), signature_algorithm=b'ed25519-sha256') + print(sig) + res = dkim.verify(sig + self.message3, dnsfunc=self.dnsfunc) + self.assertTrue(res) + def test_simple_signature(self): # A message verifies after being signed with SHOULD headers for header_algo in (b"simple", b"relaxed"): for body_algo in (b"simple", b"relaxed"): sig = dkim.sign( - self.message, b"test", b"example.com", self.key, + self.message, b"test", b"example.net", self.key, canonicalize=(header_algo, body_algo), include_headers=(b'from',) + dkim.DKIM.SHOULD, signature_algorithm=b'ed25519-sha256') @@ -105,7 +118,7 @@ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", def test_add_body_length(self): sig = dkim.sign( - self.message, b"test", b"example.com", self.key, length=True, + self.message, b"test", b"example.net", self.key, length=True, signature_algorithm=b'ed25519-sha256') msg = email.message_from_string(self.message.decode('utf-8')) self.assertIn('; l=%s' % len(msg.get_payload() + '\n'), sig.decode('utf-8')) @@ -117,7 +130,7 @@ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", for header_algo in (b"simple", b"relaxed"): for body_algo in (b"simple", b"relaxed"): sig = dkim.sign( - self.message, b"test", b"example.com", self.key, + self.message, b"test", b"example.net", self.key, signature_algorithm=b'ed25519-sha256') res = dkim.verify( sig + self.message + b"foo", dnsfunc=self.dnsfunc) @@ -125,7 +138,7 @@ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", def test_badly_encoded_domain_fails(self): # Domains should be ASCII. Bad ASCII causes verification to fail. - sig = dkim.sign(self.message, b"test", b"example.com\xe9", self.key, + sig = dkim.sign(self.message, b"test", b"example.net\xe9", self.key, signature_algorithm=b'ed25519-sha256') res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc) self.assertFalse(res) @@ -138,7 +151,7 @@ p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=""", # (should ignore FWS anywhere in signature tag: b=) sample_msg = b"""\ From: mbp@canonical.com -To: scottk@example.com +To: scottk@example.net Subject: this is my test message """.replace(b'\n', b'\r\n') @@ -183,7 +196,7 @@ yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=\ d = dkim.DKIM(message) # bug requires a repeated header to manifest d.should_not_sign.remove(b'received') - sig = d.sign(b"test", b"example.com", self.key, + sig = d.sign(b"test", b"example.net", self.key, signature_algorithm=b'ed25519-sha256', include_headers=d.all_sign_headers(), canonicalize=(header_algo, body_algo)) @@ -203,7 +216,7 @@ yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=\ for header_algo in (b"simple", b"relaxed"): for body_algo in (b"simple", b"relaxed"): sig = dkim.sign( - self.message, b"test", b"example.com", self.key, + self.message, b"test", b"example.net", self.key, signature_algorithm=b'ed25519-sha256') # adding an unknown header still verifies h1 = h+b'\r\n'+b'X-Foo: bar' @@ -227,7 +240,7 @@ yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y=\ sig = '' message = read_test_data('test_nofrom.message') selector = 'test' - domain = 'example.com' + domain = 'example.net' identity = None try: sig = dkim.sign(message, selector, domain, diff --git a/setup.py b/setup.py index f504b92..193ff87 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ from distutils.core import setup import os -version = "0.7.0" +version = "0.7.0+" setup( name = "dkimpy",