BIND 10 trac1357, updated. c3c1915586223bb1db2114ad5b2bd2189f632517 [1357] Internal TSIGContext::update method
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Sep 7 07:55:08 UTC 2012
The branch, trac1357 has been updated
via c3c1915586223bb1db2114ad5b2bd2189f632517 (commit)
from 1f5426f7eddcaea4742fe9537fa957534b254fe6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c3c1915586223bb1db2114ad5b2bd2189f632517
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Sep 7 09:53:54 2012 +0200
[1357] Internal TSIGContext::update method
To be used in the case when there's a message without TSIG in the middle
of signed stream. Also used in tests for now.
-----------------------------------------------------------------------
Summary of changes:
src/lib/dns/tests/tsig_unittest.cc | 82 +++++++++++++++++++++++-------------
src/lib/dns/tsig.cc | 22 +++++++++-
src/lib/dns/tsig.h | 13 ++++++
3 files changed, 86 insertions(+), 31 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dns/tests/tsig_unittest.cc b/src/lib/dns/tests/tsig_unittest.cc
index 55dcf0e..a5d3037 100644
--- a/src/lib/dns/tests/tsig_unittest.cc
+++ b/src/lib/dns/tests/tsig_unittest.cc
@@ -66,6 +66,22 @@ testGetTime() {
return (NOW);
}
+// Thin wrapper around TSIGContext to allow access to the
+// update method.
+class TestTSIGContext : public TSIGContext {
+public:
+ TestTSIGContext(const TSIGKey& key) :
+ TSIGContext(key)
+ {}
+ TestTSIGContext(const Name& key_name, const Name& algorithm_name,
+ const TSIGKeyRing& keyring) :
+ TSIGContext(key_name, algorithm_name, keyring)
+ {}
+ void update(const void* const data, size_t len) {
+ TSIGContext::update(data, len);
+ }
+};
+
class TSIGTest : public ::testing::Test {
protected:
TSIGTest() :
@@ -83,9 +99,10 @@ protected:
isc::util::detail::gettimeFunction = NULL;
decodeBase64("SFuWd/q99SzF8Yzd1QbB9g==", secret);
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name,
- TSIGKey::HMACMD5_NAME(),
- &secret[0], secret.size())));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACMD5_NAME(),
+ &secret[0],
+ secret.size())));
tsig_verify_ctx.reset(new TSIGContext(TSIGKey(test_name,
TSIGKey::HMACMD5_NAME(),
&secret[0],
@@ -116,7 +133,7 @@ protected:
static const unsigned int AA_FLAG = 0x2;
static const unsigned int RD_FLAG = 0x4;
- boost::scoped_ptr<TSIGContext> tsig_ctx;
+ boost::scoped_ptr<TestTSIGContext> tsig_ctx;
boost::scoped_ptr<TSIGContext> tsig_verify_ctx;
TSIGKeyRing keyring;
const uint16_t qid;
@@ -746,8 +763,8 @@ TEST_F(TSIGTest, badsigResponse) {
TEST_F(TSIGTest, badkeyResponse) {
// A similar test as badsigResponse but for BADKEY
isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>;
- tsig_ctx.reset(new TSIGContext(badkey_name, TSIGKey::HMACMD5_NAME(),
- keyring));
+ tsig_ctx.reset(new TestTSIGContext(badkey_name, TSIGKey::HMACMD5_NAME(),
+ keyring));
{
SCOPED_TRACE("Verify resulting in BADKEY");
commonVerifyChecks(*tsig_ctx, &dummy_record, &dummy_data[0],
@@ -956,45 +973,47 @@ TEST_F(TSIGTest, getTSIGLength) {
EXPECT_EQ(85, tsig_ctx->getTSIGLength());
// hmac-sha1: n2=11, x=20
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name, TSIGKey::HMACSHA1_NAME(),
- &dummy_data[0], 20)));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACSHA1_NAME(),
+ &dummy_data[0], 20)));
EXPECT_EQ(74, tsig_ctx->getTSIGLength());
// hmac-sha256: n2=13, x=32
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name,
- TSIGKey::HMACSHA256_NAME(),
- &dummy_data[0], 32)));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACSHA256_NAME(),
+ &dummy_data[0], 32)));
EXPECT_EQ(88, tsig_ctx->getTSIGLength());
// hmac-sha224: n2=13, x=28
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name,
- TSIGKey::HMACSHA224_NAME(),
- &dummy_data[0], 28)));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACSHA224_NAME(),
+ &dummy_data[0], 28)));
EXPECT_EQ(84, tsig_ctx->getTSIGLength());
// hmac-sha384: n2=13, x=48
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name,
- TSIGKey::HMACSHA384_NAME(),
- &dummy_data[0], 48)));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACSHA384_NAME(),
+ &dummy_data[0], 48)));
EXPECT_EQ(104, tsig_ctx->getTSIGLength());
// hmac-sha512: n2=13, x=64
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name,
- TSIGKey::HMACSHA512_NAME(),
- &dummy_data[0], 64)));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACSHA512_NAME(),
+ &dummy_data[0], 64)));
EXPECT_EQ(120, tsig_ctx->getTSIGLength());
// bad key case: n1=len(badkey.example.com)=20, n2=26, x=0
- tsig_ctx.reset(new TSIGContext(badkey_name, TSIGKey::HMACMD5_NAME(),
- keyring));
+ tsig_ctx.reset(new TestTSIGContext(badkey_name, TSIGKey::HMACMD5_NAME(),
+ keyring));
EXPECT_EQ(72, tsig_ctx->getTSIGLength());
// bad sig case: n1=17, n2=26, x=0
isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>;
createMessageFromFile("message_toWire2.wire");
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name, TSIGKey::HMACMD5_NAME(),
- &dummy_data[0],
- dummy_data.size())));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACMD5_NAME(),
+ &dummy_data[0],
+ dummy_data.size())));
{
SCOPED_TRACE("Verify resulting in BADSIG");
commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(),
@@ -1005,9 +1024,10 @@ TEST_F(TSIGTest, getTSIGLength) {
// bad time case: n1=17, n2=26, x=16, y=6
isc::util::detail::gettimeFunction = testGetTime<0x4da8877a - 1000>;
- tsig_ctx.reset(new TSIGContext(TSIGKey(test_name, TSIGKey::HMACMD5_NAME(),
- &dummy_data[0],
- dummy_data.size())));
+ tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name,
+ TSIGKey::HMACMD5_NAME(),
+ &dummy_data[0],
+ dummy_data.size())));
{
SCOPED_TRACE("Verify resulting in BADTIME");
commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(),
@@ -1059,7 +1079,11 @@ TEST_F(TSIGTest, verifyMulti) {
answer_rrset->addRdata(createRdata(RRType::A(), test_class,
"192.0.2.1"));
message.addRRset(Message::SECTION_ANSWER, answer_rrset);
- message.toWire(renderer, *tsig_ctx);
+ message.toWire(renderer);
+ // Update the internal state. We abuse the knowledge of
+ // internals here a little bit to generate correct test data
+ tsig_ctx->update(renderer.getData(), renderer.getLength());
+
commonVerifyChecks(*tsig_verify_ctx, NULL,
renderer.getData(), renderer.getLength(),
TSIGError(Rcode::NOERROR()),
diff --git a/src/lib/dns/tsig.cc b/src/lib/dns/tsig.cc
index 0c8a1f3..41624b2 100644
--- a/src/lib/dns/tsig.cc
+++ b/src/lib/dns/tsig.cc
@@ -138,7 +138,7 @@ struct TSIGContext::TSIGContextImpl {
// performance bottleneck, we could have this class a buffer as a member
// variable and reuse it throughout the object's lifetime. Right now,
// we prefer keeping the scope for local things as small as possible.
- void digestPreviousMAC(HMACPtr hmac) const;
+ void digestPreviousMAC(HMACPtr hmac);
void digestTSIGVariables(HMACPtr hmac, uint16_t rrclass, uint32_t rrttl,
uint64_t time_signed, uint16_t fudge,
uint16_t error, uint16_t otherlen,
@@ -160,11 +160,18 @@ struct TSIGContext::TSIGContextImpl {
};
void
-TSIGContext::TSIGContextImpl::digestPreviousMAC(HMACPtr hmac) const {
+TSIGContext::TSIGContextImpl::digestPreviousMAC(HMACPtr hmac) {
// We should have ensured the digest size fits 16 bits within this class
// implementation.
assert(previous_digest_.size() <= 0xffff);
+ if (previous_digest_.empty()) {
+ // The previous digest was already used. We're in the middle of
+ // TCP stream somewhere and we already pushed some unsigned message
+ // into the HMAC state.
+ return;
+ }
+
OutputBuffer buffer(sizeof(uint16_t) + previous_digest_.size());
const uint16_t previous_digest_len(previous_digest_.size());
buffer.writeUint16(previous_digest_len);
@@ -536,5 +543,16 @@ TSIGContext::lastHadSignature() const {
return (impl_->last_sig_dist_ == 0);
}
+void
+TSIGContext::update(const void* const data, size_t len) {
+ HMACPtr hmac(impl_->createHMAC());
+ // Use the previous digest and never use it again
+ impl_->digestPreviousMAC(hmac);
+ impl_->previous_digest_.clear();
+ // Push the message there
+ hmac->update(data, len);
+ impl_->hmac_ = hmac;
+}
+
} // namespace dns
} // namespace isc
diff --git a/src/lib/dns/tsig.h b/src/lib/dns/tsig.h
index 29a6ec5..e2a531a 100644
--- a/src/lib/dns/tsig.h
+++ b/src/lib/dns/tsig.h
@@ -413,6 +413,19 @@ public:
static const uint16_t DEFAULT_FUDGE = 300;
//@}
+protected:
+ /// \brief Update internal HMAC state by more data.
+ ///
+ /// This is used mostly internaly, when we need to verify a message without
+ /// TSIG signature in the middle of signed TCP stream. However, it is also
+ /// used in tests, so it's protected instead of private, to allow tests
+ /// in.
+ ///
+ /// It doesn't contain sanity checks, and it is not tested directly. But
+ /// we may want to add these one day to allow generating the skipped TSIG
+ /// messages too. Until then, do not use this method.
+ void update(const void* const data, size_t len);
+
private:
struct TSIGContextImpl;
TSIGContextImpl* impl_;
More information about the bind10-changes
mailing list