rdata_sshfp_unittest.cc 10.3 KB
Newer Older
1
// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include <algorithm>
#include <string>

#include <util/buffer.h>
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>

#include <gtest/gtest.h>

#include <dns/tests/unittest_util.h>
#include <dns/tests/rdata_unittest.h>
29
#include <boost/algorithm/string.hpp>
30
31
32

using isc::UnitTestUtil;
using namespace std;
33
using namespace isc;
34
35
36
37
38
39
using namespace isc::dns;
using namespace isc::util;
using namespace isc::dns::rdata;

namespace {
class Rdata_SSHFP_Test : public RdataTest {
40
41
42
43
44
45
46
47
48
49
50
protected:
        Rdata_SSHFP_Test() :
            sshfp_txt("2 1 123456789abcdef67890123456789abcdef67890"),
            rdata_sshfp(sshfp_txt)
        {}

    void checkFromText_None(const string& rdata_str) {
        checkFromText<generic::SSHFP, isc::Exception, isc::Exception>(
            rdata_str, rdata_sshfp, false, false);
    }

51
52
53
54
55
    void checkFromText_InvalidText(const string& rdata_str) {
        checkFromText<generic::SSHFP, InvalidRdataText, InvalidRdataText>(
            rdata_str, rdata_sshfp, true, true);
    }

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    void checkFromText_LexerError(const string& rdata_str) {
        checkFromText
            <generic::SSHFP, InvalidRdataText, MasterLexer::LexerError>(
                rdata_str, rdata_sshfp, true, true);
    }

    void checkFromText_BadValue(const string& rdata_str) {
        checkFromText<generic::SSHFP, InvalidRdataText, BadValue>(
            rdata_str, rdata_sshfp, true, true);
    }

    void checkFromText_BadString(const string& rdata_str) {
        checkFromText
            <generic::SSHFP, InvalidRdataText, isc::Exception>(
                rdata_str, rdata_sshfp, true, false);
    }

    const string sshfp_txt;
    const generic::SSHFP rdata_sshfp;
75
76
};

77
78
79
80
81
82
83
84
85
86
87
88
const uint8_t rdata_sshfp_wiredata[] = {
    // algorithm
    0x02,
    // fingerprint type
    0x01,
    // fingerprint
    0x12, 0x34, 0x56, 0x78,
    0x9a, 0xbc, 0xde, 0xf6,
    0x78, 0x90, 0x12, 0x34,
    0x56, 0x78, 0x9a, 0xbc,
    0xde, 0xf6, 0x78, 0x90
};
89
90

TEST_F(Rdata_SSHFP_Test, createFromText) {
91
    // Basic test
92
    checkFromText_None(sshfp_txt);
93
94

    // With different spacing
95
    checkFromText_None("2 1   123456789abcdef67890123456789abcdef67890");
96
97

    // Combination of lowercase and uppercase
98
    checkFromText_None("2 1   123456789ABCDEF67890123456789abcdef67890");
99
100
}

101
102
103
104
TEST_F(Rdata_SSHFP_Test, algorithmTypes) {
    // Some of these may not be RFC conformant, but we relax the check
    // in our code to work with algorithm and fingerprint types that may
    // show up in the future.
Mukund Sivaraman's avatar
Mukund Sivaraman committed
105
106
107
108
109
110
111
112
113
114
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("2 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("3 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("128 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("255 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 2 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 3 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 128 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 255 12ab"));
115

116
117
118
    // 0 is reserved, but we allow that too
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("0 1 12ab"));
    EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 0 12ab"));
119
120
121
122
123
124

    // > 255 would be broken
    EXPECT_THROW(const generic::SSHFP rdata_sshfp("256 1 12ab"),
                 InvalidRdataText);
    EXPECT_THROW(const generic::SSHFP rdata_sshfp("2 256 12ab"),
                 InvalidRdataText);
125
126
}

127
TEST_F(Rdata_SSHFP_Test, badText) {
128
129
130
    checkFromText_LexerError("1");
    checkFromText_LexerError("ONE 2 123456789abcdef67890123456789abcdef67890");
    checkFromText_LexerError("1 TWO 123456789abcdef67890123456789abcdef67890");
131
    checkFromText_BadValue("1 2 BUCKLEMYSHOE");
132
    checkFromText_BadString(sshfp_txt + " extra text");
133
134
135
136
137
138
139
140

    // yes, these are redundant to the last test cases in algorithmTypes
    checkFromText_InvalidText("2345 1 123456789abcdef67890123456789abcdef67890");
    checkFromText_InvalidText("2 1234 123456789abcdef67890123456789abcdef67890");

    // negative values are trapped in the lexer rather than the constructor
    checkFromText_LexerError("-2 1 123456789abcdef67890123456789abcdef67890");
    checkFromText_LexerError("2 -1 123456789abcdef67890123456789abcdef67890");
141
142
143
144
145
146
147
148
}

TEST_F(Rdata_SSHFP_Test, copy) {
    const generic::SSHFP rdata_sshfp2(rdata_sshfp);
    EXPECT_EQ(0, rdata_sshfp.compare(rdata_sshfp2));
}

TEST_F(Rdata_SSHFP_Test, createFromWire) {
149
    // Basic test
150
151
    EXPECT_EQ(0, rdata_sshfp.compare(
                  *rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
152
                                        "rdata_sshfp_fromWire")));
153
154
155
156
    // Combination of lowercase and uppercase
    EXPECT_EQ(0, rdata_sshfp.compare(
                  *rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                        "rdata_sshfp_fromWire2")));
157
158
159
160
161
162
163
164
165
    // algorithm=1, fingerprint=1
    EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                         "rdata_sshfp_fromWire3.wire"));

    // algorithm=255, fingerprint=1
    EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                         "rdata_sshfp_fromWire4.wire"));

    // algorithm=0, fingerprint=1
