Commit 5aaa6c0f authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[master] Merge branch 'trac893'

parents 29d36377 345b5986
......@@ -12,4 +12,4 @@ functionConst:src/lib/cache/rrset_cache.h
// Intentional self assignment tests. Suppress warning about them.
selfAssignment:src/lib/dns/tests/name_unittest.cc:293
selfAssignment:src/lib/dns/tests/rdata_unittest.cc:228
selfAssignment:src/lib/dns/tests/tsigkey_unittest.cc:120
selfAssignment:src/lib/dns/tests/tsigkey_unittest.cc:125
......@@ -144,8 +144,17 @@ public:
// Botan's verify_mac checks if len matches the output_length,
// which causes it to fail for truncated signatures, so we do
// the check ourselves
// SEE BELOW FOR TEMPORARY CHANGE
try {
Botan::SecureVector<Botan::byte> our_mac = hmac_->final();
if (len < getOutputLength()) {
// Currently we don't support truncated signature. To avoid
// validating too short signature accidently, we enforce the
// standard signature size for the moment.
// Once we support truncation correctly, this if-clause should
// (and the capitalized comment above) be removed.
return (false);
}
if (len == 0 || len > getOutputLength()) {
len = getOutputLength();
}
......
......@@ -233,18 +233,6 @@ TEST(CryptoLinkTest, HMAC_MD5_RFC2202_SIGN) {
0x79 };
doHMACTest(data4, secret4, 25, MD5, hmac_expected4, 16);
const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c };
const uint8_t hmac_expected5[] = { 0x56, 0x46, 0x1e, 0xf2, 0x34,
0x2e, 0xdc, 0x00, 0xf9, 0xba,
0xb9, 0x95, 0x69, 0x0e, 0xfd,
0x4c };
doHMACTest("Test With Truncation", secret5, 16, MD5,
hmac_expected5, 16);
doHMACTest("Test With Truncation", secret5, 16, MD5,
hmac_expected5, 12);
const uint8_t hmac_expected6[] = { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b,
0xd7, 0xbf, 0x8f, 0x0b, 0x62,
0xe6, 0xce, 0x61, 0xb9, 0xd0,
......@@ -261,6 +249,21 @@ TEST(CryptoLinkTest, HMAC_MD5_RFC2202_SIGN) {
std::string(80, 0xaa).c_str(), 80, MD5, hmac_expected7, 16);
}
// Temporarily disabled
TEST(CryptoLinkTest, DISABLED_HMAC_MD5_RFC2202_SIGN_TRUNCATED) {
const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c };
const uint8_t hmac_expected5[] = { 0x56, 0x46, 0x1e, 0xf2, 0x34,
0x2e, 0xdc, 0x00, 0xf9, 0xba,
0xb9, 0x95, 0x69, 0x0e, 0xfd,
0x4c };
doHMACTest("Test With Truncation", secret5, 16, MD5,
hmac_expected5, 16);
doHMACTest("Test With Truncation", secret5, 16, MD5,
hmac_expected5, 12);
}
//
// Test values taken from RFC 2202
//
......@@ -302,19 +305,6 @@ TEST(CryptoLinkTest, HMAC_SHA1_RFC2202_SIGN) {
0x6c, 0x2d, 0x72, 0x35, 0xda };
doHMACTest(std::string(50, 0xcd), secret4, 25, SHA1, hmac_expected4, 20);
const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c };
const uint8_t hmac_expected5[] = { 0x4c, 0x1a, 0x03, 0x42, 0x4b,
0x55, 0xe0, 0x7f, 0xe7, 0xf2,
0x7b, 0xe1, 0xd5, 0x8b, 0xb9,
0x32, 0x4a, 0x9a, 0x5a, 0x04 };
doHMACTest("Test With Truncation", secret5, 20, SHA1,
hmac_expected5, 20);
doHMACTest("Test With Truncation", secret5, 20, SHA1,
hmac_expected5, 12);
const uint8_t hmac_expected6[] = { 0xaa, 0x4a, 0xe5, 0xe1, 0x52,
0x72, 0xd0, 0x0e, 0x95, 0x70,
0x56, 0x37, 0xce, 0x8a, 0x3b,
......@@ -331,6 +321,22 @@ TEST(CryptoLinkTest, HMAC_SHA1_RFC2202_SIGN) {
std::string(80, 0xaa).c_str(), 80, SHA1, hmac_expected7, 20);
}
// Temporarily disabled
TEST(CryptoLinkTest, DISABLED_HMAC_SHA1_RFC2202_SIGN_TRUNCATED) {
const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c };
const uint8_t hmac_expected5[] = { 0x4c, 0x1a, 0x03, 0x42, 0x4b,
0x55, 0xe0, 0x7f, 0xe7, 0xf2,
0x7b, 0xe1, 0xd5, 0x8b, 0xb9,
0x32, 0x4a, 0x9a, 0x5a, 0x04 };
doHMACTest("Test With Truncation", secret5, 20, SHA1,
hmac_expected5, 20);
doHMACTest("Test With Truncation", secret5, 20, SHA1,
hmac_expected5, 12);
}
//
// Test values taken from RFC 4231
//
......@@ -384,17 +390,6 @@ TEST(CryptoLinkTest, HMAC_SHA256_RFC2202_SIGN) {
0x66, 0x5b };
doHMACTest(std::string(50, 0xcd), secret4, 25, SHA256, hmac_expected4, 32);
const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c };
const uint8_t hmac_expected5[] = { 0xa3, 0xb6, 0x16, 0x74, 0x73,
0x10, 0x0e, 0xe0, 0x6e, 0x0c,
0x79, 0x6c, 0x29, 0x55, 0x55,
0x2b };
doHMACTest("Test With Truncation", secret5, 20, SHA256,
hmac_expected5, 16);
const uint8_t hmac_expected6[] = { 0x60, 0xe4, 0x31, 0x59, 0x1e,
0xe0, 0xb6, 0x7f, 0x0d, 0x8a,
0x26, 0xaa, 0xcb, 0xf5, 0xb7,
......@@ -418,6 +413,19 @@ TEST(CryptoLinkTest, HMAC_SHA256_RFC2202_SIGN) {
std::string(131, 0xaa).c_str(), 131, SHA256, hmac_expected7, 32);
}
TEST(CryptoLinkTest, DISABLED_HMAC_SHA256_RFC2202_SIGN_TRUNCATED) {
const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c };
const uint8_t hmac_expected5[] = { 0xa3, 0xb6, 0x16, 0x74, 0x73,
0x10, 0x0e, 0xe0, 0x6e, 0x0c,
0x79, 0x6c, 0x29, 0x55, 0x55,
0x2b };
doHMACTest("Test With Truncation", secret5, 20, SHA256,
hmac_expected5, 16);
}
namespace {
size_t
sigVectorLength(HashAlgorithm alg, size_t len) {
......
......@@ -68,6 +68,9 @@ class TSIGKeyTest(unittest.TestCase):
class TSIGKeyRingTest(unittest.TestCase):
key_name = Name('example.com')
md5_name = Name('hmac-md5.sig-alg.reg.int')
sha1_name = Name('hmac-sha1')
sha256_name = Name('hmac-sha256')
secret = b'someRandomData'
def setUp(self):
......@@ -152,18 +155,26 @@ class TSIGKeyRingTest(unittest.TestCase):
def test_find(self):
self.assertEqual((TSIGKeyRing.NOTFOUND, None),
self.keyring.find(self.key_name))
self.keyring.find(self.key_name, self.md5_name))
self.assertEqual(TSIGKeyRing.SUCCESS,
self.keyring.add(TSIGKey(self.key_name,
TSIGKey.HMACSHA256_NAME,
self.sha256_name,
self.secret)))
(code, key) = self.keyring.find(self.key_name)
(code, key) = self.keyring.find(self.key_name, self.sha256_name)
self.assertEqual(TSIGKeyRing.SUCCESS, code)
self.assertEqual(self.key_name, key.get_key_name())
self.assertEqual(TSIGKey.HMACSHA256_NAME, key.get_algorithm_name())
self.assertEqual(self.secret, key.get_secret())
(code, key) = self.keyring.find(Name('different-key.example'),
self.sha256_name)
self.assertEqual(TSIGKeyRing.NOTFOUND, code)
self.assertEqual(None, key)
(code, key) = self.keyring.find(self.key_name, self.md5_name)
self.assertEqual(TSIGKeyRing.NOTFOUND, code)
self.assertEqual(None, key)
self.assertRaises(TypeError, self.keyring.find, 1)
self.assertRaises(TypeError, self.keyring.find, 'should be a name')
self.assertRaises(TypeError, self.keyring.find, self.key_name, 0)
......@@ -171,24 +182,28 @@ class TSIGKeyRingTest(unittest.TestCase):
def test_find_from_some(self):
self.assertEqual(TSIGKeyRing.SUCCESS,
self.keyring.add(TSIGKey(self.key_name,
TSIGKey.HMACSHA256_NAME,
self.sha256_name,
self.secret)))
self.assertEqual(TSIGKeyRing.SUCCESS,
self.keyring.add(TSIGKey(Name('another.example'),
TSIGKey.HMACMD5_NAME,
self.md5_name,
self.secret)))
self.assertEqual(TSIGKeyRing.SUCCESS,
self.keyring.add(TSIGKey(Name('more.example'),
TSIGKey.HMACSHA1_NAME,
self.sha1_name,
self.secret)))
(code, key) = self.keyring.find(Name('another.example'))
(code, key) = self.keyring.find(Name('another.example'), self.md5_name)
self.assertEqual(TSIGKeyRing.SUCCESS, code)
self.assertEqual(Name('another.example'), key.get_key_name())
self.assertEqual(TSIGKey.HMACMD5_NAME, key.get_algorithm_name())
self.assertEqual((TSIGKeyRing.NOTFOUND, None),
self.keyring.find(Name('noexist.example')))
self.keyring.find(Name('noexist.example'),
self.sha1_name))
self.assertEqual((TSIGKeyRing.NOTFOUND, None),
self.keyring.find(Name('another.example'),
self.sha1_name))
if __name__ == '__main__':
unittest.main()
......@@ -416,10 +416,12 @@ TSIGKeyRing_remove(const s_TSIGKeyRing* self, PyObject* args) {
PyObject*
TSIGKeyRing_find(const s_TSIGKeyRing* self, PyObject* args) {
s_Name* key_name;
s_Name* algorithm_name;
if (PyArg_ParseTuple(args, "O!", &name_type, &key_name)) {
if (PyArg_ParseTuple(args, "O!O!", &name_type, &key_name,
&name_type, &algorithm_name)) {
const TSIGKeyRing::FindResult result =
self->keyring->find(*key_name->name);
self->keyring->find(*key_name->name, *algorithm_name->name);
if (result.key != NULL) {
s_TSIGKey* key = PyObject_New(s_TSIGKey, &tsigkey_type);
if (key == NULL) {
......
......@@ -40,6 +40,10 @@ BUILT_SOURCES += rdata_tsig_toWire1.wire rdata_tsig_toWire2.wire
BUILT_SOURCES += rdata_tsig_toWire3.wire rdata_tsig_toWire4.wire
BUILT_SOURCES += rdata_tsig_toWire5.wire
BUILT_SOURCES += tsigrecord_toWire1.wire tsigrecord_toWire2.wire
BUILT_SOURCES += tsig_verify1.wire tsig_verify2.wire tsig_verify3.wire
BUILT_SOURCES += tsig_verify4.wire tsig_verify5.wire tsig_verify6.wire
BUILT_SOURCES += tsig_verify7.wire tsig_verify8.wire tsig_verify9.wire
BUILT_SOURCES += tsig_verify10.wire
# NOTE: keep this in sync with real file listing
# so is included in tarball
......@@ -108,6 +112,10 @@ EXTRA_DIST += rdata_tsig_toWire1.spec rdata_tsig_toWire2.spec
EXTRA_DIST += rdata_tsig_toWire3.spec rdata_tsig_toWire4.spec
EXTRA_DIST += rdata_tsig_toWire5.spec
EXTRA_DIST += tsigrecord_toWire1.spec tsigrecord_toWire2.spec
EXTRA_DIST += tsig_verify1.spec tsig_verify2.spec tsig_verify3.spec
EXTRA_DIST += tsig_verify4.spec tsig_verify5.spec tsig_verify6.spec
EXTRA_DIST += tsig_verify7.spec tsig_verify8.spec tsig_verify9.spec
EXTRA_DIST += tsig_verify10.spec
.spec.wire:
./gen-wiredata.py -o $@ $<
......@@ -283,9 +283,8 @@ class NS(RR):
f.write('# NS name=%s\n' % (self.nsname))
f.write('%s\n' % nsname_wire)
class SOA:
# this currently doesn't support name compression within the RDATA.
rdlen = -1 # auto-calculate
class SOA(RR):
rdlen = None # auto-calculate
mname = 'ns.example.com'
rname = 'root.example.com'
serial = 2010012601
......@@ -296,11 +295,9 @@ class SOA:
def dump(self, f):
mname_wire = encode_name(self.mname)
rname_wire = encode_name(self.rname)
rdlen = self.rdlen
if rdlen < 0:
rdlen = int(20 + len(mname_wire) / 2 + len(str(rname_wire)) / 2)
f.write('\n# SOA RDATA (RDLEN=%d)\n' % rdlen)
f.write('%04x\n' % rdlen);
if self.rdlen is None:
self.rdlen = int(20 + len(mname_wire) / 2 + len(str(rname_wire)) / 2)
self.dump_header(f, self.rdlen)
f.write('# NNAME=%s RNAME=%s\n' % (self.mname, self.rname))
f.write('%s %s\n' % (mname_wire, rname_wire))
f.write('# SERIAL(%d) REFRESH(%d) RETRY(%d) EXPIRE(%d) MINIMUM(%d)\n' %
......
#
# An example of signed AXFR request
#
[custom]
sections: header:question:tsig
[header]
id: 0x3410
arcount: 1
[question]
rrtype: AXFR
[tsig]
as_rr: True
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8e951
mac_size: 16
mac: 0x35b2fd08268781634400c7c8a5533b13
original_id: 0x3410
#
# A simple DNS query message with TSIG signed whose MAC is too short
# (only 1 byte)
#
[custom]
sections: header:question:tsig
[header]
id: 0x2d65
rd: 1
arcount: 1
[question]
name: www.example.com
[tsig]
as_rr: True
# TSIG QNAME won't be compressed
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8877a
mac_size: 1
mac: 0x22
original_id: 0x2d65
#
# An example of signed AXFR response
#
[custom]
sections: header:question:soa:tsig
[header]
id: 0x3410
aa: 1
qr: 1
ancount: 1
arcount: 1
[question]
rrtype: AXFR
[soa]
# note that names are compressed in this RR
as_rr: True
rr_name: ptr=12
mname: ns.ptr=12
rname: root.ptr=12
serial: 2011041503
refresh: 7200
retry: 3600
expire: 2592000
[tsig]
as_rr: True
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8e951
mac_size: 16
mac: 0xbdd612cd2c7f9e0648bd6dc23713e83c
original_id: 0x3410
#
# An example of signed AXFR response (continued)
#
[custom]
sections: header:ns:tsig
[header]
id: 0x3410
aa: 1
qr: 1
qdcount: 0
ancount: 1
arcount: 1
[ns]
# note that names are compressed in this RR
as_rr: True
rr_name: example.com.
nsname: ns.ptr=12
[tsig]
as_rr: True
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8e951
mac_size: 16
mac: 0x102458f7f62ddd7d638d746034130968
original_id: 0x3410
#
# An example of signed DNS response with bogus MAC
#
[custom]
sections: header:question:a:tsig
[header]
id: 0x2d65
aa: 1
qr: 1
rd: 1
ancount: 1
arcount: 1
[question]
name: www.example.com
[a]
as_rr: True
rr_name: ptr=12
[tsig]
as_rr: True
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8877a
mac_size: 16
# bogus MAC
mac: 0xdeadbeefdeadbeefdeadbeefdeadbeef
original_id: 0x2d65
#
# An example of signed DNS response
#
[custom]
sections: header:question:a:tsig
[header]
id: 0x2d65
aa: 1
qr: 1
rd: 1
ancount: 1
arcount: 1
[question]
name: www.example.com
[a]
as_rr: True
rr_name: ptr=12
[tsig]
as_rr: True
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8877a
mac_size: 16
mac: 0x8fcda66a7cd1a3b9948eb1869d384a9f
original_id: 0x2d65
#
# Forwarded DNS query message with TSIG signed (header ID != orig ID)
#
[custom]
sections: header:question:tsig
[header]
id: 0x1035
rd: 1
arcount: 1
[question]
name: www.example.com
[tsig]
as_rr: True
# TSIG QNAME won't be compressed
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8877a
mac_size: 16
mac: 0x227026ad297beee721ce6c6fff1e9ef3
original_id: 0x2d65
#
# DNS query message with TSIG that has empty MAC (invalidly)
#
[custom]
sections: header:question:tsig
[header]
id: 0x2d65
rd: 1
arcount: 1
[question]
name: www.example.com
[tsig]
as_rr: True
# TSIG QNAME won't be compressed
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8877a
mac_size: 0
mac: ''
original_id: 0x2d65
#
# DNS query message with TSIG that has empty MAC + BADKEY error
#
[custom]
sections: header:question:tsig
[header]
id: 0x2d65
rd: 1
arcount: 1
[question]
name: www.example.com
[tsig]
as_rr: True
# TSIG QNAME won't be compressed
rr_name: www.example.com
algorithm: hmac-md5
time_signed: 0x4da8877a
mac_size: 0
mac: ''
# 17: BADKEY
error: 17
original_id: 0x2d65
#
# A simple DNS query message with TSIG signed, but TSIG key and algorithm
# names have upper case characters (unusual)
#
[custom]
sections: header:question:tsig
[header]
id: 0x2d65
rd: 1
arcount: 1
[question]
name: www.example.com
[tsig]
as_rr: True
rr_name: WWW.EXAMPLE.COM
algorithm: HMAC-MD5.SIG-ALG.REG.INT
time_signed: 0x4da8877a
mac_size: 16
mac: 0x227026ad297beee721ce6c6fff1e9ef3
original_id: 0x2d65
This diff is collapsed.
......@@ -93,6 +93,20 @@ TEST(TSIGErrorTest, toText) {
EXPECT_EQ("65535", TSIGError(65535).toText());
}
TEST(TSIGErrorTest, toRcode) {
// TSIGError derived from the standard Rcode
EXPECT_EQ(Rcode::NOERROR(), TSIGError(Rcode::NOERROR()).toRcode());
// Well known TSIG errors
EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_SIG().toRcode());
EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_KEY().toRcode());
EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_TIME().toRcode());
// Unknown (or not yet supported) codes are treated as SERVFAIL.
EXPECT_EQ(Rcode::SERVFAIL(), TSIGError(19).toRcode());
EXPECT_EQ(Rcode::SERVFAIL(), TSIGError(65535).toRcode());
}
// test operator<<. We simply confirm it appends the result of toText().
TEST(TSIGErrorTest, LeftShiftOperator) {
ostringstream oss;
......
......@@ -33,7 +33,7 @@ class TSIGKeyTest : public ::testing::Test {
protected:
TSIGKeyTest() : secret("someRandomData"), key_name("example.com") {}
string secret;
Name key_name;
const Name key_name;
};
TEST_F(TSIGKeyTest, algorithmNames) {
......@@ -59,9 +59,13 @@ TEST_F(TSIGKeyTest, construct) {
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, secret.c_str(),
secret.size(), key.getSecret(), key.getSecretLength());
// "unknown" algorithm is only accepted with empty secret.
EXPECT_THROW(TSIGKey(key_name, Name("unknown-alg"),
secret.c_str(), secret.size()),
isc::InvalidParameter);
TSIGKey key2(key_name, Name("unknown-alg"), NULL, 0);
EXPECT_EQ(key_name, key2.getKeyName());
EXPECT_EQ(Name("unknown-alg"), key2.getAlgorithmName());
// The algorithm name should be converted to the canonical form.
EXPECT_EQ("hmac-sha1.",
......@@ -69,6 +73,7 @@ TEST_F(TSIGKeyTest, construct) {
secret.c_str(),
secret.size()).getAlgorithmName().toText());
// Same for key name
EXPECT_EQ("example.com.",
TSIGKey(Name("EXAMPLE.CoM."), TSIGKey::HMACSHA256_NAME(),
secret.c_str(),
......@@ -125,12 +130,18 @@ class TSIGKeyRingTest : public ::testing::Test {
protected:
TSIGKeyRingTest() :
key_name("example.com"),
md5_name("hmac-md5.sig-alg.reg.int"),
sha1_name("hmac-sha1"),
sha256_name("hmac-sha256"),
secretstring("anotherRandomData"),
secret(secretstring.c_str()),
secret_len(secretstring.size())
{}
TSIGKeyRing keyring;
Name key_name;