]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/test-tsig.cc
coverity: Fix paths from extracted tarball
[thirdparty/pdns.git] / pdns / test-tsig.cc
1
2 /*
3 PowerDNS Versatile Database Driven Nameserver
4 Copyright (C) 2013 - 2015 PowerDNS.COM BV
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2
8 as published by the Free Software Foundation
9
10 Additionally, the license of this program contains a special
11 exception which allows to distribute the program in binary form when
12 it is linked against OpenSSL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #define BOOST_TEST_DYN_LINK
25 #define BOOST_TEST_NO_MAIN
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <boost/test/unit_test.hpp>
32
33 #include "dnssecinfra.hh"
34 #include "dnswriter.hh"
35 #include "misc.hh"
36 #include "tsigverifier.hh"
37
38 BOOST_AUTO_TEST_SUITE(test_tsig)
39
40 static vector<uint8_t> generateTSIGQuery(const DNSName& qname, const DNSName& tsigName, const DNSName& tsigAlgo, const string& tsigSecret, uint16_t fudge=300, time_t tsigTime=time(nullptr))
41 {
42 vector<uint8_t> packet;
43 DNSPacketWriter pw(packet, qname, QType::A);
44 pw.getHeader()->qr=0;
45 pw.getHeader()->rd=0;
46 pw.getHeader()->id=42;
47 pw.startRecord(qname, QType::A);
48 pw.xfr32BitInt(0x01020304);
49 pw.addOpt(512, 0, 0);
50 pw.commit();
51
52 TSIGTriplet tt;
53 tt.name = tsigName;
54 tt.algo = tsigAlgo;
55 tt.secret = tsigSecret;
56
57 TSIGHashEnum the;
58 BOOST_REQUIRE(getTSIGHashEnum(tt.algo, the));
59
60 TSIGRecordContent trc;
61 trc.d_algoName = getTSIGAlgoName(the);
62 trc.d_time = tsigTime;
63 trc.d_fudge = fudge;
64 trc.d_origID = ntohs(pw.getHeader()->id);
65 trc.d_eRcode = 0;
66
67 addTSIG(pw, trc, tt.name, tt.secret, "", false);
68 return packet;
69 }
70
71 static void checkTSIG(const DNSName& tsigName, const DNSName& tsigAlgo, const string& tsigSecret, const vector<uint8_t>& packet, const string* overrideMac=nullptr, uint16_t* overrideExtendedRCode=nullptr, uint16_t* overrideOrigID=nullptr)
72 {
73 string packetStr(reinterpret_cast<const char*>(packet.data()), packet.size());
74 MOADNSParser mdp(true, packetStr);
75
76 bool tsigFound = false;
77 string theirMac;
78 DNSName keyName;
79 TSIGRecordContent trc;
80
81 for(const auto& answer: mdp.d_answers) {
82 if(answer.first.d_type == QType::TSIG) {
83 BOOST_CHECK_EQUAL(answer.first.d_place, DNSResourceRecord::ADDITIONAL);
84 BOOST_CHECK_EQUAL(answer.first.d_class, QClass::ANY);
85 BOOST_CHECK_EQUAL(answer.first.d_ttl, 0);
86 BOOST_CHECK_EQUAL(tsigFound, false);
87
88 shared_ptr<TSIGRecordContent> rectrc = getRR<TSIGRecordContent>(answer.first);
89 if (rectrc) {
90 trc = *rectrc;
91 theirMac = rectrc->d_mac;
92 keyName = answer.first.d_name;
93 tsigFound = true;
94 }
95 }
96 }
97
98 if (overrideMac) {
99 theirMac = *overrideMac;
100 }
101
102 if (overrideOrigID) {
103 trc.d_origID = *overrideOrigID;
104 }
105
106 if (overrideExtendedRCode) {
107 trc.d_eRcode = *overrideExtendedRCode;
108 }
109
110 BOOST_REQUIRE(tsigFound);
111 TSIGTriplet tt;
112 tt.name = tsigName;
113 tt.algo = tsigAlgo;
114 tt.secret = tsigSecret;
115
116 BOOST_CHECK(validateTSIG(packetStr, mdp.getTSIGPos(), tt, trc, "", theirMac, false));
117 }
118
119 BOOST_AUTO_TEST_CASE(test_TSIG_valid) {
120 DNSName tsigName("tsig.name");
121 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
122 DNSName qname("test.valid.tsig");
123 string tsigSecret("verysecret");
124
125 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
126
127 checkTSIG(tsigName, tsigAlgo, tsigSecret, packet);}
128
129
130 BOOST_AUTO_TEST_CASE(test_TSIG_different_case_algo) {
131 DNSName tsigName("tsig.name");
132 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
133 DNSName qname("test.valid.tsig");
134 string tsigSecret("verysecret");
135
136 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
137
138 checkTSIG(tsigName, tsigAlgo.makeLowerCase(), tsigSecret, packet);
139 }
140
141 BOOST_AUTO_TEST_CASE(test_TSIG_different_name_same_algo) {
142 DNSName tsigName("tsig.name");
143 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
144 DNSName qname("test.valid.tsig");
145 string tsigSecret("verysecret");
146
147 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
148
149 checkTSIG(tsigName, DNSName("hmac-md5."), tsigSecret, packet);
150 }
151
152 BOOST_AUTO_TEST_CASE(test_TSIG_bad_key_name) {
153 DNSName tsigName("tsig.name");
154 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
155 DNSName qname("test.valid.tsig");
156 string tsigSecret("verysecret");
157
158 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
159
160 BOOST_CHECK_THROW(checkTSIG(DNSName("another.tsig.key.name"), tsigAlgo, tsigSecret, packet), std::runtime_error);
161 }
162
163 BOOST_AUTO_TEST_CASE(test_TSIG_bad_algo) {
164 DNSName tsigName("tsig.name");
165 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
166 DNSName qname("test.valid.tsig");
167 string tsigSecret("verysecret");
168
169 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
170
171 BOOST_CHECK_THROW(checkTSIG(tsigName, DNSName("hmac-sha512."), tsigSecret, packet), std::runtime_error);
172 }
173
174 BOOST_AUTO_TEST_CASE(test_TSIG_bad_secret) {
175 DNSName tsigName("tsig.name");
176 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
177 DNSName qname("test.valid.tsig");
178 string tsigSecret("verysecret");
179
180 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
181
182 BOOST_CHECK_THROW(checkTSIG(tsigName, tsigAlgo, "bad secret", packet), std::runtime_error);
183 }
184
185 BOOST_AUTO_TEST_CASE(test_TSIG_bad_ercode) {
186 DNSName tsigName("tsig.name");
187 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
188 DNSName qname("test.valid.tsig");
189 string tsigSecret("verysecret");
190
191 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
192 uint16_t badERcode = 1;
193
194 BOOST_CHECK_THROW(checkTSIG(tsigName, tsigAlgo, tsigSecret, packet, nullptr, &badERcode), std::runtime_error);
195 }
196
197 BOOST_AUTO_TEST_CASE(test_TSIG_bad_origID) {
198 DNSName tsigName("tsig.name");
199 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
200 DNSName qname("test.valid.tsig");
201 string tsigSecret("verysecret");
202
203 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
204 uint16_t badOrigID = 1;
205
206 BOOST_CHECK_THROW(checkTSIG(tsigName, tsigAlgo, tsigSecret, packet, nullptr, nullptr, &badOrigID), std::runtime_error);
207 }
208
209 BOOST_AUTO_TEST_CASE(test_TSIG_bad_mac) {
210 DNSName tsigName("tsig.name");
211 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
212 DNSName qname("test.valid.tsig");
213 string tsigSecret("verysecret");
214
215 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret);
216
217 string badMac = "badmac";
218 BOOST_CHECK_THROW(checkTSIG(tsigName, tsigAlgo, tsigSecret, packet, &badMac), std::runtime_error);
219 }
220
221 BOOST_AUTO_TEST_CASE(test_TSIG_signature_expired) {
222 DNSName tsigName("tsig.name");
223 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
224 DNSName qname("test.valid.tsig");
225 string tsigSecret("verysecret");
226
227 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret, 5, time(nullptr) - 10);
228
229 BOOST_CHECK_THROW(checkTSIG(tsigName, tsigAlgo, tsigSecret, packet), std::runtime_error);
230 }
231
232 BOOST_AUTO_TEST_CASE(test_TSIG_signature_too_far_in_the_future) {
233 DNSName tsigName("tsig.name");
234 DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
235 DNSName qname("test.valid.tsig");
236 string tsigSecret("verysecret");
237
238 vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, tsigSecret, 5, time(nullptr) + 20);
239
240 BOOST_CHECK_THROW(checkTSIG(tsigName, tsigAlgo, tsigSecret, packet), std::runtime_error);
241 }
242
243 BOOST_AUTO_TEST_SUITE_END();