Package dkim :: Package tests :: Module test_dkim_tlsrpt
[hide private]
[frames] | no frames]

Source Code for Module dkim.tests.test_dkim_tlsrpt

  1  # This software is provided 'as-is', without any express or implied 
  2  # warranty.  In no event will the author be held liable for any damages 
  3  # arising from the use of this software. 
  4  # 
  5  # Permission is granted to anyone to use this software for any purpose, 
  6  # including commercial applications, and to alter it and redistribute it 
  7  # freely, subject to the following restrictions: 
  8  # 
  9  # 1. The origin of this software must not be misrepresented; you must not 
 10  #    claim that you wrote the original software. If you use this software 
 11  #    in a product, an acknowledgment in the product documentation would be 
 12  #    appreciated but is not required. 
 13  # 2. Altered source versions must be plainly marked as such, and must not be 
 14  #    misrepresented as being the original software. 
 15  # 3. This notice may not be removed or altered from any source distribution. 
 16  # 
 17  # Copyright (c) 2011 William Grant <me@williamgrant.id.au> 
 18   
 19  import email 
 20  import os.path 
 21  import unittest 
 22  import time 
 23   
 24  import dkim 
 25   
 26   
27 -def read_test_data(filename):
28 """Get the content of the given test data file. 29 30 The files live in dkim/tests/data. 31 """ 32 path = os.path.join(os.path.dirname(__file__), 'data', filename) 33 with open(path, 'rb') as f: 34 return f.read()
35 36
37 -class TestFold(unittest.TestCase):
38
39 - def test_short_line(self):
40 self.assertEqual( 41 b"foo", dkim.fold(b"foo"))
42
43 - def test_long_line(self):
44 # The function is terribly broken, not passing even this simple 45 # test. 46 self.assertEqual( 47 b"foo" * 24 + b"\r\n foo", dkim.fold(b"foo" * 25))
48
49 - def test_linesep(self):
50 self.assertEqual( 51 b"foo" * 24 + b"\n foo", dkim.fold(b"foo" * 25, linesep=b"\n"))
52 53 54
55 -class TestSignAndVerify(unittest.TestCase):
56 """End-to-end signature and verification tests.""" 57
58 - def setUp(self):
59 self.message = read_test_data("test.message") 60 self.message3 = read_test_data("rfc6376.msg") 61 self.message4 = read_test_data("rfc6376.signed.msg") 62 self.key = read_test_data("test.private") 63 self.rfckey = read_test_data("rfc8032_7_1.key")
64
65 - def dnsfunc(self, domain, timeout=5):
66 sample_dns = """\ 67 k=rsa; s=email;\ 68 p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ 69 b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" 70 71 _dns_responses = { 72 'example._domainkey.canonical.com.': sample_dns, 73 'test._domainkey.example.com.': read_test_data("test.txt"), 74 '20120113._domainkey.gmail.com.': """k=rsa; \ 75 p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Kd87/UeJjenpabgbFwh\ 76 +eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQ\ 77 s8g3FgD2Ap3ZB5DekAo5wMmk4wimDO+U8QzI3SD07y2+07wlNWwIt8svnxgdxGkVbb\ 78 hzY8i+RQ9DpSVpPbF7ykQxtKXkv/ahW3KjViiAH+ghvvIhkx4xYSIc9oSwVmAl5Oct\ 79 MEeWUwg8Istjqz8BZeTWbf41fbNhte7Y+YqZOwq1Sd0DbvYAD9NOZK9vlfuac0598H\ 80 Y+vtSBczUiKERHv1yRbcaQtZFh5wtiRrN04BLUTD21MycBX5jYchHjPY/wIDAQAB""" 81 } 82 try: 83 domain = domain.decode('ascii') 84 except UnicodeDecodeError: 85 return None 86 self.assertTrue(domain in _dns_responses,domain) 87 return _dns_responses[domain]
88
89 - def dnsfunc2(self, domain, timeout=5):
90 sample_dns = """\ 91 k=rsa; \ 92 p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ 93 b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" 94 95 _dns_responses = { 96 'example._domainkey.canonical.com.': sample_dns, 97 'test._domainkey.example.com.': read_test_data("test2.txt"), 98 '20120113._domainkey.gmail.com.': """\ 99 p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Kd87/UeJjenpabgbFwh\ 100 +eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQ\ 101 s8g3FgD2Ap3ZB5DekAo5wMmk4wimDO+U8QzI3SD07y2+07wlNWwIt8svnxgdxGkVbb\ 102 hzY8i+RQ9DpSVpPbF7ykQxtKXkv/ahW3KjViiAH+ghvvIhkx4xYSIc9oSwVmAl5Oct\ 103 MEeWUwg8Istjqz8BZeTWbf41fbNhte7Y+YqZOwq1Sd0DbvYAD9NOZK9vlfuac0598H\ 104 Y+vtSBczUiKERHv1yRbcaQtZFh5wtiRrN04BLUTD21MycBX5jYchHjPY/wIDAQAB""" 105 } 106 try: 107 domain = domain.decode('ascii') 108 except UnicodeDecodeError: 109 return None 110 self.assertTrue(domain in _dns_responses,domain) 111 return _dns_responses[domain]
112
113 - def dnsfunc3(self, domain, timeout=5):
114 sample_dns = """\ 115 k=rsa; \ 116 p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ 117 b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" 118 119 _dns_responses = { 120 'example._domainkey.canonical.com.': sample_dns, 121 'test._domainkey.example.com.': read_test_data("badversion.txt"), 122 '20120113._domainkey.gmail.com.': """\ 123 p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Kd87/UeJjenpabgbFwh\ 124 +eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQ\ 125 s8g3FgD2Ap3ZB5DekAo5wMmk4wimDO+U8QzI3SD07y2+07wlNWwIt8svnxgdxGkVbb\ 126 hzY8i+RQ9DpSVpPbF7ykQxtKXkv/ahW3KjViiAH+ghvvIhkx4xYSIc9oSwVmAl5Oct\ 127 MEeWUwg8Istjqz8BZeTWbf41fbNhte7Y+YqZOwq1Sd0DbvYAD9NOZK9vlfuac0598H\ 128 Y+vtSBczUiKERHv1yRbcaQtZFh5wtiRrN04BLUTD21MycBX5jYchHjPY/wIDAQAB""" 129 } 130 try: 131 domain = domain.decode('ascii') 132 except UnicodeDecodeError: 133 return None 134 self.assertTrue(domain in _dns_responses,domain) 135 return _dns_responses[domain]
136
137 - def dnsfunc4(self, domain, timeout=5):
138 sample_dns = """\ 139 k=rsa; \ 140 p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ 141 b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" 142 143 _dns_responses = { 144 'example._domainkey.canonical.com.': sample_dns, 145 'test._domainkey.example.com.': read_test_data("badk.txt"), 146 '20120113._domainkey.gmail.com.': """\ 147 p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Kd87/UeJjenpabgbFwh\ 148 +eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQ\ 149 s8g3FgD2Ap3ZB5DekAo5wMmk4wimDO+U8QzI3SD07y2+07wlNWwIt8svnxgdxGkVbb\ 150 hzY8i+RQ9DpSVpPbF7ykQxtKXkv/ahW3KjViiAH+ghvvIhkx4xYSIc9oSwVmAl5Oct\ 151 MEeWUwg8Istjqz8BZeTWbf41fbNhte7Y+YqZOwq1Sd0DbvYAD9NOZK9vlfuac0598H\ 152 Y+vtSBczUiKERHv1yRbcaQtZFh5wtiRrN04BLUTD21MycBX5jYchHjPY/wIDAQAB""" 153 } 154 try: 155 domain = domain.decode('ascii') 156 except UnicodeDecodeError: 157 return None 158 self.assertTrue(domain in _dns_responses,domain) 159 return _dns_responses[domain]
160
161 - def dnsfunc5(self, domain, timeout=5):
162 sample_dns = """\ 163 k=rsa; \ 164 p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ 165 b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" 166 167 _dns_responses = { 168 'example._domainkey.canonical.com.': sample_dns, 169 'test._domainkey.football.example.com.': read_test_data("test.txt"), 170 'brisbane._domainkey.football.example.com.': """v=DKIM1; k=ed25519; \ 171 p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=""" 172 } 173 try: 174 domain = domain.decode('ascii') 175 except UnicodeDecodeError: 176 return None 177 self.assertTrue(domain in _dns_responses,domain) 178 return _dns_responses[domain]
179
180 - def dnsfunc6(self, domain, timeout=5):
181 sample_dns = """\ 182 k=rsa; s=email;\ 183 p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANmBe10IgY+u7h3enWTukkqtUD5PR52T\ 184 b/mPfjC0QJTocVBq6Za/PlzfV+Py92VaCak19F4WrbVTK5Gg5tW220MCAwEAAQ==""" 185 186 _dns_responses = { 187 'example._domainkey.canonical.com.': sample_dns, 188 'test._domainkey.example.com.': read_test_data("test_tlsrpt.txt"), 189 '20120113._domainkey.gmail.com.': """k=rsa; \ 190 p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Kd87/UeJjenpabgbFwh\ 191 +eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQ\ 192 s8g3FgD2Ap3ZB5DekAo5wMmk4wimDO+U8QzI3SD07y2+07wlNWwIt8svnxgdxGkVbb\ 193 hzY8i+RQ9DpSVpPbF7ykQxtKXkv/ahW3KjViiAH+ghvvIhkx4xYSIc9oSwVmAl5Oct\ 194 MEeWUwg8Istjqz8BZeTWbf41fbNhte7Y+YqZOwq1Sd0DbvYAD9NOZK9vlfuac0598H\ 195 Y+vtSBczUiKERHv1yRbcaQtZFh5wtiRrN04BLUTD21MycBX5jYchHjPY/wIDAQAB""" 196 } 197 try: 198 domain = domain.decode('ascii') 199 except UnicodeDecodeError: 200 return None 201 self.assertTrue(domain in _dns_responses,domain) 202 return _dns_responses[domain]
203 204 205 206
207 - def test_ignores_tlsrptsvc(self):
208 # A non-tlsrpt signed with a key record with s=tlsrpt shouldn't verify. 209 for header_algo in (b"simple", b"relaxed"): 210 for body_algo in (b"simple", b"relaxed"): 211 sig = dkim.sign( 212 self.message, b"test", b"example.com", self.key, 213 canonicalize=(header_algo, body_algo)) 214 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc6) 215 self.assertFalse(res)
216
218 # A tlsrpt signed with a key record with s=tlsrpt should verify with tlsrpt='strict'. 219 for header_algo in (b"simple", b"relaxed"): 220 for body_algo in (b"simple", b"relaxed"): 221 sig = dkim.sign( 222 self.message, b"test", b"example.com", self.key, 223 canonicalize=(header_algo, body_algo)) 224 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc6, tlsrpt='strict') 225 self.assertTrue(res)
226
228 # A tlsrpt signed with a key record with s=tlsrpt should verify. 229 for header_algo in (b"simple", b"relaxed"): 230 for body_algo in (b"simple", b"relaxed"): 231 sig = dkim.sign( 232 self.message, b"test", b"example.com", self.key, 233 canonicalize=(header_algo, body_algo)) 234 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc6, tlsrpt=True) 235 self.assertTrue(res)
236
238 # A tlsrpt signed with a key record without s=tlsrpt not tlsrpt='strict' should not verify. 239 for header_algo in (b"simple", b"relaxed"): 240 for body_algo in (b"simple", b"relaxed"): 241 sig = dkim.sign( 242 self.message, b"test", b"example.com", self.key, 243 canonicalize=(header_algo, body_algo)) 244 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc, tlsrpt='strict') 245 self.assertFalse(res)
246
248 # A tlsrpt signed with a key record without s=tlsrpt and tlsrpt=True should verify. 249 for header_algo in (b"simple", b"relaxed"): 250 for body_algo in (b"simple", b"relaxed"): 251 sig = dkim.sign( 252 self.message, b"test", b"example.com", self.key, 253 canonicalize=(header_algo, body_algo)) 254 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc, tlsrpt=True) 255 self.assertTrue(res)
256
258 # For a tlsrpt, ignore l= on verify 259 for header_algo in (b"simple", b"relaxed"): 260 for body_algo in (b"simple", b"relaxed"): 261 sig = dkim.sign( 262 self.message, b"test", b"example.com", self.key, 263 canonicalize=(header_algo, body_algo), length=True) 264 self.message += b'added more text' 265 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc, tlsrpt=True) 266 self.assertFalse(res)
267
269 # For a tlsrpt, don't add l= when signing tlsrpt 270 for header_algo in (b"simple", b"relaxed"): 271 for body_algo in (b"simple", b"relaxed"): 272 sig = dkim.sign( 273 self.message, b"test", b"example.com", self.key, 274 canonicalize=(header_algo, body_algo), length=True, tlsrpt=True) 275 self.message += b'added more text' 276 res = dkim.verify(sig + self.message, dnsfunc=self.dnsfunc) 277 self.assertFalse(res)
278 279
280 -def test_suite():
281 from unittest import TestLoader 282 return TestLoader().loadTestsFromName(__name__)
283