Commit a7e2adfa authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

(minimum level of) RRSIG support


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/parkinglot@728 e5f2f494-b856-4b98-b285-d166d9295462
parent c635b9ac
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// 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.
// $Id$
#include <string>
#include <sstream>
#include <vector>
#include "base64.h"
#include "buffer.h"
#include "messagerenderer.h"
#include "name.h"
#include "rrtype.h"
#include "rrttl.h"
#include "rdata.h"
#include "rdataclass.h"
using namespace std;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
namespace {
inline uint32_t
convertDNSSECTime(const string time_txt)
{
istringstream iss(time_txt);
uint32_t timeval;
iss >> timeval;
// right now, we don't support the YYYYMMDDHHmmSS format for
// expire/inception
if (iss.bad() || iss.fail() || !iss.eof()) {
dns_throw(InvalidRdataText, "Invalid RRSIG Time format");
}
return (timeval);
}
}
struct RRSIGImpl {
// straightforward representation of RRSIG RDATA fields
RRSIGImpl(const RRType& covered, uint8_t algorithm, uint8_t labels,
uint32_t originalttl, uint32_t timeexpire, uint32_t timeinception,
uint16_t keyid, const Name& signer,
const vector<char>& signature) :
covered_(covered), algorithm_(algorithm), labels_(labels),
originalttl_(originalttl), timeexpire_(timeexpire),
timeinception_(timeinception), keyid_(keyid), signer_(signer),
signature_(signature)
{}
const RRType covered_;
uint8_t algorithm_;
uint8_t labels_;
uint32_t originalttl_;
uint32_t timeexpire_;
uint32_t timeinception_;
uint16_t keyid_;
const Name signer_;
const vector<char> signature_;
};
RRSIG::RRSIG(const string& rrsig_str) :
impl_(NULL)
{
istringstream iss(rrsig_str);
string covered_txt, signer_txt, expire_txt, inception_txt;
unsigned int algorithm, labels;
uint32_t originalttl;
uint16_t keyid;
stringbuf signaturebuf;
iss >> covered_txt >> algorithm >> labels >> originalttl
>> expire_txt >> inception_txt >> keyid >> signer_txt
>> &signaturebuf;
if (iss.bad() || iss.fail() || !iss.eof()) {
dns_throw(InvalidRdataText, "Invalid RRSIG text");
}
if (algorithm > 0xff) {
dns_throw(InvalidRdataText, "RRSIG algorithm out of range");
}
if (labels > 0xff) {
dns_throw(InvalidRdataText, "RRSIG labels out of range");
}
uint32_t timeexpire = convertDNSSECTime(expire_txt);
uint32_t timeinception = convertDNSSECTime(inception_txt);
vector<char> signature;
decodeBase64(signaturebuf.str(), signature);
impl_ = new RRSIGImpl(RRType(covered_txt), algorithm, labels,
originalttl, timeexpire, timeinception, keyid,
Name(signer_txt), signature);
}
RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len)
{
}
RRSIG::RRSIG(const RRSIG& source) :
impl_(new RRSIGImpl(*source.impl_))
{}
RRSIG&
RRSIG::operator=(const RRSIG& source)
{
if (impl_ == source.impl_) {
return (*this);
}
RRSIGImpl* newimpl = new RRSIGImpl(*impl_);
delete impl_;
impl_ = newimpl;
return (*this);
}
RRSIG::~RRSIG()
{
delete impl_;
}
string
RRSIG::toText() const
{
return (impl_->covered_.toText() +
" " + lexical_cast<string>(static_cast<int>(impl_->algorithm_))
+ " " + lexical_cast<string>(static_cast<int>(impl_->labels_))
+ " " + lexical_cast<string>(impl_->originalttl_)
+ " " + lexical_cast<string>(impl_->timeexpire_)
+ " " + lexical_cast<string>(impl_->timeinception_)
+ " " + lexical_cast<string>(impl_->keyid_)
+ " " + impl_->signer_.toText()
+ " " + encodeBase64(impl_->signature_));
}
void
RRSIG::toWire(OutputBuffer& buffer) const
{
impl_->covered_.toWire(buffer);
buffer.writeUint8(impl_->algorithm_);
buffer.writeUint8(impl_->labels_);
buffer.writeUint32(impl_->originalttl_);
buffer.writeUint32(impl_->timeexpire_);
buffer.writeUint32(impl_->timeinception_);
buffer.writeUint16(impl_->keyid_);
impl_->signer_.toWire(buffer);
buffer.writeData(&impl_->signature_[0], impl_->signature_.size());
}
void
RRSIG::toWire(MessageRenderer& renderer) const
{
impl_->covered_.toWire(renderer);
renderer.writeUint8(impl_->algorithm_);
renderer.writeUint8(impl_->labels_);
renderer.writeUint32(impl_->originalttl_);
renderer.writeUint32(impl_->timeexpire_);
renderer.writeUint32(impl_->timeinception_);
renderer.writeUint16(impl_->keyid_);
renderer.writeName(impl_->signer_, false);
renderer.writeData(&impl_->signature_[0], impl_->signature_.size());
}
int
RRSIG::compare(const Rdata& other) const
{
const RRSIG& other_rrsig = dynamic_cast<const RRSIG&>(other);
if (impl_->covered_.getCode() != other_rrsig.impl_->covered_.getCode()) {
return (impl_->covered_.getCode() <
other_rrsig.impl_->covered_.getCode() ? -1 : 1);
}
if (impl_->algorithm_ != other_rrsig.impl_->algorithm_) {
return (impl_->algorithm_ < other_rrsig.impl_->algorithm_ ? -1 : 1);
}
if (impl_->labels_ != other_rrsig.impl_->labels_) {
return (impl_->labels_ < other_rrsig.impl_->labels_ ? -1 : 1);
}
if (impl_->originalttl_ != other_rrsig.impl_->originalttl_) {
return (impl_->originalttl_ < other_rrsig.impl_->originalttl_ ?
-1 : 1);
}
if (impl_->timeexpire_ != other_rrsig.impl_->timeexpire_) {
return (impl_->timeexpire_ < other_rrsig.impl_->timeexpire_ ?
-1 : 1);
}
if (impl_->timeinception_ != other_rrsig.impl_->timeinception_) {
return (impl_->timeinception_ < other_rrsig.impl_->timeinception_ ?
-1 : 1);
}
if (impl_->keyid_ != other_rrsig.impl_->keyid_) {
return (impl_->keyid_ < other_rrsig.impl_->keyid_ ? -1 : 1);
}
int cmp = compareNames(impl_->signer_, other_rrsig.impl_->signer_);
if (cmp != 0) {
return (cmp);
}
size_t this_len = impl_->signature_.size();
size_t other_len = other_rrsig.impl_->signature_.size();
size_t cmplen = min(this_len, other_len);
cmp = memcmp(&impl_->signature_[0], &other_rrsig.impl_->signature_[0],
cmplen);
if (cmp != 0) {
return (cmp);
} else {
return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
}
}
// END_RDATA_NAMESPACE
// END_ISC_NAMESPACE
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// 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.
// $Id$
#include <stdint.h>
#include <string>
#include "name.h"
#include "rrtype.h"
#include "rrttl.h"
#include "rdata.h"
// BEGIN_HEADER_GUARD
// BEGIN_ISC_NAMESPACE
// BEGIN_COMMON_DECLARATIONS
// END_COMMON_DECLARATIONS
// BEGIN_RDATA_NAMESPACE
struct RRSIGImpl;
class RRSIG : public Rdata {
public:
// BEGIN_COMMON_MEMBERS
// END_COMMON_MEMBERS
RRSIG& operator=(const RRSIG& source);
~RRSIG();
private:
RRSIGImpl* impl_;
};
// END_RDATA_NAMESPACE
// END_ISC_NAMESPACE
// END_HEADER_GUARD
// Local Variables:
// mode: c++
// End:
......@@ -505,4 +505,26 @@ TEST_F(RdataTest, getCname_CNAME)
EXPECT_EQ(Name("cn.example.com."), rdata_cname.getCname());
}
TEST_F(RdataTest, fromText_RRSIG)
{
string rrsig_txt("A 5 4 43200 1264801134 191145710 8496 isc.org. "
"evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
"diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
"NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
"f49t+sXKPzbipN9g+s1ZPiIyofc=");
generic::RRSIG rdata_rrsig(rrsig_txt);
EXPECT_EQ(rrsig_txt, rdata_rrsig.toText());
}
TEST_F(RdataTest, toWireRenderer_RRSIG)
{
string rrsig_txt("A 5 4 43200 1264801134 191145710 8496 isc.org. "
"evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
"diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
"NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
"f49t+sXKPzbipN9g+s1ZPiIyofc=");
generic::RRSIG rdata_rrsig(rrsig_txt);
rdata_rrsig.toWire(renderer);
}
}
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