tsig.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <sys/time.h>
  15. #include <stdint.h>
  16. #include <cassert>
  17. #include <vector>
  18. #include <boost/shared_ptr.hpp>
  19. #include <exceptions/exceptions.h>
  20. #include <util/buffer.h>
  21. #include <util/time_utilities.h>
  22. #include <dns/rdataclass.h>
  23. #include <dns/rrclass.h>
  24. #include <dns/tsig.h>
  25. #include <dns/tsigerror.h>
  26. #include <dns/tsigkey.h>
  27. #include <cryptolink/cryptolink.h>
  28. #include <cryptolink/crypto_hmac.h>
  29. using namespace std;
  30. using namespace isc::util;
  31. using namespace isc::cryptolink;
  32. using namespace isc::dns::rdata;
  33. namespace isc {
  34. namespace dns {
  35. namespace {
  36. typedef boost::shared_ptr<HMAC> HMACPtr;
  37. // TSIG uses 48-bit unsigned integer to represent time signed.
  38. // Since gettimeWrapper() returns a 64-bit *signed* integer, we
  39. // make sure it's stored in an unsigned 64-bit integer variable and
  40. // represents a value in the expected range. (In reality, however,
  41. // gettimeWrapper() will return a positive integer that will fit
  42. // in 48 bits)
  43. uint64_t
  44. getTSIGTime() {
  45. return (detail::gettimeWrapper() & 0x0000ffffffffffffULL);
  46. }
  47. }
  48. struct TSIGContext::TSIGContextImpl {
  49. TSIGContextImpl(const TSIGKey& key,
  50. TSIGError error = TSIGError::NOERROR()) :
  51. state_(INIT), key_(key), error_(error),
  52. previous_timesigned_(0), digest_len_(0),
  53. last_sig_dist_(-1)
  54. {
  55. if (error == TSIGError::NOERROR()) {
  56. // In normal (NOERROR) case, the key should be valid, and we
  57. // should be able to pre-create a corresponding HMAC object,
  58. // which will be likely to be used for sign or verify later.
  59. // We do this in the constructor so that we can know the expected
  60. // digest length in advance. The creation should normally succeed,
  61. // but the key information could be still broken, which could
  62. // trigger an exception inside the cryptolink module. We ignore
  63. // it at this moment; a subsequent sign/verify operation will try
  64. // to create the HMAC, which would also fail.
  65. try {
  66. hmac_.reset(CryptoLink::getCryptoLink().createHMAC(
  67. key_.getSecret(), key_.getSecretLength(),
  68. key_.getAlgorithm()),
  69. deleteHMAC);
  70. } catch (const Exception&) {
  71. return;
  72. }
  73. digest_len_ = hmac_->getOutputLength();
  74. }
  75. }
  76. // This helper method is used from verify(). It's expected to be called
  77. // just before verify() returns. It updates internal state based on
  78. // the verification result and return the TSIGError to be returned to
  79. // the caller of verify(), so that verify() can call this method within
  80. // its 'return' statement.
  81. TSIGError postVerifyUpdate(TSIGError error, const void* digest,
  82. uint16_t digest_len)
  83. {
  84. if (state_ == INIT) {
  85. state_ = RECEIVED_REQUEST;
  86. } else if (state_ == SENT_REQUEST && error == TSIGError::NOERROR()) {
  87. state_ = VERIFIED_RESPONSE;
  88. }
  89. if (digest != NULL) {
  90. previous_digest_.assign(static_cast<const uint8_t*>(digest),
  91. static_cast<const uint8_t*>(digest) +
  92. digest_len);
  93. }
  94. error_ = error;
  95. return (error);
  96. }
  97. // A shortcut method to create an HMAC object for sign/verify. If one
  98. // has been successfully created in the constructor, return it; otherwise
  99. // create a new one and return it. In the former case, the ownership is
  100. // transferred to the caller; the stored HMAC will be reset after the
  101. // call.
  102. HMACPtr createHMAC() {
  103. if (hmac_) {
  104. HMACPtr ret = HMACPtr();
  105. ret.swap(hmac_);
  106. return (ret);
  107. }
  108. return (HMACPtr(CryptoLink::getCryptoLink().createHMAC(
  109. key_.getSecret(), key_.getSecretLength(),
  110. key_.getAlgorithm()),
  111. deleteHMAC));
  112. }
  113. // The following three are helper methods to compute the digest for
  114. // TSIG sign/verify in order to unify the common code logic for sign()
  115. // and verify() and to keep these callers concise.
  116. // These methods take an HMAC object, which will be updated with the
  117. // calculated digest.
  118. // Note: All methods construct a local OutputBuffer as a work space with a
  119. // fixed initial buffer size to avoid intermediate buffer extension.
  120. // This should be efficient enough, especially for fundamentally expensive
  121. // operation like cryptographic sign/verify, but if the creation of the
  122. // buffer in each helper method is still identified to be a severe
  123. // performance bottleneck, we could have this class a buffer as a member
  124. // variable and reuse it throughout the object's lifetime. Right now,
  125. // we prefer keeping the scope for local things as small as possible.
  126. void digestPreviousMAC(HMACPtr hmac);
  127. void digestTSIGVariables(HMACPtr hmac, uint16_t rrclass, uint32_t rrttl,
  128. uint64_t time_signed, uint16_t fudge,
  129. uint16_t error, uint16_t otherlen,
  130. const void* otherdata,
  131. bool time_variables_only) const;
  132. void digestDNSMessage(HMACPtr hmac, uint16_t qid, const void* data,
  133. size_t data_len) const;
  134. State state_;
  135. const TSIGKey key_;
  136. vector<uint8_t> previous_digest_;
  137. TSIGError error_;
  138. uint64_t previous_timesigned_; // only meaningful for response with BADTIME
  139. size_t digest_len_;
  140. HMACPtr hmac_;
  141. // This is the distance from the last verified signed message. Value of 0
  142. // means the last message was signed. Special value -1 means there was no
  143. // signed message yet.
  144. int last_sig_dist_;
  145. };
  146. void
  147. TSIGContext::TSIGContextImpl::digestPreviousMAC(HMACPtr hmac) {
  148. // We should have ensured the digest size fits 16 bits within this class
  149. // implementation.
  150. assert(previous_digest_.size() <= 0xffff);
  151. if (previous_digest_.empty()) {
  152. // The previous digest was already used. We're in the middle of
  153. // TCP stream somewhere and we already pushed some unsigned message
  154. // into the HMAC state.
  155. return;
  156. }
  157. OutputBuffer buffer(sizeof(uint16_t) + previous_digest_.size());
  158. const uint16_t previous_digest_len(previous_digest_.size());
  159. buffer.writeUint16(previous_digest_len);
  160. if (previous_digest_len != 0) {
  161. buffer.writeData(&previous_digest_[0], previous_digest_len);
  162. }
  163. hmac->update(buffer.getData(), buffer.getLength());
  164. }
  165. void
  166. TSIGContext::TSIGContextImpl::digestTSIGVariables(
  167. HMACPtr hmac, uint16_t rrclass, uint32_t rrttl, uint64_t time_signed,
  168. uint16_t fudge, uint16_t error, uint16_t otherlen, const void* otherdata,
  169. bool time_variables_only) const
  170. {
  171. // It's bit complicated, but we can still predict the necessary size of
  172. // the data to be digested. So we precompute it to avoid possible
  173. // reallocation inside OutputBuffer (not absolutely necessary, but this
  174. // is a bit more efficient)
  175. size_t data_size = 8;
  176. if (!time_variables_only) {
  177. data_size += 10 + key_.getKeyName().getLength() +
  178. key_.getAlgorithmName().getLength();
  179. }
  180. OutputBuffer buffer(data_size);
  181. if (!time_variables_only) {
  182. key_.getKeyName().toWire(buffer);
  183. buffer.writeUint16(rrclass);
  184. buffer.writeUint32(rrttl);
  185. key_.getAlgorithmName().toWire(buffer);
  186. }
  187. buffer.writeUint16(time_signed >> 32);
  188. buffer.writeUint32(time_signed & 0xffffffff);
  189. buffer.writeUint16(fudge);
  190. if (!time_variables_only) {
  191. buffer.writeUint16(error);
  192. buffer.writeUint16(otherlen);
  193. }
  194. hmac->update(buffer.getData(), buffer.getLength());
  195. if (!time_variables_only && otherlen > 0) {
  196. hmac->update(otherdata, otherlen);
  197. }
  198. }
  199. // In digestDNSMessage, we exploit some minimum knowledge of DNS message
  200. // format:
  201. // - the header section has a fixed length of 12 octets (MESSAGE_HEADER_LEN)
  202. // - the offset in the header section to the ID field is 0
  203. // - the offset in the header section to the ARCOUNT field is 10 (and the field
  204. // length is 2 octets)
  205. // We could construct a separate Message object from the given data, adjust
  206. // fields via the Message interfaces and then render it back to a separate
  207. // buffer, but that would be overkilling. The DNS message header has a
  208. // fixed length and necessary modifications are quite straightforward, so
  209. // we do the job using lower level interfaces.
  210. namespace {
  211. const size_t MESSAGE_HEADER_LEN = 12;
  212. }
  213. void
  214. TSIGContext::TSIGContextImpl::digestDNSMessage(HMACPtr hmac,
  215. uint16_t qid, const void* data,
  216. size_t data_len) const
  217. {
  218. OutputBuffer buffer(MESSAGE_HEADER_LEN);
  219. const uint8_t* msgptr = static_cast<const uint8_t*>(data);
  220. // Install the original ID
  221. buffer.writeUint16(qid);
  222. msgptr += sizeof(uint16_t);
  223. // Copy the rest of the header except the ARCOUNT field.
  224. buffer.writeData(msgptr, 8);
  225. msgptr += 8;
  226. // Install the adjusted ARCOUNT (we don't care even if the value is bogus
  227. // and it underflows; it would simply result in verification failure)
  228. buffer.writeUint16(InputBuffer(msgptr, sizeof(uint16_t)).readUint16() - 1);
  229. msgptr += 2;
  230. // Digest the header and the rest of the DNS message
  231. hmac->update(buffer.getData(), buffer.getLength());
  232. hmac->update(msgptr, data_len - MESSAGE_HEADER_LEN);
  233. }
  234. TSIGContext::TSIGContext(const TSIGKey& key) : impl_(new TSIGContextImpl(key))
  235. {
  236. }
  237. TSIGContext::TSIGContext(const Name& key_name, const Name& algorithm_name,
  238. const TSIGKeyRing& keyring) : impl_(NULL)
  239. {
  240. const TSIGKeyRing::FindResult result(keyring.find(key_name,
  241. algorithm_name));
  242. if (result.code == TSIGKeyRing::NOTFOUND) {
  243. // If not key is found, create a dummy key with the specified key
  244. // parameters and empty secret. In the common scenario this will
  245. // be used in subsequent response with a TSIG indicating a BADKEY
  246. // error.
  247. impl_ = new TSIGContextImpl(TSIGKey(key_name, algorithm_name,
  248. NULL, 0), TSIGError::BAD_KEY());
  249. } else {
  250. impl_ = new TSIGContextImpl(*result.key);
  251. }
  252. }
  253. TSIGContext::~TSIGContext() {
  254. delete impl_;
  255. }
  256. size_t
  257. TSIGContext::getTSIGLength() const {
  258. //
  259. // The space required for an TSIG record is:
  260. //
  261. // n1 bytes for the (key) name
  262. // 2 bytes for the type
  263. // 2 bytes for the class
  264. // 4 bytes for the ttl
  265. // 2 bytes for the rdlength
  266. // n2 bytes for the algorithm name
  267. // 6 bytes for the time signed
  268. // 2 bytes for the fudge
  269. // 2 bytes for the MAC size
  270. // x bytes for the MAC
  271. // 2 bytes for the original id
  272. // 2 bytes for the error
  273. // 2 bytes for the other data length
  274. // y bytes for the other data (at most)
  275. // ---------------------------------
  276. // 26 + n1 + n2 + x + y bytes
  277. //
  278. // Normally the digest length ("x") is the length of the underlying
  279. // hash output. If a key related error occurred, however, the
  280. // corresponding TSIG will be "unsigned", and the digest length will be 0.
  281. const size_t digest_len =
  282. (impl_->error_ == TSIGError::BAD_KEY() ||
  283. impl_->error_ == TSIGError::BAD_SIG()) ? 0 : impl_->digest_len_;
  284. // Other Len ("y") is normally 0; if BAD_TIME error occurred, the
  285. // subsequent TSIG will contain 48 bits of the server current time.
  286. const size_t other_len = (impl_->error_ == TSIGError::BAD_TIME()) ? 6 : 0;
  287. return (26 + impl_->key_.getKeyName().getLength() +
  288. impl_->key_.getAlgorithmName().getLength() +
  289. digest_len + other_len);
  290. }
  291. TSIGContext::State
  292. TSIGContext::getState() const {
  293. return (impl_->state_);
  294. }
  295. TSIGError
  296. TSIGContext::getError() const {
  297. return (impl_->error_);
  298. }
  299. ConstTSIGRecordPtr
  300. TSIGContext::sign(const uint16_t qid, const void* const data,
  301. const size_t data_len)
  302. {
  303. if (impl_->state_ == VERIFIED_RESPONSE) {
  304. isc_throw(TSIGContextError,
  305. "TSIG sign attempt after verifying a response");
  306. }
  307. if (data == NULL || data_len == 0) {
  308. isc_throw(InvalidParameter, "TSIG sign error: empty data is given");
  309. }
  310. TSIGError error(TSIGError::NOERROR());
  311. const uint64_t now = getTSIGTime();
  312. // For responses adjust the error code.
  313. if (impl_->state_ == RECEIVED_REQUEST) {
  314. error = impl_->error_;
  315. }
  316. // For errors related to key or MAC, return an unsigned response as
  317. // specified in Section 4.3 of RFC2845.
  318. if (error == TSIGError::BAD_SIG() || error == TSIGError::BAD_KEY()) {
  319. ConstTSIGRecordPtr tsig(new TSIGRecord(
  320. impl_->key_.getKeyName(),
  321. any::TSIG(impl_->key_.getAlgorithmName(),
  322. now, DEFAULT_FUDGE, 0, NULL,
  323. qid, error.getCode(), 0, NULL)));
  324. impl_->previous_digest_.clear();
  325. impl_->state_ = SENT_RESPONSE;
  326. return (tsig);
  327. }
  328. HMACPtr hmac(impl_->createHMAC());
  329. // If the context has previous MAC (either the Request MAC or its own
  330. // previous MAC), digest it.
  331. if (impl_->state_ != INIT) {
  332. impl_->digestPreviousMAC(hmac);
  333. }
  334. // Digest the message (without TSIG)
  335. hmac->update(data, data_len);
  336. // Digest TSIG variables.
  337. // First, prepare some non constant variables.
  338. const uint64_t time_signed = (error == TSIGError::BAD_TIME()) ?
  339. impl_->previous_timesigned_ : now;
  340. // For BADTIME error, we include 6 bytes of other data.
  341. // (6 bytes = size of time signed value)
  342. const uint16_t otherlen = (error == TSIGError::BAD_TIME()) ? 6 : 0;
  343. OutputBuffer otherdatabuf(otherlen);
  344. if (error == TSIGError::BAD_TIME()) {
  345. otherdatabuf.writeUint16(now >> 32);
  346. otherdatabuf.writeUint32(now & 0xffffffff);
  347. }
  348. const void* const otherdata =
  349. (otherlen == 0) ? NULL : otherdatabuf.getData();
  350. // Then calculate the digest. If state_ is SENT_RESPONSE we are sending
  351. // a continued message in the same TCP stream so skip digesting
  352. // variables except for time related variables (RFC2845 4.4).
  353. impl_->digestTSIGVariables(hmac, TSIGRecord::getClass().getCode(),
  354. TSIGRecord::TSIG_TTL, time_signed,
  355. DEFAULT_FUDGE, error.getCode(),
  356. otherlen, otherdata,
  357. impl_->state_ == SENT_RESPONSE);
  358. // Get the final digest, update internal state, then finish.
  359. vector<uint8_t> digest = hmac->sign();
  360. assert(digest.size() <= 0xffff); // cryptolink API should have ensured it.
  361. ConstTSIGRecordPtr tsig(new TSIGRecord(
  362. impl_->key_.getKeyName(),
  363. any::TSIG(impl_->key_.getAlgorithmName(),
  364. time_signed, DEFAULT_FUDGE,
  365. digest.size(), &digest[0],
  366. qid, error.getCode(), otherlen,
  367. otherdata)));
  368. // Exception free from now on.
  369. impl_->previous_digest_.swap(digest);
  370. impl_->state_ = (impl_->state_ == INIT) ? SENT_REQUEST : SENT_RESPONSE;
  371. return (tsig);
  372. }
  373. TSIGError
  374. TSIGContext::verify(const TSIGRecord* const record, const void* const data,
  375. const size_t data_len)
  376. {
  377. if (impl_->state_ == SENT_RESPONSE) {
  378. isc_throw(TSIGContextError,
  379. "TSIG verify attempt after sending a response");
  380. }
  381. if (record == NULL) {
  382. if (impl_->last_sig_dist_ >= 0 && impl_->last_sig_dist_ < 99) {
  383. // It is not signed, but in the middle of TCP stream. We just
  384. // update the HMAC state and consider this message OK.
  385. update(data, data_len);
  386. // This one is not signed, the last signed is one message further
  387. // now.
  388. impl_->last_sig_dist_++;
  389. // No digest to return now. Just say it's OK.
  390. return (impl_->postVerifyUpdate(TSIGError::NOERROR(), NULL, 0));
  391. }
  392. // This case happens when we sent a signed request and have received an
  393. // unsigned response. According to RFC2845 Section 4.6 this case should be
  394. // considered a "format error" (although the specific error code
  395. // wouldn't matter much for the caller).
  396. return (impl_->postVerifyUpdate(TSIGError::FORMERR(), NULL, 0));
  397. }
  398. const any::TSIG& tsig_rdata = record->getRdata();
  399. // Reject some obviously invalid data
  400. if (data_len < MESSAGE_HEADER_LEN + record->getLength()) {
  401. isc_throw(InvalidParameter,
  402. "TSIG verify: data length is invalid: " << data_len);
  403. }
  404. if (data == NULL) {
  405. isc_throw(InvalidParameter, "TSIG verify: empty data is invalid");
  406. }
  407. // This message is signed and we won't throw any more.
  408. impl_->last_sig_dist_ = 0;
  409. // Check key: whether we first verify it with a known key or we verify
  410. // it using the consistent key in the context. If the check fails we are
  411. // done with BADKEY.
  412. if (impl_->state_ == INIT && impl_->error_ == TSIGError::BAD_KEY()) {
  413. return (impl_->postVerifyUpdate(TSIGError::BAD_KEY(), NULL, 0));
  414. }
  415. if (impl_->key_.getKeyName() != record->getName() ||
  416. impl_->key_.getAlgorithmName() != tsig_rdata.getAlgorithm()) {
  417. return (impl_->postVerifyUpdate(TSIGError::BAD_KEY(), NULL, 0));
  418. }
  419. // Check time: the current time must be in the range of
  420. // [time signed - fudge, time signed + fudge]. Otherwise verification
  421. // fails with BADTIME. (RFC2845 Section 4.6.2)
  422. // Note: for simplicity we don't explicitly catch the case of too small
  423. // current time causing underflow. With the fact that fudge is quite
  424. // small and (for now) non configurable, it shouldn't be a real concern
  425. // in practice.
  426. const uint64_t now = getTSIGTime();
  427. if (tsig_rdata.getTimeSigned() + DEFAULT_FUDGE < now ||
  428. tsig_rdata.getTimeSigned() - DEFAULT_FUDGE > now) {
  429. const void* digest = NULL;
  430. size_t digest_len = 0;
  431. if (impl_->state_ == INIT) {
  432. digest = tsig_rdata.getMAC();
  433. digest_len = tsig_rdata.getMACSize();
  434. impl_->previous_timesigned_ = tsig_rdata.getTimeSigned();
  435. }
  436. return (impl_->postVerifyUpdate(TSIGError::BAD_TIME(), digest,
  437. digest_len));
  438. }
  439. // TODO: signature length check based on RFC4635
  440. // (Right now we enforce the standard signature length in libcryptolink)
  441. // Handling empty MAC. While RFC2845 doesn't explicitly prohibit other
  442. // cases, it can only reasonably happen in a response with BADSIG or
  443. // BADKEY. We reject other cases as if it were BADSIG to avoid unexpected
  444. // acceptance of a bogus signature. This behavior follows the BIND 9
  445. // implementation.
  446. if (tsig_rdata.getMACSize() == 0) {
  447. TSIGError error = TSIGError(tsig_rdata.getError());
  448. if (error != TSIGError::BAD_SIG() && error != TSIGError::BAD_KEY()) {
  449. error = TSIGError::BAD_SIG();
  450. }
  451. return (impl_->postVerifyUpdate(error, NULL, 0));
  452. }
  453. HMACPtr hmac(impl_->createHMAC());
  454. // If the context has previous MAC (either the Request MAC or its own
  455. // previous MAC), digest it.
  456. if (impl_->state_ != INIT) {
  457. impl_->digestPreviousMAC(hmac);
  458. }
  459. //
  460. // Digest DNS message (excluding the trailing TSIG RR and adjusting the
  461. // QID and ARCOUNT header fields)
  462. //
  463. impl_->digestDNSMessage(hmac, tsig_rdata.getOriginalID(),
  464. data, data_len - record->getLength());
  465. // Digest TSIG variables. If state_ is VERIFIED_RESPONSE, it's a
  466. // continuation of the same TCP stream and skip digesting them except
  467. // for time related variables (RFC2845 4.4).
  468. // Note: we use the constant values for RR class and TTL specified
  469. // in RFC2845, not received values (we reject other values in constructing
  470. // the TSIGRecord).
  471. impl_->digestTSIGVariables(hmac, TSIGRecord::getClass().getCode(),
  472. TSIGRecord::TSIG_TTL,
  473. tsig_rdata.getTimeSigned(),
  474. tsig_rdata.getFudge(), tsig_rdata.getError(),
  475. tsig_rdata.getOtherLen(),
  476. tsig_rdata.getOtherData(),
  477. impl_->state_ == VERIFIED_RESPONSE);
  478. // Verify the digest with the received signature.
  479. if (hmac->verify(tsig_rdata.getMAC(), tsig_rdata.getMACSize())) {
  480. return (impl_->postVerifyUpdate(TSIGError::NOERROR(),
  481. tsig_rdata.getMAC(),
  482. tsig_rdata.getMACSize()));
  483. }
  484. return (impl_->postVerifyUpdate(TSIGError::BAD_SIG(), NULL, 0));
  485. }
  486. bool
  487. TSIGContext::lastHadSignature() const {
  488. if (impl_->last_sig_dist_ == -1) {
  489. isc_throw(TSIGContextError, "No message was verified yet");
  490. }
  491. return (impl_->last_sig_dist_ == 0);
  492. }
  493. void
  494. TSIGContext::update(const void* const data, size_t len) {
  495. HMACPtr hmac(impl_->createHMAC());
  496. // Use the previous digest and never use it again
  497. impl_->digestPreviousMAC(hmac);
  498. impl_->previous_digest_.clear();
  499. // Push the message there
  500. hmac->update(data, len);
  501. impl_->hmac_ = hmac;
  502. }
  503. } // namespace dns
  504. } // namespace isc