Kea 1.9.11
tsig.cc
Go to the documentation of this file.
1// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <sys/time.h>
10
11#include <stdint.h>
12
13#include <cassert>
14#include <vector>
15
16#include <boost/shared_ptr.hpp>
17
19
20#include <util/buffer.h>
21#include <util/time_utilities.h>
22
23#include <dns/rdataclass.h>
24#include <dns/rrclass.h>
25#include <dns/tsig.h>
26#include <dns/tsigerror.h>
27#include <dns/tsigkey.h>
28
31
32using namespace std;
33using namespace isc::util;
34using namespace isc::cryptolink;
35using namespace isc::dns::rdata;
36
37namespace isc {
38namespace dns {
39namespace {
40typedef boost::shared_ptr<HMAC> HMACPtr;
41
42// TSIG uses 48-bit unsigned integer to represent time signed.
43// Since gettimeWrapper() returns a 64-bit *signed* integer, we
44// make sure it's stored in an unsigned 64-bit integer variable and
45// represents a value in the expected range. (In reality, however,
46// gettimeWrapper() will return a positive integer that will fit
47// in 48 bits)
48uint64_t
49getTSIGTime() {
50 return (detail::gettimeWrapper() & 0x0000ffffffffffffULL);
51}
52}
53
57 state_(INIT), key_(key), error_(error),
60 {
61 if (error == TSIGError::NOERROR()) {
62 // In normal (NOERROR) case, the key should be valid, and we
63 // should be able to pre-create a corresponding HMAC object,
64 // which will be likely to be used for sign or verify later.
65 // We do this in the constructor so that we can know the expected
66 // digest length in advance. The creation should normally succeed,
67 // but the key information could be still broken, which could
68 // trigger an exception inside the cryptolink module. We ignore
69 // it at this moment; a subsequent sign/verify operation will try
70 // to create the HMAC, which would also fail.
71 try {
72 hmac_.reset(CryptoLink::getCryptoLink().createHMAC(
76 } catch (const isc::Exception&) {
77 return;
78 }
79 size_t digestbits = key_.getDigestbits();
80 size_t default_digest_len = hmac_->getOutputLength();
81 if (digestbits > 0) {
82 digest_len_ = (digestbits + 7) / 8;
83 // sanity (cf. RFC 4635)
84 if ((digest_len_ < 10) ||
85 (digest_len_ < (default_digest_len / 2)) ||
86 (digest_len_ > default_digest_len)) {
87 // should emit a warning?
88 digest_len_ = default_digest_len;
89 }
90 } else {
91 digest_len_ = default_digest_len;
92 }
93 }
94 }
95
96 // This helper method is used from verify(). It's expected to be called
97 // just before verify() returns. It updates internal state based on
98 // the verification result and return the TSIGError to be returned to
99 // the caller of verify(), so that verify() can call this method within
100 // its 'return' statement.
102 uint16_t digest_len)
103 {
104 if (state_ == INIT) {
106 } else if (state_ == SENT_REQUEST && error == TSIGError::NOERROR()) {
108 }
109 if (digest != NULL) {
110 previous_digest_.assign(static_cast<const uint8_t*>(digest),
111 static_cast<const uint8_t*>(digest) +
112 digest_len);
113 }
114 error_ = error;
115 return (error);
116 }
117
118 // A shortcut method to create an HMAC object for sign/verify. If one
119 // has been successfully created in the constructor, return it; otherwise
120 // create a new one and return it. In the former case, the ownership is
121 // transferred to the caller; the stored HMAC will be reset after the
122 // call.
123 HMACPtr createHMAC() {
124 if (hmac_) {
125 HMACPtr ret = HMACPtr();
126 ret.swap(hmac_);
127 return (ret);
128 }
129 return (HMACPtr(CryptoLink::getCryptoLink().createHMAC(
132 deleteHMAC));
133 }
134
135 // The following three are helper methods to compute the digest for
136 // TSIG sign/verify in order to unify the common code logic for sign()
137 // and verify() and to keep these callers concise.
138 // These methods take an HMAC object, which will be updated with the
139 // calculated digest.
140 // Note: All methods construct a local OutputBuffer as a work space with a
141 // fixed initial buffer size to avoid intermediate buffer extension.
142 // This should be efficient enough, especially for fundamentally expensive
143 // operation like cryptographic sign/verify, but if the creation of the
144 // buffer in each helper method is still identified to be a severe
145 // performance bottleneck, we could have this class a buffer as a member
146 // variable and reuse it throughout the object's lifetime. Right now,
147 // we prefer keeping the scope for local things as small as possible.
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;
158 vector<uint8_t> previous_digest_;
160 uint64_t previous_timesigned_; // only meaningful for response with BADTIME
162 HMACPtr hmac_;
163 // This is the distance from the last verified signed message. Value of 0
164 // means the last message was signed. Special value -1 means there was no
165 // signed message yet.
167};
168
169void
171 // We should have ensured the digest size fits 16 bits within this class
172 // implementation.
173 assert(previous_digest_.size() <= 0xffff);
174
175 if (previous_digest_.empty()) {
176 // The previous digest was already used. We're in the middle of
177 // TCP stream somewhere and we already pushed some unsigned message
178 // into the HMAC state.
179 return;
180 }
181
182 OutputBuffer buffer(sizeof(uint16_t) + previous_digest_.size());
183 const uint16_t previous_digest_len(previous_digest_.size());
184 buffer.writeUint16(previous_digest_len);
185 if (previous_digest_len != 0) {
186 buffer.writeData(&previous_digest_[0], previous_digest_len);
187 }
188 hmac->update(buffer.getData(), buffer.getLength());
189}
190
191void
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
196{
197 // It's bit complicated, but we can still predict the necessary size of
198 // the data to be digested. So we precompute it to avoid possible
199 // reallocation inside OutputBuffer (not absolutely necessary, but this
200 // is a bit more efficient)
201 size_t data_size = 8;
202 if (!time_variables_only) {
203 data_size += 10 + key_.getKeyName().getLength() +
204 key_.getAlgorithmName().getLength();
205 }
206 OutputBuffer buffer(data_size);
207
208 if (!time_variables_only) {
209 key_.getKeyName().toWire(buffer);
210 buffer.writeUint16(rrclass);
211 buffer.writeUint32(rrttl);
212 key_.getAlgorithmName().toWire(buffer);
213 }
214 buffer.writeUint16(time_signed >> 32);
215 buffer.writeUint32(time_signed & 0xffffffff);
216 buffer.writeUint16(fudge);
217
218 if (!time_variables_only) {
219 buffer.writeUint16(error);
220 buffer.writeUint16(otherlen);
221 }
222
223 hmac->update(buffer.getData(), buffer.getLength());
224 if (!time_variables_only && otherlen > 0) {
225 hmac->update(otherdata, otherlen);
226 }
227}
228
229// In digestDNSMessage, we exploit some minimum knowledge of DNS message
230// format:
231// - the header section has a fixed length of 12 octets (MESSAGE_HEADER_LEN)
232// - the offset in the header section to the ID field is 0
233// - the offset in the header section to the ARCOUNT field is 10 (and the field
234// length is 2 octets)
235// We could construct a separate Message object from the given data, adjust
236// fields via the Message interfaces and then render it back to a separate
237// buffer, but that would be overkilling. The DNS message header has a
238// fixed length and necessary modifications are quite straightforward, so
239// we do the job using lower level interfaces.
240namespace {
241const size_t MESSAGE_HEADER_LEN = 12;
242}
243void
245 uint16_t qid, const void* data,
246 size_t data_len) const
247{
248 OutputBuffer buffer(MESSAGE_HEADER_LEN);
249 const uint8_t* msgptr = static_cast<const uint8_t*>(data);
250
251 // Install the original ID
252 buffer.writeUint16(qid);
253 msgptr += sizeof(uint16_t);
254
255 // Copy the rest of the header except the ARCOUNT field.
256 buffer.writeData(msgptr, 8);
257 msgptr += 8;
258
259 // Install the adjusted ARCOUNT (we don't care even if the value is bogus
260 // and it underflows; it would simply result in verification failure)
261 buffer.writeUint16(InputBuffer(msgptr, sizeof(uint16_t)).readUint16() - 1);
262 msgptr += 2;
263
264 // Digest the header and the rest of the DNS message
265 hmac->update(buffer.getData(), buffer.getLength());
266 hmac->update(msgptr, data_len - MESSAGE_HEADER_LEN);
267}
268
270{
271}
272
273TSIGContext::TSIGContext(const Name& key_name, const Name& algorithm_name,
274 const TSIGKeyRing& keyring) : impl_(NULL)
275{
276 const TSIGKeyRing::FindResult result(keyring.find(key_name,
277 algorithm_name));
278 if (result.code == TSIGKeyRing::NOTFOUND) {
279 // If not key is found, create a dummy key with the specified key
280 // parameters and empty secret. In the common scenario this will
281 // be used in subsequent response with a TSIG indicating a BADKEY
282 // error.
283 impl_ = new TSIGContextImpl(TSIGKey(key_name, algorithm_name,
284 NULL, 0), TSIGError::BAD_KEY());
285 } else {
286 impl_ = new TSIGContextImpl(*result.key);
287 }
288}
289
291 delete impl_;
292}
293
294size_t
296 //
297 // The space required for an TSIG record is:
298 //
299 // n1 bytes for the (key) name
300 // 2 bytes for the type
301 // 2 bytes for the class
302 // 4 bytes for the ttl
303 // 2 bytes for the rdlength
304 // n2 bytes for the algorithm name
305 // 6 bytes for the time signed
306 // 2 bytes for the fudge
307 // 2 bytes for the MAC size
308 // x bytes for the MAC
309 // 2 bytes for the original id
310 // 2 bytes for the error
311 // 2 bytes for the other data length
312 // y bytes for the other data (at most)
313 // ---------------------------------
314 // 26 + n1 + n2 + x + y bytes
315 //
316
317 // Normally the digest length ("x") is the length of the underlying
318 // hash output. If a key related error occurred, however, the
319 // corresponding TSIG will be "unsigned", and the digest length will be 0.
320 const size_t digest_len =
321 (impl_->error_ == TSIGError::BAD_KEY() ||
322 impl_->error_ == TSIGError::BAD_SIG()) ? 0 : impl_->digest_len_;
323
324 // Other Len ("y") is normally 0; if BAD_TIME error occurred, the
325 // subsequent TSIG will contain 48 bits of the server current time.
326 const size_t other_len = (impl_->error_ == TSIGError::BAD_TIME()) ? 6 : 0;
327
328 return (26 + impl_->key_.getKeyName().getLength() +
329 impl_->key_.getAlgorithmName().getLength() +
330 digest_len + other_len);
331}
332
335 return (impl_->state_);
336}
337
340 return (impl_->error_);
341}
342
344TSIGContext::sign(const uint16_t qid, const void* const data,
345 const size_t data_len)
346{
347 if (impl_->state_ == VERIFIED_RESPONSE) {
349 "TSIG sign attempt after verifying a response");
350 }
351
352 if (data == NULL || data_len == 0) {
353 isc_throw(InvalidParameter, "TSIG sign error: empty data is given");
354 }
355
357 const uint64_t now = getTSIGTime();
358
359 // For responses adjust the error code.
360 if (impl_->state_ == RECEIVED_REQUEST) {
361 error = impl_->error_;
362 }
363
364 // For errors related to key or MAC, return an unsigned response as
365 // specified in Section 4.3 of RFC2845.
368 impl_->key_.getKeyName(),
370 now, DEFAULT_FUDGE, 0, NULL,
371 qid, error.getCode(), 0, NULL)));
372 impl_->previous_digest_.clear();
373 impl_->state_ = SENT_RESPONSE;
374 return (tsig);
375 }
376
377 HMACPtr hmac(impl_->createHMAC());
378
379 // If the context has previous MAC (either the Request MAC or its own
380 // previous MAC), digest it.
381 if (impl_->state_ != INIT) {
382 impl_->digestPreviousMAC(hmac);
383 }
384
385 // Digest the message (without TSIG)
386 hmac->update(data, data_len);
387
388 // Digest TSIG variables.
389 // First, prepare some non constant variables.
390 const uint64_t time_signed = (error == TSIGError::BAD_TIME()) ?
391 impl_->previous_timesigned_ : now;
392 // For BADTIME error, we include 6 bytes of other data.
393 // (6 bytes = size of time signed value)
394 const uint16_t otherlen = (error == TSIGError::BAD_TIME()) ? 6 : 0;
395 OutputBuffer otherdatabuf(otherlen);
396 if (error == TSIGError::BAD_TIME()) {
397 otherdatabuf.writeUint16(now >> 32);
398 otherdatabuf.writeUint32(now & 0xffffffff);
399 }
400 const void* const otherdata =
401 (otherlen == 0) ? NULL : otherdatabuf.getData();
402 // Then calculate the digest. If state_ is SENT_RESPONSE we are sending
403 // a continued message in the same TCP stream so skip digesting
404 // variables except for time related variables (RFC2845 4.4).
406 TSIGRecord::TSIG_TTL, time_signed,
407 DEFAULT_FUDGE, error.getCode(),
408 otherlen, otherdata,
409 impl_->state_ == SENT_RESPONSE);
410
411 // Get the final digest, update internal state, then finish.
412 vector<uint8_t> digest = hmac->sign(impl_->digest_len_);
413 assert(digest.size() <= 0xffff); // cryptolink API should have ensured it.
415 impl_->key_.getKeyName(),
417 time_signed, DEFAULT_FUDGE,
418 digest.size(), &digest[0],
419 qid, error.getCode(), otherlen,
420 otherdata)));
421 // Exception free from now on.
422 impl_->previous_digest_.swap(digest);
423 impl_->state_ = (impl_->state_ == INIT) ? SENT_REQUEST : SENT_RESPONSE;
424 return (tsig);
425}
426
428TSIGContext::verify(const TSIGRecord* const record, const void* const data,
429 const size_t data_len)
430{
431 if (impl_->state_ == SENT_RESPONSE) {
433 "TSIG verify attempt after sending a response");
434 }
435
436 if (record == NULL) {
437 if (impl_->last_sig_dist_ >= 0 && impl_->last_sig_dist_ < 99) {
438 // It is not signed, but in the middle of TCP stream. We just
439 // update the HMAC state and consider this message OK.
440 update(data, data_len);
441 // This one is not signed, the last signed is one message further
442 // now.
443 impl_->last_sig_dist_++;
444 // No digest to return now. Just say it's OK.
445 return (impl_->postVerifyUpdate(TSIGError::NOERROR(), NULL, 0));
446 }
447 // This case happens when we sent a signed request and have received an
448 // unsigned response. According to RFC2845 Section 4.6 this case should be
449 // considered a "format error" (although the specific error code
450 // wouldn't matter much for the caller).
451 return (impl_->postVerifyUpdate(TSIGError::FORMERR(), NULL, 0));
452 }
453
454 const any::TSIG& tsig_rdata = record->getRdata();
455
456 // Reject some obviously invalid data
457 if (data_len < MESSAGE_HEADER_LEN + record->getLength()) {
459 "TSIG verify: data length is invalid: " << data_len);
460 }
461 if (data == NULL) {
462 isc_throw(InvalidParameter, "TSIG verify: empty data is invalid");
463 }
464
465 // This message is signed and we won't throw any more.
466 impl_->last_sig_dist_ = 0;
467
468 // Check key: whether we first verify it with a known key or we verify
469 // it using the consistent key in the context. If the check fails we are
470 // done with BADKEY.
471 if (impl_->state_ == INIT && impl_->error_ == TSIGError::BAD_KEY()) {
472 return (impl_->postVerifyUpdate(TSIGError::BAD_KEY(), NULL, 0));
473 }
474 if (impl_->key_.getKeyName() != record->getName() ||
475 impl_->key_.getAlgorithmName() != tsig_rdata.getAlgorithm()) {
476 return (impl_->postVerifyUpdate(TSIGError::BAD_KEY(), NULL, 0));
477 }
478
479 // Check time: the current time must be in the range of
480 // [time signed - fudge, time signed + fudge]. Otherwise verification
481 // fails with BADTIME. (RFC2845 Section 4.6.2)
482 // Note: for simplicity we don't explicitly catch the case of too small
483 // current time causing underflow. With the fact that fudge is quite
484 // small and (for now) non configurable, it shouldn't be a real concern
485 // in practice.
486 const uint64_t now = getTSIGTime();
487 if (tsig_rdata.getTimeSigned() + DEFAULT_FUDGE < now ||
488 tsig_rdata.getTimeSigned() - DEFAULT_FUDGE > now) {
489 const void* digest = NULL;
490 size_t digest_len = 0;
491 if (impl_->state_ == INIT) {
492 digest = tsig_rdata.getMAC();
493 digest_len = tsig_rdata.getMACSize();
494 impl_->previous_timesigned_ = tsig_rdata.getTimeSigned();
495 }
497 digest_len));
498 }
499
500 // Handling empty MAC. While RFC2845 doesn't explicitly prohibit other
501 // cases, it can only reasonably happen in a response with BADSIG or
502 // BADKEY. We reject other cases as if it were BADSIG to avoid unexpected
503 // acceptance of a bogus signature. This behavior follows the BIND 9
504 // implementation.
505 if (tsig_rdata.getMACSize() == 0) {
506 TSIGError error = TSIGError(tsig_rdata.getError());
509 }
510 return (impl_->postVerifyUpdate(error, NULL, 0));
511 }
512
513 HMACPtr hmac(impl_->createHMAC());
514
515 // If the context has previous MAC (either the Request MAC or its own
516 // previous MAC), digest it.
517 if (impl_->state_ != INIT) {
518 impl_->digestPreviousMAC(hmac);
519 }
520
521 // Signature length check based on RFC 4635 3.1
522 if (tsig_rdata.getMACSize() > hmac->getOutputLength()) {
523 // signature length too big
524 return (impl_->postVerifyUpdate(TSIGError::FORMERR(), NULL, 0));
525 }
526 if ((tsig_rdata.getMACSize() < 10) ||
527 (tsig_rdata.getMACSize() < (hmac->getOutputLength() / 2))) {
528 // signature length below minimum
529 return (impl_->postVerifyUpdate(TSIGError::FORMERR(), NULL, 0));
530 }
531 if (tsig_rdata.getMACSize() < impl_->digest_len_) {
532 // (truncated) signature length too small
533 return (impl_->postVerifyUpdate(TSIGError::BAD_TRUNC(), NULL, 0));
534 }
535
536 //
537 // Digest DNS message (excluding the trailing TSIG RR and adjusting the
538 // QID and ARCOUNT header fields)
539 //
540 impl_->digestDNSMessage(hmac, tsig_rdata.getOriginalID(),
541 data, data_len - record->getLength());
542
543 // Digest TSIG variables. If state_ is VERIFIED_RESPONSE, it's a
544 // continuation of the same TCP stream and skip digesting them except
545 // for time related variables (RFC2845 4.4).
546 // Note: we use the constant values for RR class and TTL specified
547 // in RFC2845, not received values (we reject other values in constructing
548 // the TSIGRecord).
549 impl_->digestTSIGVariables(hmac, TSIGRecord::getClass().getCode(),
551 tsig_rdata.getTimeSigned(),
552 tsig_rdata.getFudge(), tsig_rdata.getError(),
553 tsig_rdata.getOtherLen(),
554 tsig_rdata.getOtherData(),
555 impl_->state_ == VERIFIED_RESPONSE);
556
557 // Verify the digest with the received signature.
558 if (hmac->verify(tsig_rdata.getMAC(), tsig_rdata.getMACSize())) {
559 return (impl_->postVerifyUpdate(TSIGError::NOERROR(),
560 tsig_rdata.getMAC(),
561 tsig_rdata.getMACSize()));
562 }
563
564 return (impl_->postVerifyUpdate(TSIGError::BAD_SIG(), NULL, 0));
565}
566
567bool
569 if (impl_->last_sig_dist_ == -1) {
570 isc_throw(TSIGContextError, "No message was verified yet");
571 }
572 return (impl_->last_sig_dist_ == 0);
573}
574
575void
576TSIGContext::update(const void* const data, size_t len) {
577 HMACPtr hmac(impl_->createHMAC());
578 // Use the previous digest and never use it again
579 impl_->digestPreviousMAC(hmac);
580 impl_->previous_digest_.clear();
581 // Push the message there
582 hmac->update(data, len);
583 impl_->hmac_ = hmac;
584}
585
586} // namespace dns
587} // namespace isc
This is a base class for exceptions thrown from the DNS library module.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
The Name class encapsulates DNS names.
Definition: name.h:223
size_t getLength() const
Gets the length of the Name in its wire format.
Definition: name.h:360
uint16_t getCode() const
Returns the RR class code as a 16-bit unsigned integer.
Definition: rrclass.h:238
An exception that is thrown for logic errors identified in TSIG sign/verify operations.
Definition: tsig.h:31
State
Internal state of context.
Definition: tsig.h:181
@ RECEIVED_REQUEST
Server received a signed request.
Definition: tsig.h:184
@ SENT_REQUEST
Client sent a signed request, waiting response.
Definition: tsig.h:183
@ SENT_RESPONSE
Server sent a signed response.
Definition: tsig.h:185
@ VERIFIED_RESPONSE
Client successfully verified a response.
Definition: tsig.h:186
@ INIT
Initial state.
Definition: tsig.h:182
virtual ConstTSIGRecordPtr sign(const uint16_t qid, const void *const data, const size_t data_len)
Sign a DNS message.
Definition: tsig.cc:344
static const uint16_t DEFAULT_FUDGE
The recommended fudge value (in seconds) by RFC2845.
Definition: tsig.h:414
virtual TSIGError getError() const
Return the TSIG error as a result of the latest verification.
Definition: tsig.cc:339
virtual size_t getTSIGLength() const
Return the expected length of TSIG RR after sign()
Definition: tsig.cc:295
virtual ~TSIGContext()
The destructor.
Definition: tsig.cc:290
void update(const void *const data, size_t len)
Update internal HMAC state by more data.
Definition: tsig.cc:576
TSIGContext(const TSIGKey &key)
Constructor from a TSIG key.
Definition: tsig.cc:269
virtual TSIGError verify(const TSIGRecord *const record, const void *const data, const size_t data_len)
Verify a DNS message.
Definition: tsig.cc:428
virtual State getState() const
Return the current state of the context.
Definition: tsig.cc:334
virtual bool lastHadSignature() const
Check whether the last verified message was signed.
Definition: tsig.cc:568
TSIG errors.
Definition: tsigerror.h:22
static const TSIGError & BAD_SIG()
A constant TSIG error object for the BADSIG code (see TSIGError::BAD_SIG_CODE).
Definition: tsigerror.h:315
static const TSIGError & BAD_KEY()
A constant TSIG error object for the BADKEY code (see TSIGError::BAD_KEY_CODE).
Definition: tsigerror.h:321
static const TSIGError & BAD_TIME()
A constant TSIG error object for the BADTIME code (see TSIGError::BAD_TIME_CODE).
Definition: tsigerror.h:327
static const TSIGError & NOERROR()
A constant TSIG error object derived from Rcode::NOERROR()
Definition: tsigerror.h:219
static const TSIGError & BAD_TRUNC()
A constant TSIG error object for the BADTRUNC code (see TSIGError::BAD_TRUNC_CODE).
Definition: tsigerror.h:351
static const TSIGError & FORMERR()
A constant TSIG error object derived from Rcode::FORMERR()
Definition: tsigerror.h:225
A simple repository of a set of TSIGKey objects.
Definition: tsigkey.h:246
FindResult find(const Name &key_name) const
Find a TSIGKey for the given name in the TSIGKeyRing.
Definition: tsigkey.cc:344
@ NOTFOUND
The specified key is not found in TSIGKeyRing.
Definition: tsigkey.h:252
TSIG key.
Definition: tsigkey.h:56
const Name & getAlgorithmName() const
Return the algorithm name.
Definition: tsigkey.cc:219
size_t getDigestbits() const
Return the minimum truncated length.
Definition: tsigkey.cc:229
isc::cryptolink::HashAlgorithm getAlgorithm() const
Return the hash algorithm name in the form of cryptolink::HashAlgorithm.
Definition: tsigkey.cc:224
const Name & getKeyName() const
Return the key name.
Definition: tsigkey.cc:214
size_t getSecretLength() const
Return the length of the TSIG secret in bytes.
Definition: tsigkey.cc:239
const void * getSecret() const
Return the value of the TSIG secret.
Definition: tsigkey.cc:234
TSIG resource record.
Definition: tsigrecord.h:54
static const RRClass & getClass()
Return the RR class of TSIG.
Definition: tsigrecord.cc:81
static const uint32_t TSIG_TTL
The TTL value to be used in TSIG RRs.
Definition: tsigrecord.h:267
size_t getLength() const
Return the length of the TSIG record.
Definition: tsigrecord.h:210
const Name & getName() const
Return the owner name of the TSIG RR, which is the TSIG key name.
Definition: tsigrecord.h:171
const rdata::any::TSIG & getRdata() const
Return the RDATA of the TSIG RR.
Definition: tsigrecord.h:176
rdata::TSIG class represents the TSIG RDATA as defined in RFC2845.
Definition: rdataclass.h:63
uint16_t getOriginalID() const
Return the value of the Original ID field.
uint16_t getError() const
Return the value of the Error field.
const Name & getAlgorithm() const
Return the algorithm name.
uint16_t getOtherLen() const
Return the value of the Other Len field.
const void * getOtherData() const
Return the value of the Other Data field.
const void * getMAC() const
Return the value of the MAC field.
uint16_t getFudge() const
Return the value of the Fudge field.
uint16_t getMACSize() const
Return the value of the MAC Size field.
uint64_t getTimeSigned() const
Return the value of the Time Signed field.
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition: buffer.h:81
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
Definition: buffer.h:490
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition: buffer.h:550
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order.
Definition: buffer.h:520
size_t getLength() const
Return the length of data written in the buffer.
Definition: buffer.h:403
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
Definition: buffer.h:401
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
@ error
Definition: db_log.h:118
boost::shared_ptr< const TSIGRecord > ConstTSIGRecordPtr
A pointer-like type pointing to an immutable TSIGRecord object.
Definition: tsigrecord.h:280
int64_t gettimeWrapper()
Return the current time in seconds.
Definition: edns.h:19
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Definition: io_utilities.h:28
Defines the logger used by the top-level component of kea-lfc.
void digestDNSMessage(HMACPtr hmac, uint16_t qid, const void *data, size_t data_len) const
Definition: tsig.cc:244
void digestPreviousMAC(HMACPtr hmac)
Definition: tsig.cc:170
TSIGContextImpl(const TSIGKey &key, TSIGError error=TSIGError::NOERROR())
Definition: tsig.cc:55
TSIGError postVerifyUpdate(TSIGError error, const void *digest, uint16_t digest_len)
Definition: tsig.cc:101
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
Definition: tsig.cc:192
vector< uint8_t > previous_digest_
Definition: tsig.cc:158
A helper structure to represent the search result of TSIGKeyRing::find().
Definition: tsigkey.h:270
const TSIGKey *const key
Definition: tsigkey.h:275