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