| 1 | # Copyright (C) 2010 Nominum, Inc.
|
|---|
| 2 | #
|
|---|
| 3 | # Permission to use, copy, modify, and distribute this software and its
|
|---|
| 4 | # documentation for any purpose with or without fee is hereby granted,
|
|---|
| 5 | # provided that the above copyright notice and this permission notice
|
|---|
| 6 | # appear in all copies.
|
|---|
| 7 | #
|
|---|
| 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
|
|---|
| 9 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|---|
| 10 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
|
|---|
| 11 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|---|
| 12 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|---|
| 13 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|---|
| 14 | # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|---|
| 15 |
|
|---|
| 16 | import unittest
|
|---|
| 17 |
|
|---|
| 18 | import dns.dnssec
|
|---|
| 19 | import dns.name
|
|---|
| 20 | import dns.rdata
|
|---|
| 21 | import dns.rdataclass
|
|---|
| 22 | import dns.rdatatype
|
|---|
| 23 | import dns.rrset
|
|---|
| 24 |
|
|---|
| 25 | abs_dnspython_org = dns.name.from_text('dnspython.org')
|
|---|
| 26 |
|
|---|
| 27 | abs_keys = { abs_dnspython_org :
|
|---|
| 28 | dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'DNSKEY',
|
|---|
| 29 | '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
|
|---|
| 30 | '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
|
|---|
| 31 | }
|
|---|
| 32 |
|
|---|
| 33 | rel_keys = { dns.name.empty :
|
|---|
| 34 | dns.rrset.from_text('@', 3600, 'IN', 'DNSKEY',
|
|---|
| 35 | '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=',
|
|---|
| 36 | '256 3 5 AwEAAdSSghOGjU33IQZgwZM2Hh771VGXX05olJK49FxpSyuEAjDBXY58 LGU9R2Zgeecnk/b9EAhFu/vCV9oECtiTCvwuVAkt9YEweqYDluQInmgP NGMJCKdSLlnX93DkjDw8rMYv5dqXCuSGPlKChfTJOLQxIAxGloS7lL+c 0CTZydAF')
|
|---|
| 37 | }
|
|---|
| 38 |
|
|---|
| 39 | when = 1290250287
|
|---|
| 40 |
|
|---|
| 41 | abs_soa = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'SOA',
|
|---|
| 42 | 'howl.dnspython.org. hostmaster.dnspython.org. 2010020047 3600 1800 604800 3600')
|
|---|
| 43 |
|
|---|
| 44 | abs_other_soa = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'SOA',
|
|---|
| 45 | 'foo.dnspython.org. hostmaster.dnspython.org. 2010020047 3600 1800 604800 3600')
|
|---|
| 46 |
|
|---|
| 47 | abs_soa_rrsig = dns.rrset.from_text('dnspython.org.', 3600, 'IN', 'RRSIG',
|
|---|
| 48 | 'SOA 5 2 3600 20101127004331 20101119213831 61695 dnspython.org. sDUlltRlFTQw5ITFxOXW3TgmrHeMeNpdqcZ4EXxM9FHhIlte6V9YCnDw t6dvM9jAXdIEi03l9H/RAd9xNNW6gvGMHsBGzpvvqFQxIBR2PoiZA1mX /SWHZFdbt4xjYTtXqpyYvrMK0Dt7bUYPadyhPFCJ1B+I8Zi7B5WJEOd0 8vs=')
|
|---|
| 49 |
|
|---|
| 50 | rel_soa = dns.rrset.from_text('@', 3600, 'IN', 'SOA',
|
|---|
| 51 | 'howl hostmaster 2010020047 3600 1800 604800 3600')
|
|---|
| 52 |
|
|---|
| 53 | rel_other_soa = dns.rrset.from_text('@', 3600, 'IN', 'SOA',
|
|---|
| 54 | 'foo hostmaster 2010020047 3600 1800 604800 3600')
|
|---|
| 55 |
|
|---|
| 56 | rel_soa_rrsig = dns.rrset.from_text('@', 3600, 'IN', 'RRSIG',
|
|---|
| 57 | 'SOA 5 2 3600 20101127004331 20101119213831 61695 @ sDUlltRlFTQw5ITFxOXW3TgmrHeMeNpdqcZ4EXxM9FHhIlte6V9YCnDw t6dvM9jAXdIEi03l9H/RAd9xNNW6gvGMHsBGzpvvqFQxIBR2PoiZA1mX /SWHZFdbt4xjYTtXqpyYvrMK0Dt7bUYPadyhPFCJ1B+I8Zi7B5WJEOd0 8vs=')
|
|---|
| 58 |
|
|---|
| 59 | sep_key = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY,
|
|---|
| 60 | '257 3 5 AwEAAenVTr9L1OMlL1/N2ta0Qj9LLLnnmFWIr1dJoAsWM9BQfsbV7kFZ XbAkER/FY9Ji2o7cELxBwAsVBuWn6IUUAJXLH74YbC1anY0lifjgt29z SwDzuB7zmC7yVYZzUunBulVW4zT0tg1aePbpVL2EtTL8VzREqbJbE25R KuQYHZtFwG8S4iBxJUmT2Bbd0921LLxSQgVoFXlQx/gFV2+UERXcJ5ce iX6A6wc02M/pdg/YbJd2rBa0MYL3/Fz/Xltre0tqsImZGxzi6YtYDs45 NC8gH+44egz82e2DATCVM1ICPmRDjXYTLldQiWA2ZXIWnK0iitl5ue24 7EsWJefrIhE=')
|
|---|
| 61 |
|
|---|
| 62 | good_ds = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
|
|---|
| 63 | '57349 5 2 53A79A3E7488AB44FFC56B2D1109F0699D1796DD977E72108B841F96 E47D7013')
|
|---|
| 64 |
|
|---|
| 65 | when2 = 1290425644
|
|---|
| 66 |
|
|---|
| 67 | abs_example = dns.name.from_text('example')
|
|---|
| 68 |
|
|---|
| 69 | abs_dsa_keys = { abs_example :
|
|---|
| 70 | dns.rrset.from_text('example.', 86400, 'IN', 'DNSKEY',
|
|---|
| 71 | '257 3 3 CI3nCqyJsiCJHTjrNsJOT4RaszetzcJPYuoH3F9ZTVt3KJXncCVR3bwn 1w0iavKljb9hDlAYSfHbFCp4ic/rvg4p1L8vh5s8ToMjqDNl40A0hUGQ Ybx5hsECyK+qHoajilUX1phYSAD8d9WAGO3fDWzUPBuzR7o85NiZCDxz yXuNVfni0uhj9n1KYhEO5yAbbruDGN89wIZcxMKuQsdUY2GYD93ssnBv a55W6XRABYWayKZ90WkRVODLVYLSn53Pj/wwxGH+XdhIAZJXimrZL4yl My7rtBsLMqq8Ihs4Tows7LqYwY7cp6y/50tw6pj8tFqMYcPUjKZV36l1 M/2t5BVg3i7IK61Aidt6aoC3TDJtzAxg3ZxfjZWJfhHjMJqzQIfbW5b9 q1mjFsW5EUv39RaNnX+3JWPRLyDqD4pIwDyqfutMsdk/Py3paHn82FGp CaOg+nicqZ9TiMZURN/XXy5JoXUNQ3RNvbHCUiPUe18KUkY6mTfnyHld 1l9YCWmzXQVClkx/hOYxjJ4j8Ife58+Obu5X',
|
|---|
| 72 | '256 3 3 CJE1yb9YRQiw5d2xZrMUMR+cGCTt1bp1KDCefmYKmS+Z1+q9f42ETVhx JRiQwXclYwmxborzIkSZegTNYIV6mrYwbNB27Q44c3UGcspb3PiOw5TC jNPRYEcdwGvDZ2wWy+vkSV/S9tHXY8O6ODiE6abZJDDg/RnITyi+eoDL R3KZ5n/V1f1T1b90rrV6EewhBGQJpQGDogaXb2oHww9Tm6NfXyo7SoMM pbwbzOckXv+GxRPJIQNSF4D4A9E8XCksuzVVdE/0lr37+uoiAiPia38U 5W2QWe/FJAEPLjIp2eTzf0TrADc1pKP1wrA2ASpdzpm/aX3IB5RPp8Ew S9U72eBFZJAUwg635HxJVxH1maG6atzorR566E+e0OZSaxXS9o1o6QqN 3oPlYLGPORDiExilKfez3C/x/yioOupW9K5eKF0gmtaqrHX0oq9s67f/ RIM2xVaKHgG9Vf2cgJIZkhv7sntujr+E4htnRmy9P9BxyFxsItYxPI6Z bzygHAZpGhlI/7ltEGlIwKxyTK3ZKBm67q7B')
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | abs_dsa_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
|
|---|
| 76 | 'ns1.example. hostmaster.example. 2 10800 3600 604800 86400')
|
|---|
| 77 |
|
|---|
| 78 | abs_other_dsa_soa = dns.rrset.from_text('example.', 86400, 'IN', 'SOA',
|
|---|
| 79 | 'ns1.example. hostmaster.example. 2 10800 3600 604800 86401')
|
|---|
| 80 |
|
|---|
| 81 | abs_dsa_soa_rrsig = dns.rrset.from_text('example.', 86400, 'IN', 'RRSIG',
|
|---|
| 82 | 'SOA 3 1 86400 20101129143231 20101122112731 42088 example. CGul9SuBofsktunV8cJs4eRs6u+3NCS3yaPKvBbD+pB2C76OUXDZq9U=')
|
|---|
| 83 |
|
|---|
| 84 | example_sep_key = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY,
|
|---|
| 85 | '257 3 3 CI3nCqyJsiCJHTjrNsJOT4RaszetzcJPYuoH3F9ZTVt3KJXncCVR3bwn 1w0iavKljb9hDlAYSfHbFCp4ic/rvg4p1L8vh5s8ToMjqDNl40A0hUGQ Ybx5hsECyK+qHoajilUX1phYSAD8d9WAGO3fDWzUPBuzR7o85NiZCDxz yXuNVfni0uhj9n1KYhEO5yAbbruDGN89wIZcxMKuQsdUY2GYD93ssnBv a55W6XRABYWayKZ90WkRVODLVYLSn53Pj/wwxGH+XdhIAZJXimrZL4yl My7rtBsLMqq8Ihs4Tows7LqYwY7cp6y/50tw6pj8tFqMYcPUjKZV36l1 M/2t5BVg3i7IK61Aidt6aoC3TDJtzAxg3ZxfjZWJfhHjMJqzQIfbW5b9 q1mjFsW5EUv39RaNnX+3JWPRLyDqD4pIwDyqfutMsdk/Py3paHn82FGp CaOg+nicqZ9TiMZURN/XXy5JoXUNQ3RNvbHCUiPUe18KUkY6mTfnyHld 1l9YCWmzXQVClkx/hOYxjJ4j8Ife58+Obu5X')
|
|---|
| 86 |
|
|---|
| 87 | example_ds_sha1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
|
|---|
| 88 | '18673 3 1 71b71d4f3e11bbd71b4eff12cde69f7f9215bbe7')
|
|---|
| 89 |
|
|---|
| 90 | example_ds_sha256 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS,
|
|---|
| 91 | '18673 3 2 eb8344cbbf07c9d3d3d6c81d10c76653e28d8611a65e639ef8f716e4e4e5d913')
|
|---|
| 92 |
|
|---|
| 93 | class DNSSECValidatorTestCase(unittest.TestCase):
|
|---|
| 94 |
|
|---|
| 95 | def testAbsoluteRSAGood(self):
|
|---|
| 96 | dns.dnssec.validate(abs_soa, abs_soa_rrsig, abs_keys, None, when)
|
|---|
| 97 |
|
|---|
| 98 | def testAbsoluteRSABad(self):
|
|---|
| 99 | def bad():
|
|---|
| 100 | dns.dnssec.validate(abs_other_soa, abs_soa_rrsig, abs_keys, None,
|
|---|
| 101 | when)
|
|---|
| 102 | self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
|
|---|
| 103 |
|
|---|
| 104 | def testRelativeRSAGood(self):
|
|---|
| 105 | dns.dnssec.validate(rel_soa, rel_soa_rrsig, rel_keys,
|
|---|
| 106 | abs_dnspython_org, when)
|
|---|
| 107 |
|
|---|
| 108 | def testRelativeRSABad(self):
|
|---|
| 109 | def bad():
|
|---|
| 110 | dns.dnssec.validate(rel_other_soa, rel_soa_rrsig, rel_keys,
|
|---|
| 111 | abs_dnspython_org, when)
|
|---|
| 112 | self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
|
|---|
| 113 |
|
|---|
| 114 | def testMakeSHA256DS(self):
|
|---|
| 115 | ds = dns.dnssec.make_ds(abs_dnspython_org, sep_key, 'SHA256')
|
|---|
| 116 | self.failUnless(ds == good_ds)
|
|---|
| 117 |
|
|---|
| 118 | def testAbsoluteDSAGood(self):
|
|---|
| 119 | dns.dnssec.validate(abs_dsa_soa, abs_dsa_soa_rrsig, abs_dsa_keys, None,
|
|---|
| 120 | when2)
|
|---|
| 121 |
|
|---|
| 122 | def testAbsoluteDSABad(self):
|
|---|
| 123 | def bad():
|
|---|
| 124 | dns.dnssec.validate(abs_other_dsa_soa, abs_dsa_soa_rrsig,
|
|---|
| 125 | abs_dsa_keys, None, when2)
|
|---|
| 126 | self.failUnlessRaises(dns.dnssec.ValidationFailure, bad)
|
|---|
| 127 |
|
|---|
| 128 | def testMakeExampleSHA1DS(self):
|
|---|
| 129 | ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA1')
|
|---|
| 130 | self.failUnless(ds == example_ds_sha1)
|
|---|
| 131 |
|
|---|
| 132 | def testMakeExampleSHA256DS(self):
|
|---|
| 133 | ds = dns.dnssec.make_ds(abs_example, example_sep_key, 'SHA256')
|
|---|
| 134 | self.failUnless(ds == example_ds_sha256)
|
|---|
| 135 |
|
|---|
| 136 | if __name__ == '__main__':
|
|---|
| 137 | import_ok = False
|
|---|
| 138 | try:
|
|---|
| 139 | import Crypto.Util.number
|
|---|
| 140 | import_ok = True
|
|---|
| 141 | except:
|
|---|
| 142 | pass
|
|---|
| 143 | if import_ok:
|
|---|
| 144 | unittest.main()
|
|---|
| 145 | else:
|
|---|
| 146 | print 'skipping DNSSEC tests because pycrypto is not installed'
|
|---|