16 #include <boost/shared_ptr.hpp>
40 typedef boost::shared_ptr<HMAC> HMACPtr;
57 state_(INIT), key_(key), error_(
error),
58 previous_timesigned_(0), digest_len_(0),
61 if (
error == TSIGError::NOERROR()) {
72 hmac_.reset(CryptoLink::getCryptoLink().createHMAC(
73 key_.getSecret(), key_.getSecretLength(),
79 size_t digestbits = key_.getDigestbits();
80 size_t default_digest_len = hmac_->getOutputLength();
82 digest_len_ = (digestbits + 7) / 8;
84 if ((digest_len_ < 10) ||
85 (digest_len_ < (default_digest_len / 2)) ||
86 (digest_len_ > default_digest_len)) {
88 digest_len_ = default_digest_len;
91 digest_len_ = default_digest_len;
104 if (state_ == INIT) {
105 state_ = RECEIVED_REQUEST;
106 }
else if (state_ == SENT_REQUEST && error == TSIGError::NOERROR()) {
107 state_ = VERIFIED_RESPONSE;
109 if (digest != NULL) {
110 previous_digest_.assign(static_cast<const uint8_t*>(digest),
111 static_cast<const uint8_t*>(digest) +
125 HMACPtr ret = HMACPtr();
129 return (HMACPtr(CryptoLink::getCryptoLink().createHMAC(
130 key_.getSecret(), key_.getSecretLength(),
131 key_.getAlgorithm()),
148 void digestPreviousMAC(HMACPtr hmac);
149 void digestTSIGVariables(HMACPtr hmac, uint16_t rrclass, uint32_t rrttl,
150 uint64_t time_signed, uint16_t fudge,
151 uint16_t
error, uint16_t otherlen,
152 const void* otherdata,
153 bool time_variables_only)
const;
154 void digestDNSMessage(HMACPtr hmac, uint16_t qid,
const void* data,
155 size_t data_len)
const;
170 TSIGContext::TSIGContextImpl::digestPreviousMAC(HMACPtr hmac) {
173 assert(previous_digest_.size() <= 0xffff);
175 if (previous_digest_.empty()) {
182 OutputBuffer buffer(
sizeof(uint16_t) + previous_digest_.size());
183 const uint16_t previous_digest_len(previous_digest_.size());
185 if (previous_digest_len != 0) {
186 buffer.writeData(&previous_digest_[0], previous_digest_len);
188 hmac->update(buffer.getData(), buffer.getLength());
192 TSIGContext::TSIGContextImpl::digestTSIGVariables(
193 HMACPtr hmac, uint16_t rrclass, uint32_t rrttl, uint64_t time_signed,
194 uint16_t fudge, uint16_t
error, uint16_t otherlen,
const void* otherdata,
195 bool time_variables_only)
const
201 size_t data_size = 8;
202 if (!time_variables_only) {
203 data_size += 10 + key_.getKeyName().getLength() +
204 key_.getAlgorithmName().getLength();
208 if (!time_variables_only) {
209 key_.getKeyName().toWire(buffer);
212 key_.getAlgorithmName().toWire(buffer);
218 if (!time_variables_only) {
224 if (!time_variables_only && otherlen > 0) {
225 hmac->update(otherdata, otherlen);
241 const size_t MESSAGE_HEADER_LEN = 12;
244 TSIGContext::TSIGContextImpl::digestDNSMessage(HMACPtr hmac,
245 uint16_t qid,
const void* data,
246 size_t data_len)
const
249 const uint8_t* msgptr =
static_cast<const uint8_t*
>(data);
253 msgptr +=
sizeof(uint16_t);
266 hmac->update(msgptr, data_len - MESSAGE_HEADER_LEN);
320 const size_t digest_len =
330 digest_len + other_len);
345 const size_t data_len)
349 "TSIG sign attempt after verifying a response");
352 if (data == NULL || data_len == 0) {
357 const uint64_t now = getTSIGTime();
371 qid, error.
getCode(), 0, NULL)));
386 hmac->update(data, data_len);
400 const void*
const otherdata =
401 (otherlen == 0) ? NULL : otherdatabuf.
getData();
413 assert(digest.size() <= 0xffff);
418 digest.size(), &digest[0],
419 qid, error.
getCode(), otherlen,
429 const size_t data_len)
433 "TSIG verify attempt after sending a response");
436 if (record == NULL) {
457 if (data_len < MESSAGE_HEADER_LEN + record->getLength()) {
459 "TSIG verify: data length is invalid: " << data_len);
486 const uint64_t now = getTSIGTime();
489 const void*
digest = NULL;
490 size_t digest_len = 0;
492 digest = tsig_rdata.
getMAC();
522 if (tsig_rdata.
getMACSize() > hmac->getOutputLength()) {
527 (tsig_rdata.
getMACSize() < (hmac->getOutputLength() / 2))) {
582 hmac->update(data, len);
rdata::TSIG class represents the TSIG RDATA as defined in RFC2845.
The Name class encapsulates DNS names.
uint64_t previous_timesigned_
int64_t gettimeWrapper()
Return the current time in seconds.
static const TSIGError & FORMERR()
A constant TSIG error object derived from Rcode::FORMERR()
static const uint32_t TSIG_TTL
The TTL value to be used in TSIG RRs.
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
static const TSIGError & BAD_TRUNC()
A constant TSIG error object for the BADTRUNC code (see TSIGError::BAD_TRUNC_CODE).
TSIGError postVerifyUpdate(TSIGError error, const void *digest, uint16_t digest_len)
uint16_t getError() const
Return the value of the Error field.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
uint16_t getOtherLen() const
Return the value of the Other Len field.
ConstTSIGRecordPtr sign(const uint16_t qid, const void *const data, const size_t data_len)
Sign a DNS message.
State getState() const
Return the current state of the context.
TSIGError getError() const
Return the TSIG error as a result of the latest verification.
static const uint16_t DEFAULT_FUDGE
The recommended fudge value (in seconds) by RFC2845.
A helper structure to represent the search result of TSIGKeyRing::find().
Server sent a signed response.
State
Internal state of context.
static const TSIGError & BAD_KEY()
A constant TSIG error object for the BADKEY code (see TSIGError::BAD_KEY_CODE).
Server received a signed request.
uint16_t getMACSize() const
Return the value of the MAC Size field.
Client sent a signed request, waiting response.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
static const TSIGError & BAD_SIG()
A constant TSIG error object for the BADSIG code (see TSIGError::BAD_SIG_CODE).
static const RRClass & getClass()
Return the RR class of TSIG.
const Name & getAlgorithmName() const
Return the algorithm name.
static const TSIGError & BAD_TIME()
A constant TSIG error object for the BADTIME code (see TSIGError::BAD_TIME_CODE). ...
size_t getLength() const
Return the length of the TSIG record.
void deleteHMAC(HMAC *hmac)
Delete an HMAC object.
~TSIGContext()
The destructor.
void digestPreviousMAC(HMACPtr hmac)
const Name & getKeyName() const
Return the key name.
const rdata::any::TSIG & getRdata() const
Return the RDATA of the TSIG RR.
uint64_t getTimeSigned() const
Return the value of the Time Signed field.
FindResult find(const Name &key_name) const
Find a TSIGKey for the given name in the TSIGKeyRing.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Client successfully verified a response.
An exception that is thrown for logic errors identified in TSIG sign/verify operations.
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order...
boost::shared_ptr< const TSIGRecord > ConstTSIGRecordPtr
A pointer-like type pointing to an immutable TSIGRecord object.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
size_t getTSIGLength() const
Return the expected length of TSIG RR after sign()
void update(const void *const data, size_t len)
Update internal HMAC state by more data.
void digest(const void *data, const size_t data_len, const HashAlgorithm hash_algorithm, isc::util::OutputBuffer &result, size_t len)
Create an Hash digest for the given data.
A simple repository of a set of TSIGKey objects.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
void digestDNSMessage(HMACPtr hmac, uint16_t qid, const void *data, size_t data_len) const
const Name & getAlgorithm() const
Return the algorithm name.
const Name & getName() const
Return the owner name of the TSIG RR, which is the TSIG key name.
size_t getLength() const
Gets the length of the Name in its wire format.
const void * getMAC() const
Return the value of the MAC field.
void digestTSIGVariables(HMACPtr hmac, uint16_t rrclass, uint32_t rrttl, uint64_t time_signed, uint16_t fudge, uint16_t error, uint16_t otherlen, const void *otherdata, bool time_variables_only) const
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order...
TSIGError verify(const TSIGRecord *const record, const void *const data, const size_t data_len)
Verify a DNS message.
TSIGContextImpl(const TSIGKey &key, TSIGError error=TSIGError::NOERROR())
uint16_t getFudge() const
Return the value of the Fudge field.
The specified key is not found in TSIGKeyRing.
uint16_t getOriginalID() const
Return the value of the Original ID field.
uint16_t getCode() const
Returns the TSIGCode error code value.
vector< uint8_t > previous_digest_
bool lastHadSignature() const
Check whether the last verified message was signed.
const void * getOtherData() const
Return the value of the Other Data field.
size_t getLength() const
Return the length of data written in the buffer.
TSIGContext(const TSIGKey &key)
Constructor from a TSIG key.
static const TSIGError & NOERROR()
A constant TSIG error object derived from Rcode::NOERROR()