166
167
    EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                         "rdata_sshfp_fromWire5.wire"));
168
169

    // algorithm=5, fingerprint=0
170
171
    EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                         "rdata_sshfp_fromWire6.wire"));
172
173
174
175

    // algorithm=255, fingerprint=255
    EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                         "rdata_sshfp_fromWire7.wire"));
176
177
178
179

    // short fingerprint data
    EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                         "rdata_sshfp_fromWire8.wire"));
180
181
182
183

    // fingerprint is shorter than rdata len
    EXPECT_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                      "rdata_sshfp_fromWire9"),
184
                 InvalidBufferPosition);
185
186
187
188

    // fingerprint is missing
    EXPECT_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                      "rdata_sshfp_fromWire10"),
189
                 InvalidBufferPosition);
190
191
192
193

    // all rdata is missing
    EXPECT_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                                      "rdata_sshfp_fromWire11"),
194
                 InvalidBufferPosition);
195
196
}

197
TEST_F(Rdata_SSHFP_Test, createFromParams) {
198
199
200
201
    const generic::SSHFP rdata_sshfp2(2, 1, "123456789abcdef67890123456789abcdef67890");
    EXPECT_EQ(0, rdata_sshfp2.compare(rdata_sshfp));
}

202
TEST_F(Rdata_SSHFP_Test, toText) {
203
    EXPECT_TRUE(boost::iequals(sshfp_txt, rdata_sshfp.toText()));
204
205
206
207
208
209
210

    const string sshfp_txt2("2 1");
    const generic::SSHFP rdata_sshfp2(sshfp_txt2);
    EXPECT_TRUE(boost::iequals(sshfp_txt2, rdata_sshfp2.toText()));

    const generic::SSHFP rdata_sshfp3("2 1 ");
    EXPECT_TRUE(boost::iequals(sshfp_txt2, rdata_sshfp3.toText()));
211
212
}

213
214
215
216
217
218
219
220
221
222
223
224
TEST_F(Rdata_SSHFP_Test, toWire) {
    this->obuffer.clear();
    rdata_sshfp.toWire(this->obuffer);

    EXPECT_EQ(22, this->obuffer.getLength());

    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        this->obuffer.getData(),
                        this->obuffer.getLength(),
                        rdata_sshfp_wiredata, sizeof(rdata_sshfp_wiredata));
}

225
226
227
228
229
230
TEST_F(Rdata_SSHFP_Test, compare) {
    const generic::SSHFP rdata_sshfp2("2 1");
    EXPECT_EQ(-1, rdata_sshfp2.compare(rdata_sshfp));
    EXPECT_EQ(1, rdata_sshfp.compare(rdata_sshfp2));
}

231
232
TEST_F(Rdata_SSHFP_Test, getAlgorithmNumber) {
    EXPECT_EQ(2, rdata_sshfp.getAlgorithmNumber());
233
234
}

235
236
TEST_F(Rdata_SSHFP_Test, getFingerprintType) {
    EXPECT_EQ(1, rdata_sshfp.getFingerprintType());
237
}
238
239
240
241
242
243

TEST_F(Rdata_SSHFP_Test, getFingerprintLen) {
    EXPECT_EQ(20, rdata_sshfp.getFingerprintLen());
}

TEST_F(Rdata_SSHFP_Test, emptyFingerprintFromWire) {
244
245
246
247
248
249
250
    const uint8_t rdf_wiredata[] = {
        // algorithm
        0x04,
        // fingerprint type
        0x09
    };

251
    const generic::SSHFP rdf =
252
253
254
255
        dynamic_cast<const generic::SSHFP&>
        (*rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"),
                               "rdata_sshfp_fromWire12"));

256
257
    EXPECT_EQ(4, rdf.getAlgorithmNumber());
    EXPECT_EQ(9, rdf.getFingerprintType());
258
    EXPECT_EQ(0, rdf.getFingerprintLen());
259
260
261
262
263
264
265
266
267
268

    this->obuffer.clear();
    rdf.toWire(this->obuffer);

    EXPECT_EQ(2, this->obuffer.getLength());

    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        this->obuffer.getData(),
                        this->obuffer.getLength(),
                        rdf_wiredata, sizeof(rdf_wiredata));
269
270
271
272
}

TEST_F(Rdata_SSHFP_Test, emptyFingerprintFromString) {
    const generic::SSHFP rdata_sshfp2("5 6");
273
274
275
276
277
278
    const uint8_t rdata_sshfp2_wiredata[] = {
        // algorithm
        0x05,
        // fingerprint type
        0x06
    };
279

280
281
    EXPECT_EQ(5, rdata_sshfp2.getAlgorithmNumber());
    EXPECT_EQ(6, rdata_sshfp2.getFingerprintType());
282
    EXPECT_EQ(0, rdata_sshfp2.getFingerprintLen());
283
284
285
286
287
288
289
290
291
292

    this->obuffer.clear();
    rdata_sshfp2.toWire(this->obuffer);

    EXPECT_EQ(2, this->obuffer.getLength());

    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
                        this->obuffer.getData(),
                        this->obuffer.getLength(),
                        rdata_sshfp2_wiredata, sizeof(rdata_sshfp2_wiredata));
293
}
294
}