Commit efdf126e authored by JINMEI Tatuya's avatar JINMEI Tatuya

[trac893] added another constructor for TSIGContext: from key params and keyring.

parent 35a7c63a
......@@ -111,6 +111,7 @@ protected:
boost::scoped_ptr<TSIGContext> tsig_ctx;
boost::scoped_ptr<TSIGContext> tsig_verify_ctx;
TSIGKeyRing keyring;
const uint16_t qid;
const Name test_name;
const RRClass test_class;
......@@ -199,6 +200,33 @@ TEST_F(TSIGTest, initialState) {
EXPECT_EQ(TSIGError(Rcode::NOERROR()), tsig_ctx->getError());
TEST_F(TSIGTest, constructFromKeyRing) {
// Construct a TSIG context with an empty key ring. Key shouldn't be
// found, and the BAD_KEY error should be recorded.
TSIGContext ctx1(test_name, TSIGKey::HMACMD5_NAME(), keyring);
EXPECT_EQ(TSIGContext::INIT, ctx1.getState());
EXPECT_EQ(TSIGError::BAD_KEY(), ctx1.getError());
// Add a matching key (we don't use the secret so leave it empty), and
// construct it again. This time it should be constructed with a valid
// key.
keyring.add(TSIGKey(test_name, TSIGKey::HMACMD5_NAME(), NULL, 0));
TSIGContext ctx2(test_name, TSIGKey::HMACMD5_NAME(), keyring);
EXPECT_EQ(TSIGContext::INIT, ctx2.getState());
EXPECT_EQ(TSIGError::NOERROR(), ctx2.getError());
// Similar to the first case except that the key ring isn't empty but
// it doesn't contain a matching key.
TSIGContext ctx3(test_name, TSIGKey::HMACSHA1_NAME(), keyring);
EXPECT_EQ(TSIGContext::INIT, ctx3.getState());
EXPECT_EQ(TSIGError::BAD_KEY(), ctx3.getError());
TSIGContext ctx4(Name("different-key.example"), TSIGKey::HMACMD5_NAME(),
EXPECT_EQ(TSIGContext::INIT, ctx4.getState());
EXPECT_EQ(TSIGError::BAD_KEY(), ctx4.getError());
// Example output generated by
// "dig -y
// QID: 0x2d65
......@@ -44,6 +44,16 @@ namespace isc {
namespace dns {
namespace {
typedef boost::shared_ptr<HMAC> HMACPtr;
// This singleton key is used when the TSIG context is constructed with no
// matching key. The key name and algorithm won't be used in subsequent
// sign/verify, so the their values don't matter.
const TSIGKey&
getDummyTSIGKey() {
static TSIGKey dummy_key(Name::ROOT_NAME(), TSIGKey::HMACMD5_NAME(), NULL,
return (dummy_key);
struct TSIGContext::TSIGContextImpl {
......@@ -52,7 +62,7 @@ struct TSIGContext::TSIGContextImpl {
State state_;
TSIGKey key_;
const TSIGKey key_;
vector<uint8_t> previous_digest_;
TSIGError error_;
uint64_t previous_timesigned_; // only meaningful for response with BADTIME
......@@ -62,6 +72,19 @@ TSIGContext::TSIGContext(const TSIGKey& key) : impl_(new TSIGContextImpl(key))
TSIGContext::TSIGContext(const Name& key_name, const Name& algorithm_name,
const TSIGKeyRing& keyring) : impl_(NULL)
const TSIGKeyRing::FindResult result(keyring.find(key_name,
if (result.code == TSIGKeyRing::NOTFOUND) {
impl_ = new TSIGContextImpl(getDummyTSIGKey());
impl_->error_ = TSIGError::BAD_KEY();
} else {
impl_ = new TSIGContextImpl(*result.key);
TSIGContext::~TSIGContext() {
delete impl_;
......@@ -124,6 +124,10 @@ public:
/// \param key The TSIG key to be used for TSIG sessions with this context.
explicit TSIGContext(const TSIGKey& key);
/// Constructor from key parameters and key ring.
TSIGContext(const Name& key_name, const Name& algorithm_name,
const TSIGKeyRing& keyring);
/// The destructor.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment