1999-08-20 18:56:24 +00:00
|
|
|
/*
|
2018-02-23 09:53:12 +01:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2021-06-03 08:37:05 +02:00
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
|
|
*
|
2016-06-27 14:56:38 +10:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 16:20:40 -07:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
1999-08-20 18:56:24 +00:00
|
|
|
*/
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*! \file */
|
2018-03-28 14:19:37 +02:00
|
|
|
|
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2001-01-16 22:47:56 +00:00
|
|
|
#include <stdlib.h>
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-30 23:14:57 +00:00
|
|
|
#include <isc/buffer.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/mem.h>
|
2001-02-13 03:57:06 +00:00
|
|
|
#include <isc/refcount.h>
|
2021-10-04 17:14:53 +02:00
|
|
|
#include <isc/result.h>
|
2010-07-09 05:13:15 +00:00
|
|
|
#include <isc/serial.h>
|
2022-04-11 15:53:34 +01:00
|
|
|
#include <isc/string.h>
|
2006-12-04 01:54:53 +00:00
|
|
|
#include <isc/time.h>
|
2020-02-12 13:59:18 +01:00
|
|
|
#include <isc/util.h>
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#include <dns/fixedname.h>
|
1999-08-20 18:56:24 +00:00
|
|
|
#include <dns/keyvalues.h>
|
2000-07-20 19:32:57 +00:00
|
|
|
#include <dns/log.h>
|
1999-08-20 18:56:24 +00:00
|
|
|
#include <dns/message.h>
|
2000-07-21 20:53:59 +00:00
|
|
|
#include <dns/rbt.h>
|
1999-08-20 18:56:24 +00:00
|
|
|
#include <dns/rdata.h>
|
|
|
|
#include <dns/rdatalist.h>
|
|
|
|
#include <dns/rdataset.h>
|
2000-05-30 23:14:57 +00:00
|
|
|
#include <dns/rdatastruct.h>
|
1999-08-20 18:56:24 +00:00
|
|
|
#include <dns/tsig.h>
|
|
|
|
|
2020-03-09 16:17:26 +01:00
|
|
|
#include "tsig_p.h"
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G')
|
2020-02-12 13:59:18 +01:00
|
|
|
#define VALID_TSIG_KEY(x) ISC_MAGIC_VALID(x, TSIG_MAGIC)
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2010-07-09 05:13:15 +00:00
|
|
|
#ifndef DNS_TSIG_MAXGENERATEDKEYS
|
|
|
|
#define DNS_TSIG_MAXGENERATEDKEYS 4096
|
2020-02-13 21:48:23 +01:00
|
|
|
#endif /* ifndef DNS_TSIG_MAXGENERATEDKEYS */
|
2010-07-09 05:13:15 +00:00
|
|
|
|
2018-10-11 11:57:57 +02:00
|
|
|
#define is_response(msg) ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
|
2000-08-14 18:13:11 +00:00
|
|
|
|
2000-08-14 22:00:00 +00:00
|
|
|
#define BADTIMELEN 6
|
|
|
|
|
2001-01-11 21:07:21 +00:00
|
|
|
static unsigned char hmacmd5_ndata[] = "\010hmac-md5\007sig-alg\003reg\003int";
|
|
|
|
static unsigned char hmacmd5_offsets[] = { 0, 9, 17, 21, 25 };
|
2000-08-14 22:00:00 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static dns_name_t const hmacmd5 = DNS_NAME_INITABSOLUTE(hmacmd5_ndata,
|
|
|
|
hmacmd5_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5;
|
2001-01-11 21:07:21 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char gsstsig_ndata[] = "\010gss-tsig";
|
|
|
|
static unsigned char gsstsig_offsets[] = { 0, 9 };
|
|
|
|
static dns_name_t const gsstsig = DNS_NAME_INITABSOLUTE(gsstsig_ndata,
|
|
|
|
gsstsig_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_gssapi_name = &gsstsig;
|
2000-08-17 02:08:27 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char hmacsha1_ndata[] = "\011hmac-sha1";
|
|
|
|
static unsigned char hmacsha1_offsets[] = { 0, 10 };
|
|
|
|
static dns_name_t const hmacsha1 = DNS_NAME_INITABSOLUTE(hmacsha1_ndata,
|
|
|
|
hmacsha1_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1;
|
2006-01-27 02:35:15 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char hmacsha224_ndata[] = "\013hmac-sha224";
|
|
|
|
static unsigned char hmacsha224_offsets[] = { 0, 12 };
|
|
|
|
static dns_name_t const hmacsha224 = DNS_NAME_INITABSOLUTE(hmacsha224_ndata,
|
|
|
|
hmacsha224_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224;
|
2006-01-27 02:35:15 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char hmacsha256_ndata[] = "\013hmac-sha256";
|
|
|
|
static unsigned char hmacsha256_offsets[] = { 0, 12 };
|
|
|
|
static dns_name_t const hmacsha256 = DNS_NAME_INITABSOLUTE(hmacsha256_ndata,
|
|
|
|
hmacsha256_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256;
|
2006-01-27 02:35:15 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char hmacsha384_ndata[] = "\013hmac-sha384";
|
|
|
|
static unsigned char hmacsha384_offsets[] = { 0, 12 };
|
|
|
|
static dns_name_t const hmacsha384 = DNS_NAME_INITABSOLUTE(hmacsha384_ndata,
|
|
|
|
hmacsha384_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384;
|
2006-01-27 02:35:15 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char hmacsha512_ndata[] = "\013hmac-sha512";
|
|
|
|
static unsigned char hmacsha512_offsets[] = { 0, 12 };
|
|
|
|
static dns_name_t const hmacsha512 = DNS_NAME_INITABSOLUTE(hmacsha512_ndata,
|
|
|
|
hmacsha512_offsets);
|
2021-06-10 08:06:48 +02:00
|
|
|
const dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512;
|
2006-01-27 02:35:15 +00:00
|
|
|
|
2017-11-13 16:58:12 +11:00
|
|
|
static const struct {
|
2017-09-06 10:57:40 -07:00
|
|
|
const dns_name_t *name;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int dstalg;
|
2020-02-12 13:59:18 +01:00
|
|
|
} known_algs[] = { { &hmacmd5, DST_ALG_HMACMD5 },
|
|
|
|
{ &gsstsig, DST_ALG_GSSAPI },
|
|
|
|
{ &hmacsha1, DST_ALG_HMACSHA1 },
|
|
|
|
{ &hmacsha224, DST_ALG_HMACSHA224 },
|
|
|
|
{ &hmacsha256, DST_ALG_HMACSHA256 },
|
|
|
|
{ &hmacsha384, DST_ALG_HMACSHA384 },
|
|
|
|
{ &hmacsha512, DST_ALG_HMACSHA512 } };
|
2006-01-27 02:35:15 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...)
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_FORMAT_PRINTF(3, 4);
|
2001-08-08 22:54:55 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
cleanup_ring(dns_tsig_keyring_t *ring);
|
|
|
|
static void
|
|
|
|
tsigkey_free(dns_tsigkey_t *key);
|
2006-12-04 01:54:53 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2020-02-13 14:44:37 -08:00
|
|
|
dns__tsig_algvalid(unsigned int alg) {
|
2020-02-12 13:59:18 +01:00
|
|
|
return (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 ||
|
|
|
|
alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 ||
|
|
|
|
alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512);
|
2017-09-06 10:57:40 -07:00
|
|
|
}
|
|
|
|
|
2000-12-07 20:13:29 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
|
2000-12-07 20:13:29 +00:00
|
|
|
va_list ap;
|
2020-02-13 14:44:37 -08:00
|
|
|
char message[4096];
|
|
|
|
char namestr[DNS_NAME_FORMATSIZE];
|
|
|
|
char creatorstr[DNS_NAME_FORMATSIZE];
|
2000-12-07 20:13:29 +00:00
|
|
|
|
2020-03-30 13:49:55 -07:00
|
|
|
if (!isc_log_wouldlog(dns_lctx, level)) {
|
2000-12-07 20:13:29 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-13 00:14:37 -07:00
|
|
|
if (key != NULL) {
|
2000-12-07 20:13:29 +00:00
|
|
|
dns_name_format(&key->name, namestr, sizeof(namestr));
|
2017-09-13 00:14:37 -07:00
|
|
|
} else {
|
|
|
|
strlcpy(namestr, "<null>", sizeof(namestr));
|
|
|
|
}
|
2006-12-04 01:54:53 +00:00
|
|
|
|
2023-02-28 18:29:38 -08:00
|
|
|
if (key != NULL && key->generated && key->creator != NULL) {
|
2006-12-04 01:54:53 +00:00
|
|
|
dns_name_format(key->creator, creatorstr, sizeof(creatorstr));
|
2017-09-13 00:14:37 -07:00
|
|
|
} else {
|
|
|
|
strlcpy(creatorstr, "<null>", sizeof(creatorstr));
|
|
|
|
}
|
2006-12-04 01:54:53 +00:00
|
|
|
|
2000-12-07 20:13:29 +00:00
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(message, sizeof(message), fmt, ap);
|
|
|
|
va_end(ap);
|
2017-09-13 00:14:37 -07:00
|
|
|
if (key != NULL && key->generated) {
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
|
|
|
|
DNS_LOGMODULE_TSIG, level,
|
|
|
|
"tsig key '%s' (%s): %s", namestr, creatorstr,
|
|
|
|
message);
|
2017-09-13 00:14:37 -07:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
|
|
|
|
DNS_LOGMODULE_TSIG, level, "tsig key '%s': %s",
|
|
|
|
namestr, message);
|
2017-09-13 00:14:37 -07:00
|
|
|
}
|
2000-12-07 20:13:29 +00:00
|
|
|
}
|
|
|
|
|
2010-07-09 05:13:15 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
remove_fromring(dns_tsigkey_t *tkey) {
|
2010-07-09 05:13:15 +00:00
|
|
|
if (tkey->generated) {
|
|
|
|
ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
|
|
|
|
tkey->ring->generated--;
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
(void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, false);
|
2010-07-09 05:13:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
adjust_lru(dns_tsigkey_t *tkey) {
|
2010-07-09 05:13:15 +00:00
|
|
|
if (tkey->generated) {
|
|
|
|
RWLOCK(&tkey->ring->lock, isc_rwlocktype_write);
|
|
|
|
/*
|
|
|
|
* We may have been removed from the LRU list between
|
2020-02-20 14:49:36 -08:00
|
|
|
* removing the read lock and acquiring the write lock.
|
2010-07-09 05:13:15 +00:00
|
|
|
*/
|
2020-02-13 14:44:37 -08:00
|
|
|
if (ISC_LINK_LINKED(tkey, link) && tkey->ring->lru.tail != tkey)
|
|
|
|
{
|
2010-07-09 05:13:15 +00:00
|
|
|
ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
|
|
|
|
ISC_LIST_APPEND(tkey->ring->lru, tkey, link);
|
|
|
|
}
|
|
|
|
RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-10 00:27:22 +00:00
|
|
|
/*
|
|
|
|
* A supplemental routine just to add a key to ring. Note that reference
|
|
|
|
* counter should be counted separately because we may be adding the key
|
|
|
|
* as part of creation of the key, in which case the reference counter was
|
|
|
|
* already initialized. Also note we don't need RWLOCK for the reference
|
|
|
|
* counter: it's protected by a separate lock.
|
|
|
|
*/
|
|
|
|
static isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
keyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkey_t *tkey) {
|
2009-06-10 00:27:22 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
|
|
|
RWLOCK(&ring->lock, isc_rwlocktype_write);
|
|
|
|
ring->writecount++;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Do on the fly cleaning. Find some nodes we might not
|
|
|
|
* want around any more.
|
|
|
|
*/
|
|
|
|
if (ring->writecount > 10) {
|
|
|
|
cleanup_ring(ring);
|
|
|
|
ring->writecount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = dns_rbt_addname(ring->keys, name, tkey);
|
2023-05-21 12:59:38 -07:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
if (tkey->generated) {
|
|
|
|
/*
|
|
|
|
* Add the new key to the LRU list and remove the
|
|
|
|
* least recently used key if there are too many
|
|
|
|
* keys on the list.
|
|
|
|
*/
|
|
|
|
ISC_LIST_APPEND(ring->lru, tkey, link);
|
|
|
|
if (ring->generated++ > ring->maxgenerated) {
|
|
|
|
remove_fromring(ISC_LIST_HEAD(ring->lru));
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2023-05-21 12:59:38 -07:00
|
|
|
|
|
|
|
tkey->ring = ring;
|
2010-07-09 05:13:15 +00:00
|
|
|
}
|
2023-05-21 12:59:38 -07:00
|
|
|
|
2009-06-10 00:27:22 +00:00
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
|
2023-02-28 18:29:38 -08:00
|
|
|
dst_key_t *dstkey, bool generated, bool restored,
|
2016-12-30 15:45:08 +11:00
|
|
|
const dns_name_t *creator, isc_stdtime_t inception,
|
2000-08-17 02:08:27 +00:00
|
|
|
isc_stdtime_t expire, isc_mem_t *mctx,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsig_keyring_t *ring, dns_tsigkey_t **key) {
|
2023-02-28 18:29:38 -08:00
|
|
|
dns_tsigkey_t *tkey = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t ret;
|
|
|
|
unsigned int refs = 0;
|
|
|
|
unsigned int dstalg = 0;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
1999-10-27 19:59:34 +00:00
|
|
|
REQUIRE(key == NULL || *key == NULL);
|
1999-08-20 18:56:24 +00:00
|
|
|
REQUIRE(name != NULL);
|
|
|
|
REQUIRE(algorithm != NULL);
|
|
|
|
REQUIRE(mctx != NULL);
|
2005-07-12 01:00:20 +00:00
|
|
|
REQUIRE(key != NULL || ring != NULL);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2019-07-16 15:52:14 +02:00
|
|
|
tkey = isc_mem_get(mctx, sizeof(dns_tsigkey_t));
|
2023-02-28 18:29:38 -08:00
|
|
|
*tkey = (dns_tsigkey_t){
|
|
|
|
.generated = generated,
|
|
|
|
.restored = restored,
|
|
|
|
.ring = ring,
|
|
|
|
.inception = inception,
|
|
|
|
.expire = expire,
|
|
|
|
.name = DNS_NAME_INITEMPTY,
|
|
|
|
.link = ISC_LINK_INITIALIZER,
|
|
|
|
};
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(name, mctx, &tkey->name);
|
2001-11-30 01:59:49 +00:00
|
|
|
(void)dns_name_downcase(&tkey->name, &tkey->name, NULL);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2017-09-06 10:57:40 -07:00
|
|
|
/* Check against known algorithm names */
|
|
|
|
dstalg = dns__tsig_algfromname(algorithm);
|
|
|
|
if (dstalg != 0) {
|
|
|
|
/*
|
|
|
|
* 'algorithm' must be set to a static pointer
|
|
|
|
* so that dns__tsig_algallocated() can compare them.
|
|
|
|
*/
|
|
|
|
tkey->algorithm = dns__tsig_algnamefromname(algorithm);
|
|
|
|
if (dstkey != NULL && dst_key_alg(dstkey) != dstalg) {
|
2001-09-27 17:49:11 +00:00
|
|
|
ret = DNS_R_BADALG;
|
|
|
|
goto cleanup_name;
|
|
|
|
}
|
|
|
|
} else {
|
2023-02-28 18:29:38 -08:00
|
|
|
dns_name_t *tmpname = NULL;
|
2005-03-16 01:47:16 +00:00
|
|
|
if (dstkey != NULL) {
|
2000-11-15 00:52:04 +00:00
|
|
|
ret = DNS_R_BADALG;
|
2000-08-14 18:13:11 +00:00
|
|
|
goto cleanup_name;
|
|
|
|
}
|
2016-12-30 15:45:08 +11:00
|
|
|
tmpname = isc_mem_get(mctx, sizeof(dns_name_t));
|
|
|
|
dns_name_init(tmpname, NULL);
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(algorithm, mctx, tmpname);
|
2016-12-30 15:45:08 +11:00
|
|
|
(void)dns_name_downcase(tmpname, tmpname, NULL);
|
|
|
|
tkey->algorithm = tmpname;
|
2000-08-14 18:13:11 +00:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
1999-11-02 19:55:45 +00:00
|
|
|
if (creator != NULL) {
|
|
|
|
tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t));
|
|
|
|
dns_name_init(tkey->creator, NULL);
|
2019-11-01 08:31:13 -05:00
|
|
|
dns_name_dup(creator, mctx, tkey->creator);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-11-02 19:55:45 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dstkey != NULL) {
|
2010-12-09 00:54:34 +00:00
|
|
|
dst_key_attach(dstkey, &tkey->key);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-07-18 00:46:03 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (key != NULL) {
|
2009-06-10 00:27:22 +00:00
|
|
|
refs = 1;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (ring != NULL) {
|
2005-07-12 01:00:20 +00:00
|
|
|
refs++;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-08-01 11:46:11 +02:00
|
|
|
|
|
|
|
isc_refcount_init(&tkey->refs, refs);
|
2008-01-02 04:24:59 +00:00
|
|
|
isc_mem_attach(mctx, &tkey->mctx);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
tkey->magic = TSIG_MAGIC;
|
2000-01-22 04:45:17 +00:00
|
|
|
|
2005-07-12 01:00:20 +00:00
|
|
|
if (ring != NULL) {
|
2009-06-10 00:27:22 +00:00
|
|
|
ret = keyring_add(ring, name, tkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2005-07-12 01:00:20 +00:00
|
|
|
goto cleanup_refs;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-07-12 01:00:20 +00:00
|
|
|
}
|
|
|
|
|
2006-12-04 01:54:53 +00:00
|
|
|
/*
|
|
|
|
* Ignore this if it's a GSS key, since the key size is meaningless.
|
|
|
|
*/
|
|
|
|
if (dstkey != NULL && dst_key_size(dstkey) < 64 &&
|
2022-11-02 19:33:14 +01:00
|
|
|
dstalg != DST_ALG_GSSAPI)
|
|
|
|
{
|
2000-09-07 20:34:04 +00:00
|
|
|
char namestr[DNS_NAME_FORMATSIZE];
|
|
|
|
dns_name_format(name, namestr, sizeof(namestr));
|
|
|
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
|
|
|
|
DNS_LOGMODULE_TSIG, ISC_LOG_INFO,
|
2001-07-26 20:54:35 +00:00
|
|
|
"the key '%s' is too short to be secure",
|
|
|
|
namestr);
|
2000-09-07 20:34:04 +00:00
|
|
|
}
|
2009-06-10 00:27:22 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (key != NULL) {
|
2000-01-22 04:45:17 +00:00
|
|
|
*key = tkey;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-01-22 04:45:17 +00:00
|
|
|
|
2023-02-28 18:29:38 -08:00
|
|
|
if (tkey->restored) {
|
|
|
|
tsig_log(tkey, ISC_LOG_DEBUG(3), "restored from file");
|
|
|
|
} else if (tkey->generated) {
|
|
|
|
tsig_log(tkey, ISC_LOG_DEBUG(3), "generated");
|
|
|
|
} else {
|
|
|
|
tsig_log(tkey, ISC_LOG_DEBUG(3), "statically configured");
|
|
|
|
}
|
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_refs:
|
2005-07-12 01:00:20 +00:00
|
|
|
tkey->magic = 0;
|
2018-08-17 15:16:59 +02:00
|
|
|
while (refs-- > 0) {
|
2019-12-05 13:29:45 +11:00
|
|
|
isc_refcount_decrement0(&tkey->refs);
|
2018-08-17 15:16:59 +02:00
|
|
|
}
|
2005-07-12 01:00:20 +00:00
|
|
|
isc_refcount_destroy(&tkey->refs);
|
2018-08-01 11:46:11 +02:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tkey->key != NULL) {
|
2010-12-09 00:54:34 +00:00
|
|
|
dst_key_free(&tkey->key);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-07-12 01:00:20 +00:00
|
|
|
if (tkey->creator != NULL) {
|
|
|
|
dns_name_free(tkey->creator, mctx);
|
|
|
|
isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
|
|
|
|
}
|
2017-09-06 10:57:40 -07:00
|
|
|
if (dns__tsig_algallocated(tkey->algorithm)) {
|
2023-03-30 22:34:12 +02:00
|
|
|
dns_name_t *tmpname = UNCONST(tkey->algorithm);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dns_name_dynamic(tmpname)) {
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_free(tmpname, mctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2016-12-30 15:45:08 +11:00
|
|
|
isc_mem_put(mctx, tmpname, sizeof(dns_name_t));
|
2000-08-14 18:13:11 +00:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_name:
|
1999-08-20 18:56:24 +00:00
|
|
|
dns_name_free(&tkey->name, mctx);
|
2000-07-28 00:01:59 +00:00
|
|
|
isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t));
|
1999-08-20 18:56:24 +00:00
|
|
|
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2006-12-04 01:54:53 +00:00
|
|
|
/*
|
|
|
|
* Find a few nodes to destroy if possible.
|
|
|
|
*/
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
cleanup_ring(dns_tsig_keyring_t *ring) {
|
|
|
|
isc_result_t result;
|
2006-12-04 01:54:53 +00:00
|
|
|
dns_rbtnodechain_t chain;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_name_t foundname;
|
|
|
|
dns_fixedname_t fixedorigin;
|
|
|
|
dns_name_t *origin;
|
2023-03-30 21:13:41 +02:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rbtnode_t *node;
|
|
|
|
dns_tsigkey_t *tkey;
|
2006-12-04 01:54:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Start up a new iterator each time.
|
|
|
|
*/
|
|
|
|
dns_name_init(&foundname, NULL);
|
2018-03-28 14:38:09 +02:00
|
|
|
origin = dns_fixedname_initname(&fixedorigin);
|
2006-12-04 01:54:53 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
again:
|
2019-08-27 22:41:18 -07:00
|
|
|
dns_rbtnodechain_init(&chain);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin);
|
2006-12-04 01:54:53 +00:00
|
|
|
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
|
|
|
dns_rbtnodechain_invalidate(&chain);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
node = NULL;
|
|
|
|
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
|
|
|
|
tkey = node->data;
|
|
|
|
if (tkey != NULL) {
|
2020-02-12 13:59:18 +01:00
|
|
|
if (tkey->generated &&
|
|
|
|
isc_refcount_current(&tkey->refs) == 1 &&
|
|
|
|
tkey->inception != tkey->expire &&
|
2020-02-13 14:44:37 -08:00
|
|
|
tkey->expire < now)
|
|
|
|
{
|
2006-12-04 01:54:53 +00:00
|
|
|
tsig_log(tkey, 2, "tsig expire: deleting");
|
|
|
|
/* delete the key */
|
|
|
|
dns_rbtnodechain_invalidate(&chain);
|
2010-07-09 05:13:15 +00:00
|
|
|
remove_fromring(tkey);
|
2006-12-04 01:54:53 +00:00
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_rbtnodechain_next(&chain, &foundname, origin);
|
2006-12-04 01:54:53 +00:00
|
|
|
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
|
|
|
dns_rbtnodechain_invalidate(&chain);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-10 05:32:04 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
destroyring(dns_tsig_keyring_t *ring) {
|
2019-07-23 08:27:30 -04:00
|
|
|
isc_refcount_destroy(&ring->references);
|
2011-01-10 05:32:04 +00:00
|
|
|
dns_rbt_destroy(&ring->keys);
|
|
|
|
isc_rwlock_destroy(&ring->lock);
|
|
|
|
isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t));
|
|
|
|
}
|
|
|
|
|
2017-09-06 10:57:40 -07:00
|
|
|
/*
|
|
|
|
* Look up the DST_ALG_ constant for a given name.
|
|
|
|
*/
|
|
|
|
unsigned int
|
2020-02-13 14:44:37 -08:00
|
|
|
dns__tsig_algfromname(const dns_name_t *algorithm) {
|
2017-09-06 10:57:40 -07:00
|
|
|
int i;
|
|
|
|
int n = sizeof(known_algs) / sizeof(*known_algs);
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
|
const dns_name_t *name = known_algs[i].name;
|
|
|
|
if (algorithm == name || dns_name_equal(algorithm, name)) {
|
|
|
|
return (known_algs[i].dstalg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert an algorithm name into a pointer to the
|
|
|
|
* corresponding pre-defined dns_name_t structure.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
const dns_name_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
dns__tsig_algnamefromname(const dns_name_t *algorithm) {
|
2017-09-06 10:57:40 -07:00
|
|
|
int i;
|
|
|
|
int n = sizeof(known_algs) / sizeof(*known_algs);
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
|
const dns_name_t *name = known_algs[i].name;
|
|
|
|
if (algorithm == name || dns_name_equal(algorithm, name)) {
|
|
|
|
return (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test whether the passed algorithm is NOT a pointer to one of the
|
|
|
|
* pre-defined known algorithms (and therefore one that has been
|
|
|
|
* dynamically allocated).
|
|
|
|
*
|
|
|
|
* This will return an incorrect result if passed a dynamically allocated
|
|
|
|
* dns_name_t that happens to match one of the pre-defined names.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2020-02-13 14:44:37 -08:00
|
|
|
dns__tsig_algallocated(const dns_name_t *algorithm) {
|
2017-09-06 10:57:40 -07:00
|
|
|
int i;
|
|
|
|
int n = sizeof(known_algs) / sizeof(*known_algs);
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
|
const dns_name_t *name = known_algs[i].name;
|
|
|
|
if (algorithm == name) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2017-09-06 10:57:40 -07:00
|
|
|
}
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2011-01-10 05:32:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
|
|
|
|
dst_key_t *dstkey = NULL;
|
|
|
|
char namestr[1024];
|
|
|
|
char creatorstr[1024];
|
|
|
|
char algorithmstr[1024];
|
|
|
|
char keystr[4096];
|
|
|
|
unsigned int inception, expire;
|
|
|
|
int n;
|
|
|
|
isc_buffer_t b;
|
|
|
|
dns_name_t *name, *creator, *algorithm;
|
2011-01-10 05:32:04 +00:00
|
|
|
dns_fixedname_t fname, fcreator, falgorithm;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
unsigned int dstalg;
|
2011-01-10 05:32:04 +00:00
|
|
|
|
|
|
|
n = fscanf(fp, "%1023s %1023s %u %u %1023s %4095s\n", namestr,
|
|
|
|
creatorstr, &inception, &expire, algorithmstr, keystr);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (n == EOF) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (ISC_R_NOMORE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (n != 6) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (ISC_R_FAILURE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isc_serial_lt(expire, now)) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (DNS_R_EXPIRED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
name = dns_fixedname_initname(&fname);
|
2011-01-10 05:32:04 +00:00
|
|
|
isc_buffer_init(&b, namestr, strlen(namestr));
|
|
|
|
isc_buffer_add(&b, strlen(namestr));
|
|
|
|
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
creator = dns_fixedname_initname(&fcreator);
|
2011-01-10 05:32:04 +00:00
|
|
|
isc_buffer_init(&b, creatorstr, strlen(creatorstr));
|
|
|
|
isc_buffer_add(&b, strlen(creatorstr));
|
|
|
|
result = dns_name_fromtext(creator, &b, dns_rootname, 0, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
algorithm = dns_fixedname_initname(&falgorithm);
|
2011-01-10 05:32:04 +00:00
|
|
|
isc_buffer_init(&b, algorithmstr, strlen(algorithmstr));
|
|
|
|
isc_buffer_add(&b, strlen(algorithmstr));
|
|
|
|
result = dns_name_fromtext(algorithm, &b, dns_rootname, 0, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
2017-09-06 10:57:40 -07:00
|
|
|
dstalg = dns__tsig_algfromname(algorithm);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dstalg == 0) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (DNS_R_BADALG);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
|
|
|
result = dst_key_restore(name, dstalg, DNS_KEYOWNER_ENTITY,
|
|
|
|
DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
|
|
|
|
ring->mctx, keystr, &dstkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
2023-02-28 18:29:38 -08:00
|
|
|
result = dns_tsigkey_createfromkey(name, algorithm, dstkey, true, true,
|
2020-02-12 13:59:18 +01:00
|
|
|
creator, inception, expire,
|
|
|
|
ring->mctx, ring, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dstkey != NULL) {
|
2011-01-10 05:32:04 +00:00
|
|
|
dst_key_free(&dstkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
dump_key(dns_tsigkey_t *tkey, FILE *fp) {
|
|
|
|
char *buffer = NULL;
|
|
|
|
int length = 0;
|
|
|
|
char namestr[DNS_NAME_FORMATSIZE];
|
|
|
|
char creatorstr[DNS_NAME_FORMATSIZE];
|
|
|
|
char algorithmstr[DNS_NAME_FORMATSIZE];
|
2011-01-10 05:32:04 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
2013-02-15 10:19:50 -08:00
|
|
|
REQUIRE(tkey != NULL);
|
|
|
|
REQUIRE(fp != NULL);
|
|
|
|
|
2011-01-10 05:32:04 +00:00
|
|
|
dns_name_format(&tkey->name, namestr, sizeof(namestr));
|
|
|
|
dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr));
|
|
|
|
dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr));
|
|
|
|
result = dst_key_dump(tkey->key, tkey->mctx, &buffer, &length);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2011-01-10 05:32:04 +00:00
|
|
|
fprintf(fp, "%s %s %u %u %s %.*s\n", namestr, creatorstr,
|
2020-02-12 13:59:18 +01:00
|
|
|
tkey->inception, tkey->expire, algorithmstr, length,
|
|
|
|
buffer);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (buffer != NULL) {
|
2011-01-10 05:32:04 +00:00
|
|
|
isc_mem_put(tkey->mctx, buffer, length);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) {
|
|
|
|
isc_result_t result;
|
|
|
|
dns_rbtnodechain_t chain;
|
|
|
|
dns_name_t foundname;
|
|
|
|
dns_fixedname_t fixedorigin;
|
|
|
|
dns_name_t *origin;
|
2023-03-30 21:13:41 +02:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rbtnode_t *node;
|
|
|
|
dns_tsigkey_t *tkey;
|
2011-01-10 05:32:04 +00:00
|
|
|
dns_tsig_keyring_t *ring;
|
|
|
|
|
|
|
|
REQUIRE(ringp != NULL && *ringp != NULL);
|
|
|
|
|
|
|
|
ring = *ringp;
|
|
|
|
*ringp = NULL;
|
|
|
|
|
2019-05-20 16:55:42 +02:00
|
|
|
if (isc_refcount_decrement(&ring->references) > 1) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return (DNS_R_CONTINUE);
|
2019-05-20 16:55:42 +02:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
|
|
|
|
dns_name_init(&foundname, NULL);
|
2018-03-28 14:38:09 +02:00
|
|
|
origin = dns_fixedname_initname(&fixedorigin);
|
2019-08-27 22:41:18 -07:00
|
|
|
dns_rbtnodechain_init(&chain);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin);
|
2011-01-10 05:32:04 +00:00
|
|
|
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
|
|
|
dns_rbtnodechain_invalidate(&chain);
|
|
|
|
goto destroy;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
node = NULL;
|
|
|
|
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
|
|
|
|
tkey = node->data;
|
2019-07-23 08:27:30 -04:00
|
|
|
if (tkey != NULL && tkey->generated && tkey->expire >= now) {
|
2011-01-10 05:32:04 +00:00
|
|
|
dump_key(tkey, fp);
|
2019-07-23 08:27:30 -04:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_rbtnodechain_next(&chain, &foundname, origin);
|
2011-01-10 05:32:04 +00:00
|
|
|
if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
|
|
|
|
dns_rbtnodechain_invalidate(&chain);
|
2019-07-23 08:27:30 -04:00
|
|
|
if (result == ISC_R_NOMORE) {
|
2011-01-10 05:32:04 +00:00
|
|
|
result = ISC_R_SUCCESS;
|
2019-07-23 08:27:30 -04:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
goto destroy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
destroy:
|
2011-01-10 05:32:04 +00:00
|
|
|
destroyring(ring);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2019-09-27 09:39:02 +02:00
|
|
|
const dns_name_t *
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkey_identity(const dns_tsigkey_t *tsigkey) {
|
2019-09-27 09:39:02 +02:00
|
|
|
REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
|
|
|
|
|
|
|
|
if (tsigkey == NULL) {
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
if (tsigkey->generated) {
|
|
|
|
return (tsigkey->creator);
|
|
|
|
} else {
|
|
|
|
return (&tsigkey->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-17 02:08:27 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm,
|
2018-04-17 08:29:14 -07:00
|
|
|
unsigned char *secret, int length, bool generated,
|
2023-02-28 18:29:38 -08:00
|
|
|
bool restored, const dns_name_t *creator,
|
|
|
|
isc_stdtime_t inception, isc_stdtime_t expire,
|
|
|
|
isc_mem_t *mctx, dns_tsig_keyring_t *ring,
|
|
|
|
dns_tsigkey_t **key) {
|
2020-02-13 14:44:37 -08:00
|
|
|
dst_key_t *dstkey = NULL;
|
2000-08-17 02:08:27 +00:00
|
|
|
isc_result_t result;
|
2017-09-06 10:57:40 -07:00
|
|
|
unsigned int dstalg = 0;
|
2000-08-17 02:08:27 +00:00
|
|
|
|
|
|
|
REQUIRE(length >= 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (length > 0) {
|
2000-08-17 02:08:27 +00:00
|
|
|
REQUIRE(secret != NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-17 02:08:27 +00:00
|
|
|
|
2017-09-06 10:57:40 -07:00
|
|
|
dstalg = dns__tsig_algfromname(algorithm);
|
|
|
|
if (dns__tsig_algvalid(dstalg)) {
|
2006-01-27 02:35:15 +00:00
|
|
|
if (secret != NULL) {
|
|
|
|
isc_buffer_t b;
|
|
|
|
|
|
|
|
isc_buffer_init(&b, secret, length);
|
|
|
|
isc_buffer_add(&b, length);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dst_key_frombuffer(
|
|
|
|
name, dstalg, DNS_KEYOWNER_ENTITY,
|
|
|
|
DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b,
|
|
|
|
mctx, &dstkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2017-09-06 10:57:40 -07:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2006-01-27 02:35:15 +00:00
|
|
|
}
|
2017-09-06 10:57:40 -07:00
|
|
|
} else if (length > 0) {
|
2000-11-15 00:52:04 +00:00
|
|
|
return (DNS_R_BADALG);
|
2017-09-06 10:57:40 -07:00
|
|
|
}
|
2000-08-17 02:08:27 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_tsigkey_createfromkey(name, algorithm, dstkey, generated,
|
2023-02-28 18:29:38 -08:00
|
|
|
restored, creator, inception, expire,
|
|
|
|
mctx, ring, key);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (dstkey != NULL) {
|
2000-08-17 02:08:27 +00:00
|
|
|
dst_key_free(&dstkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-17 02:08:27 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-05-26 00:16:46 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) {
|
2000-05-26 00:16:46 +00:00
|
|
|
REQUIRE(VALID_TSIG_KEY(source));
|
|
|
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
|
|
|
|
2018-08-17 15:16:59 +02:00
|
|
|
isc_refcount_increment(&source->refs);
|
2000-05-26 00:16:46 +00:00
|
|
|
*targetp = source;
|
|
|
|
}
|
|
|
|
|
1999-11-16 03:02:36 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
tsigkey_free(dns_tsigkey_t *key) {
|
2000-05-26 00:16:46 +00:00
|
|
|
REQUIRE(VALID_TSIG_KEY(key));
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-26 00:16:46 +00:00
|
|
|
key->magic = 0;
|
|
|
|
dns_name_free(&key->name, key->mctx);
|
2017-09-06 10:57:40 -07:00
|
|
|
if (dns__tsig_algallocated(key->algorithm)) {
|
2023-03-30 22:34:12 +02:00
|
|
|
dns_name_t *name = UNCONST(key->algorithm);
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_name_free(name, key->mctx);
|
|
|
|
isc_mem_put(key->mctx, name, sizeof(dns_name_t));
|
2000-08-14 18:13:11 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (key->key != NULL) {
|
2000-05-26 00:16:46 +00:00
|
|
|
dst_key_free(&key->key);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-26 00:16:46 +00:00
|
|
|
if (key->creator != NULL) {
|
|
|
|
dns_name_free(key->creator, key->mctx);
|
|
|
|
isc_mem_put(key->mctx, key->creator, sizeof(dns_name_t));
|
1999-11-02 19:55:45 +00:00
|
|
|
}
|
2008-01-02 04:24:59 +00:00
|
|
|
isc_mem_putanddetach(&key->mctx, key, sizeof(dns_tsigkey_t));
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
|
1999-11-16 03:02:36 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkey_detach(dns_tsigkey_t **keyp) {
|
2018-08-28 10:18:59 +02:00
|
|
|
REQUIRE(keyp != NULL && VALID_TSIG_KEY(*keyp));
|
|
|
|
dns_tsigkey_t *key = *keyp;
|
|
|
|
*keyp = NULL;
|
1999-11-16 03:02:36 +00:00
|
|
|
|
2018-08-17 15:16:59 +02:00
|
|
|
if (isc_refcount_decrement(&key->refs) == 1) {
|
2018-08-28 10:18:59 +02:00
|
|
|
isc_refcount_destroy(&key->refs);
|
2000-07-21 20:53:59 +00:00
|
|
|
tsigkey_free(key);
|
2018-08-17 15:16:59 +02:00
|
|
|
}
|
1999-11-16 03:02:36 +00:00
|
|
|
}
|
|
|
|
|
1999-10-08 20:14:47 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkey_setdeleted(dns_tsigkey_t *key) {
|
2000-07-21 20:53:59 +00:00
|
|
|
REQUIRE(VALID_TSIG_KEY(key));
|
|
|
|
REQUIRE(key->ring != NULL);
|
|
|
|
|
|
|
|
RWLOCK(&key->ring->lock, isc_rwlocktype_write);
|
2010-07-09 05:13:15 +00:00
|
|
|
remove_fromring(key);
|
2000-07-21 20:53:59 +00:00
|
|
|
RWUNLOCK(&key->ring->lock, isc_rwlocktype_write);
|
1999-10-08 20:14:47 +00:00
|
|
|
}
|
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsig_sign(dns_message_t *msg) {
|
|
|
|
dns_tsigkey_t *key = NULL;
|
2000-05-30 23:14:57 +00:00
|
|
|
dns_rdata_any_tsig_t tsig, querytsig;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned char data[128];
|
|
|
|
isc_buffer_t databuf, sigbuf;
|
|
|
|
isc_buffer_t *dynbuf = NULL;
|
2021-05-19 17:18:22 -07:00
|
|
|
dns_name_t *owner = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdata_t *rdata = NULL;
|
|
|
|
dns_rdatalist_t *datalist = NULL;
|
|
|
|
dns_rdataset_t *dataset = NULL;
|
|
|
|
isc_region_t r;
|
|
|
|
isc_stdtime_t now;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
dst_context_t *ctx = NULL;
|
|
|
|
isc_result_t ret;
|
|
|
|
unsigned char badtimedata[BADTIMELEN];
|
|
|
|
unsigned int sigsize = 0;
|
|
|
|
bool response;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
|
|
|
REQUIRE(msg != NULL);
|
2016-10-11 14:40:29 +11:00
|
|
|
key = dns_message_gettsigkey(msg);
|
|
|
|
REQUIRE(VALID_TSIG_KEY(key));
|
1999-09-10 15:42:57 +00:00
|
|
|
|
2019-01-30 11:12:49 +01:00
|
|
|
/*
|
|
|
|
* If this is a response, there should be a TSIG in the query with the
|
|
|
|
* the exception if this is a TKEY request (see RFC 3645, Section 2.2).
|
|
|
|
*/
|
2016-10-11 14:40:29 +11:00
|
|
|
response = is_response(msg);
|
2019-01-30 11:12:49 +01:00
|
|
|
if (response && msg->querytsig == NULL) {
|
|
|
|
if (msg->tkey != 1) {
|
|
|
|
return (DNS_R_EXPECTEDTSIG);
|
|
|
|
}
|
|
|
|
}
|
1999-09-10 02:42:12 +00:00
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
mctx = msg->mctx;
|
|
|
|
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.mctx = mctx;
|
|
|
|
tsig.common.rdclass = dns_rdataclass_any;
|
|
|
|
tsig.common.rdtype = dns_rdatatype_tsig;
|
|
|
|
ISC_LINK_INIT(&tsig.common, link);
|
|
|
|
dns_name_init(&tsig.algorithm, NULL);
|
2000-08-14 18:13:11 +00:00
|
|
|
dns_name_clone(key->algorithm, &tsig.algorithm);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2022-03-02 11:48:26 +01:00
|
|
|
if (msg->fuzzing) {
|
|
|
|
now = msg->fuzztime;
|
|
|
|
} else {
|
2023-03-30 21:13:41 +02:00
|
|
|
now = isc_stdtime_now();
|
2022-03-02 11:48:26 +01:00
|
|
|
}
|
|
|
|
|
2001-01-09 23:35:33 +00:00
|
|
|
tsig.timesigned = now + msg->timeadjust;
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.fudge = DNS_TSIG_FUDGE;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.originalid = msg->id;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&databuf, data, sizeof(data));
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (response) {
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.error = msg->querytsigstatus;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.error = dns_rcode_noerror;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-22 23:17:22 +00:00
|
|
|
if (tsig.error != dns_tsigerror_badtime) {
|
|
|
|
tsig.otherlen = 0;
|
|
|
|
tsig.other = NULL;
|
2000-08-14 22:00:00 +00:00
|
|
|
} else {
|
1999-08-20 18:56:24 +00:00
|
|
|
isc_buffer_t otherbuf;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-08-14 22:00:00 +00:00
|
|
|
tsig.otherlen = BADTIMELEN;
|
|
|
|
tsig.other = badtimedata;
|
|
|
|
isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen);
|
2006-12-04 01:54:53 +00:00
|
|
|
isc_buffer_putuint48(&otherbuf, tsig.timesigned);
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
2000-08-14 22:00:00 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
if ((key->key != NULL) && (tsig.error != dns_tsigerror_badsig) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
(tsig.error != dns_tsigerror_badkey))
|
|
|
|
{
|
1999-08-20 18:56:24 +00:00
|
|
|
unsigned char header[DNS_MESSAGE_HEADERLEN];
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_buffer_t headerbuf;
|
|
|
|
uint16_t digestbits;
|
|
|
|
bool querytsig_ok = false;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2017-06-28 09:11:49 -07:00
|
|
|
/*
|
|
|
|
* If it is a response, we assume that the request MAC
|
|
|
|
* has validated at this point. This is why we include a
|
|
|
|
* MAC length > 0 in the reply.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
ret = dst_context_create(key->key, mctx, DNS_LOGCATEGORY_DNSSEC,
|
2018-04-17 08:29:14 -07:00
|
|
|
true, 0, &ctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-08-14 22:00:00 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-12-17 21:09:34 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
2019-01-29 11:51:48 -08:00
|
|
|
* If this is a response, and if there was a TSIG in
|
|
|
|
* the query, digest the request's MAC.
|
|
|
|
*
|
|
|
|
* (Note: querytsig should be non-NULL for all
|
|
|
|
* responses except TKEY responses. Those may be signed
|
|
|
|
* with the newly-negotiated TSIG key even if the query
|
|
|
|
* wasn't signed.)
|
2000-05-08 14:38:29 +00:00
|
|
|
*/
|
2019-01-29 11:51:48 -08:00
|
|
|
if (response && msg->querytsig != NULL) {
|
2000-10-25 04:26:57 +00:00
|
|
|
dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
|
2000-05-30 23:14:57 +00:00
|
|
|
|
2017-08-07 18:54:05 -07:00
|
|
|
INSIST(msg->verified_sig);
|
|
|
|
|
2000-05-31 23:58:35 +00:00
|
|
|
ret = dns_rdataset_first(msg->querytsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-31 23:58:35 +00:00
|
|
|
dns_rdataset_current(msg->querytsig, &querytsigrdata);
|
2000-05-30 23:14:57 +00:00
|
|
|
ret = dns_rdata_tostruct(&querytsigrdata, &querytsig,
|
|
|
|
NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_putuint16(&databuf, querytsig.siglen);
|
|
|
|
if (isc_buffer_availablelength(&databuf) <
|
2022-11-02 19:33:14 +01:00
|
|
|
querytsig.siglen)
|
|
|
|
{
|
2000-05-30 23:14:57 +00:00
|
|
|
ret = ISC_R_NOSPACE;
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2000-05-30 23:14:57 +00:00
|
|
|
}
|
|
|
|
isc_buffer_putmem(&databuf, querytsig.signature,
|
|
|
|
querytsig.siglen);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2019-02-13 17:21:16 +11:00
|
|
|
querytsig_ok = true;
|
1999-12-17 21:09:34 +00:00
|
|
|
}
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the header.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&headerbuf, header, sizeof(header));
|
1999-08-20 18:56:24 +00:00
|
|
|
dns_message_renderheader(msg, &headerbuf);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&headerbuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the remainder of the message.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(msg->buffer, &r);
|
1999-08-20 18:56:24 +00:00
|
|
|
isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
1999-09-10 14:56:36 +00:00
|
|
|
if (msg->tcp_continuation == 0) {
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the name, class, ttl, alg.
|
|
|
|
*/
|
1999-09-10 14:56:36 +00:00
|
|
|
dns_name_toregion(&key->name, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
1999-09-10 14:56:36 +00:00
|
|
|
isc_buffer_clear(&databuf);
|
|
|
|
isc_buffer_putuint16(&databuf, dns_rdataclass_any);
|
|
|
|
isc_buffer_putuint32(&databuf, 0); /* ttl */
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-22 23:17:22 +00:00
|
|
|
dns_name_toregion(&tsig.algorithm, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
|
|
|
/* Digest the timesigned and fudge */
|
1999-08-20 18:56:24 +00:00
|
|
|
isc_buffer_clear(&databuf);
|
2019-02-13 17:21:16 +11:00
|
|
|
if (tsig.error == dns_tsigerror_badtime && querytsig_ok) {
|
2001-01-09 14:32:44 +00:00
|
|
|
tsig.timesigned = querytsig.timesigned;
|
2011-08-29 04:02:54 +00:00
|
|
|
}
|
2006-12-04 01:54:53 +00:00
|
|
|
isc_buffer_putuint48(&databuf, tsig.timesigned);
|
2000-05-22 23:17:22 +00:00
|
|
|
isc_buffer_putuint16(&databuf, tsig.fudge);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
1999-09-10 14:56:36 +00:00
|
|
|
if (msg->tcp_continuation == 0) {
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the error and other data length.
|
|
|
|
*/
|
1999-09-10 14:56:36 +00:00
|
|
|
isc_buffer_clear(&databuf);
|
2000-05-22 23:17:22 +00:00
|
|
|
isc_buffer_putuint16(&databuf, tsig.error);
|
|
|
|
isc_buffer_putuint16(&databuf, tsig.otherlen);
|
1999-09-10 14:56:36 +00:00
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
2011-11-02 19:41:02 +00:00
|
|
|
* Digest other data.
|
2000-05-08 14:38:29 +00:00
|
|
|
*/
|
2000-05-22 23:17:22 +00:00
|
|
|
if (tsig.otherlen > 0) {
|
|
|
|
r.length = tsig.otherlen;
|
|
|
|
r.base = tsig.other;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
|
2000-05-17 22:48:10 +00:00
|
|
|
ret = dst_key_sigsize(key->key, &sigsize);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2019-07-16 15:52:14 +02:00
|
|
|
tsig.signature = isc_mem_get(mctx, sigsize);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-08-17 02:08:27 +00:00
|
|
|
isc_buffer_init(&sigbuf, tsig.signature, sigsize);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_sign(ctx, &sigbuf);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
1999-08-20 18:56:24 +00:00
|
|
|
goto cleanup_signature;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-02 18:59:33 +00:00
|
|
|
dst_context_destroy(&ctx);
|
2006-01-27 02:35:15 +00:00
|
|
|
digestbits = dst_key_getbits(key->key);
|
|
|
|
if (digestbits != 0) {
|
2019-02-13 17:21:16 +11:00
|
|
|
unsigned int bytes = (digestbits + 7) / 8;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (querytsig_ok && bytes < querytsig.siglen) {
|
2006-01-27 02:35:15 +00:00
|
|
|
bytes = querytsig.siglen;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (bytes > isc_buffer_usedlength(&sigbuf)) {
|
2006-01-27 02:35:15 +00:00
|
|
|
bytes = isc_buffer_usedlength(&sigbuf);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2006-01-27 02:35:15 +00:00
|
|
|
tsig.siglen = bytes;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2006-01-27 02:35:15 +00:00
|
|
|
tsig.siglen = isc_buffer_usedlength(&sigbuf);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-14 22:00:00 +00:00
|
|
|
} else {
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.siglen = 0;
|
|
|
|
tsig.signature = NULL;
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
|
2022-05-16 13:28:13 +02:00
|
|
|
dns_message_gettemprdata(msg, &rdata);
|
2020-02-02 08:35:46 +01:00
|
|
|
isc_buffer_allocate(msg->mctx, &dynbuf, 512);
|
1999-09-10 02:42:12 +00:00
|
|
|
ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any,
|
2000-05-22 23:17:22 +00:00
|
|
|
dns_rdatatype_tsig, &tsig, dynbuf);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
1999-10-08 16:39:17 +00:00
|
|
|
goto cleanup_dynbuf;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-30 23:14:57 +00:00
|
|
|
dns_message_takebuffer(msg, &dynbuf);
|
|
|
|
|
2000-05-22 23:17:22 +00:00
|
|
|
if (tsig.signature != NULL) {
|
2000-08-17 02:08:27 +00:00
|
|
|
isc_mem_put(mctx, tsig.signature, sigsize);
|
2000-05-22 23:17:22 +00:00
|
|
|
tsig.signature = NULL;
|
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2022-05-16 13:28:13 +02:00
|
|
|
dns_message_gettempname(msg, &owner);
|
2021-05-21 17:20:44 -07:00
|
|
|
dns_name_copy(&key->name, owner);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2022-05-16 13:28:13 +02:00
|
|
|
dns_message_gettemprdatalist(msg, &datalist);
|
2021-05-19 17:18:22 -07:00
|
|
|
|
2022-05-16 13:28:13 +02:00
|
|
|
dns_message_gettemprdataset(msg, &dataset);
|
1999-08-20 18:56:24 +00:00
|
|
|
datalist->rdclass = dns_rdataclass_any;
|
|
|
|
datalist->type = dns_rdatatype_tsig;
|
|
|
|
ISC_LIST_APPEND(datalist->rdata, rdata, link);
|
2022-07-29 12:40:45 +00:00
|
|
|
dns_rdatalist_tordataset(datalist, dataset);
|
2000-05-31 23:58:35 +00:00
|
|
|
msg->tsig = dataset;
|
2000-03-29 01:32:22 +00:00
|
|
|
msg->tsigname = owner;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2010-03-12 03:34:56 +00:00
|
|
|
/* Windows does not like the tsig name being compressed. */
|
2022-10-13 10:33:41 +02:00
|
|
|
msg->tsigname->attributes.nocompress = true;
|
2010-03-12 03:34:56 +00:00
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_dynbuf:
|
2005-11-30 03:33:49 +00:00
|
|
|
isc_buffer_free(&dynbuf);
|
2006-03-08 03:51:01 +00:00
|
|
|
dns_message_puttemprdata(msg, &rdata);
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_signature:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tsig.signature != NULL) {
|
2000-09-21 21:29:16 +00:00
|
|
|
isc_mem_put(mctx, tsig.signature, sigsize);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_context:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ctx != NULL) {
|
2006-03-08 03:51:01 +00:00
|
|
|
dst_context_destroy(&ctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2000-01-21 20:18:41 +00:00
|
|
|
dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2) {
|
2000-05-30 23:14:57 +00:00
|
|
|
dns_rdata_any_tsig_t tsig, querytsig;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_region_t r, source_r, header_r, sig_r;
|
|
|
|
isc_buffer_t databuf;
|
|
|
|
unsigned char data[32];
|
|
|
|
dns_name_t *keyname;
|
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
|
|
|
isc_stdtime_t now;
|
|
|
|
isc_result_t ret;
|
|
|
|
dns_tsigkey_t *tsigkey;
|
|
|
|
dst_key_t *key = NULL;
|
|
|
|
unsigned char header[DNS_MESSAGE_HEADERLEN];
|
|
|
|
dst_context_t *ctx = NULL;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
uint16_t addcount, id;
|
|
|
|
unsigned int siglen;
|
|
|
|
unsigned int alg;
|
|
|
|
bool response;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
|
|
|
REQUIRE(source != NULL);
|
2000-01-21 21:50:45 +00:00
|
|
|
REQUIRE(DNS_MESSAGE_VALID(msg));
|
2000-05-26 00:16:46 +00:00
|
|
|
tsigkey = dns_message_gettsigkey(msg);
|
2011-08-25 06:20:07 +00:00
|
|
|
response = is_response(msg);
|
2006-12-04 01:54:53 +00:00
|
|
|
|
2000-05-26 00:16:46 +00:00
|
|
|
REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
|
1999-09-10 15:42:57 +00:00
|
|
|
|
2000-03-13 19:27:35 +00:00
|
|
|
msg->verify_attempted = 1;
|
2017-06-27 11:35:52 -07:00
|
|
|
msg->verified_sig = 0;
|
|
|
|
msg->tsigstatus = dns_tsigerror_badsig;
|
2000-03-13 19:27:35 +00:00
|
|
|
|
2006-05-02 04:07:36 +00:00
|
|
|
if (msg->tcp_continuation) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tsigkey == NULL || msg->querytsig == NULL) {
|
2006-05-02 04:07:36 +00:00
|
|
|
return (DNS_R_UNEXPECTEDTSIG);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-23 00:48:28 +00:00
|
|
|
return (tsig_verify_tcp(source, msg));
|
2006-05-02 04:07:36 +00:00
|
|
|
}
|
2000-01-21 20:18:41 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* There should be a TSIG record...
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (msg->tsig == NULL) {
|
1999-09-10 15:42:57 +00:00
|
|
|
return (DNS_R_EXPECTEDTSIG);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 15:42:57 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If this is a response and there's no key or query TSIG, there
|
|
|
|
* shouldn't be one on the response.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (response && (tsigkey == NULL || msg->querytsig == NULL)) {
|
1999-09-10 15:42:57 +00:00
|
|
|
return (DNS_R_UNEXPECTEDTSIG);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
|
|
|
mctx = msg->mctx;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we're here, we know the message is well formed and contains a
|
|
|
|
* TSIG record.
|
|
|
|
*/
|
|
|
|
|
2000-03-29 01:32:22 +00:00
|
|
|
keyname = msg->tsigname;
|
2000-05-31 23:58:35 +00:00
|
|
|
ret = dns_rdataset_first(msg->tsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
1999-08-20 18:56:24 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-31 23:58:35 +00:00
|
|
|
dns_rdataset_current(msg->tsig, &rdata);
|
2000-05-30 23:14:57 +00:00
|
|
|
ret = dns_rdata_tostruct(&rdata, &tsig, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-05-30 23:14:57 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-10-31 03:22:05 +00:00
|
|
|
dns_rdata_reset(&rdata);
|
2011-08-25 06:20:07 +00:00
|
|
|
if (response) {
|
2000-05-31 23:58:35 +00:00
|
|
|
ret = dns_rdataset_first(msg->querytsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-05-30 23:14:57 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-31 23:58:35 +00:00
|
|
|
dns_rdataset_current(msg->querytsig, &rdata);
|
2000-05-30 23:14:57 +00:00
|
|
|
ret = dns_rdata_tostruct(&rdata, &querytsig, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-05-30 23:14:57 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-30 23:14:57 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Do the key name and algorithm match that of the query?
|
|
|
|
*/
|
2011-08-25 06:20:07 +00:00
|
|
|
if (response &&
|
2000-05-26 00:16:46 +00:00
|
|
|
(!dns_name_equal(keyname, &tsigkey->name) ||
|
2020-02-13 14:44:37 -08:00
|
|
|
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm)))
|
|
|
|
{
|
1999-08-20 18:56:24 +00:00
|
|
|
msg->tsigstatus = dns_tsigerror_badkey;
|
2000-12-07 20:13:29 +00:00
|
|
|
tsig_log(msg->tsigkey, 2,
|
|
|
|
"key name and algorithm do not match");
|
1999-08-20 18:56:24 +00:00
|
|
|
return (DNS_R_TSIGVERIFYFAILURE);
|
|
|
|
}
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Get the current time.
|
|
|
|
*/
|
2022-03-02 11:48:26 +01:00
|
|
|
if (msg->fuzzing) {
|
|
|
|
now = msg->fuzztime;
|
|
|
|
} else {
|
2023-03-30 21:13:41 +02:00
|
|
|
now = isc_stdtime_now();
|
2022-03-02 11:48:26 +01:00
|
|
|
}
|
2000-01-24 22:22:51 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Find dns_tsigkey_t based on keyname.
|
|
|
|
*/
|
2000-05-26 00:16:46 +00:00
|
|
|
if (tsigkey == NULL) {
|
2000-01-21 20:18:41 +00:00
|
|
|
ret = ISC_R_NOTFOUND;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ring1 != NULL) {
|
2000-01-21 20:18:41 +00:00
|
|
|
ret = dns_tsigkey_find(&tsigkey, keyname,
|
2000-08-01 01:33:37 +00:00
|
|
|
&tsig.algorithm, ring1);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (ret == ISC_R_NOTFOUND && ring2 != NULL) {
|
2000-01-21 20:18:41 +00:00
|
|
|
ret = dns_tsigkey_find(&tsigkey, keyname,
|
2000-07-21 22:38:31 +00:00
|
|
|
&tsig.algorithm, ring2);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-11-03 16:52:28 +00:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
|
|
|
msg->tsigstatus = dns_tsigerror_badkey;
|
2023-02-28 18:29:38 -08:00
|
|
|
ret = dns_tsigkey_create(
|
|
|
|
keyname, &tsig.algorithm, NULL, 0, false, false,
|
|
|
|
NULL, now, now, mctx, NULL, &msg->tsigkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-05-30 23:14:57 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-12-07 20:13:29 +00:00
|
|
|
tsig_log(msg->tsigkey, 2, "unknown key");
|
1999-11-03 16:52:28 +00:00
|
|
|
return (DNS_R_TSIGVERIFYFAILURE);
|
|
|
|
}
|
2000-05-27 00:24:07 +00:00
|
|
|
msg->tsigkey = tsigkey;
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
key = tsigkey->key;
|
|
|
|
|
2006-01-27 02:35:15 +00:00
|
|
|
/*
|
|
|
|
* Check digest length.
|
|
|
|
*/
|
|
|
|
alg = dst_key_alg(key);
|
|
|
|
ret = dst_key_sigsize(key, &siglen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2006-01-27 02:35:15 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-06 10:57:40 -07:00
|
|
|
if (dns__tsig_algvalid(alg)) {
|
2006-01-27 02:35:15 +00:00
|
|
|
if (tsig.siglen > siglen) {
|
2014-09-15 18:18:12 -07:00
|
|
|
tsig_log(msg->tsigkey, 2, "signature length too big");
|
2006-01-27 02:35:15 +00:00
|
|
|
return (DNS_R_FORMERR);
|
|
|
|
}
|
|
|
|
if (tsig.siglen > 0 &&
|
2022-11-02 19:33:14 +01:00
|
|
|
(tsig.siglen < 10 || tsig.siglen < ((siglen + 1) / 2)))
|
|
|
|
{
|
2006-01-27 02:35:15 +00:00
|
|
|
tsig_log(msg->tsigkey, 2,
|
|
|
|
"signature length below minimum");
|
|
|
|
return (DNS_R_FORMERR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-05-30 23:14:57 +00:00
|
|
|
if (tsig.siglen > 0) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t addcount_n;
|
2015-03-09 09:23:46 +05:30
|
|
|
|
2000-05-30 23:14:57 +00:00
|
|
|
sig_r.base = tsig.signature;
|
|
|
|
sig_r.length = tsig.siglen;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
ret = dst_context_create(key, mctx, DNS_LOGCATEGORY_DNSSEC,
|
2018-04-17 08:29:14 -07:00
|
|
|
false, 0, &ctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-08-14 22:00:00 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2017-06-28 09:11:49 -07:00
|
|
|
if (response) {
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&databuf, data, sizeof(data));
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_putuint16(&databuf, querytsig.siglen);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-30 23:14:57 +00:00
|
|
|
if (querytsig.siglen > 0) {
|
|
|
|
r.length = querytsig.siglen;
|
|
|
|
r.base = querytsig.signature;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Extract the header.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(source, &r);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(header, r.base, DNS_MESSAGE_HEADERLEN);
|
1999-09-10 14:56:36 +00:00
|
|
|
isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Decrement the additional field counter.
|
|
|
|
*/
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
|
2015-03-09 09:23:46 +05:30
|
|
|
addcount_n = ntohs(addcount);
|
2018-03-28 14:19:37 +02:00
|
|
|
addcount = htons((uint16_t)(addcount_n - 1));
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Put in the original id.
|
|
|
|
*/
|
2000-05-30 23:14:57 +00:00
|
|
|
id = htons(tsig.originalid);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&header[0], &id, 2);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the modified header.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
header_r.base = (unsigned char *)header;
|
1999-08-20 18:56:24 +00:00
|
|
|
header_r.length = DNS_MESSAGE_HEADERLEN;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &header_r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest all non-TSIG records.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(source, &source_r);
|
1999-08-20 18:56:24 +00:00
|
|
|
r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
|
1999-11-02 19:55:45 +00:00
|
|
|
r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the key name.
|
|
|
|
*/
|
1999-08-20 18:56:24 +00:00
|
|
|
dns_name_toregion(&tsigkey->name, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&databuf, data, sizeof(data));
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_putuint16(&databuf, tsig.common.rdclass);
|
2000-05-31 23:58:35 +00:00
|
|
|
isc_buffer_putuint32(&databuf, msg->tsig->ttl);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the key algorithm.
|
|
|
|
*/
|
2000-08-14 18:13:11 +00:00
|
|
|
dns_name_toregion(tsigkey->algorithm, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
|
|
|
isc_buffer_clear(&databuf);
|
2006-12-04 01:54:53 +00:00
|
|
|
isc_buffer_putuint48(&databuf, tsig.timesigned);
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_putuint16(&databuf, tsig.fudge);
|
|
|
|
isc_buffer_putuint16(&databuf, tsig.error);
|
|
|
|
isc_buffer_putuint16(&databuf, tsig.otherlen);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-05-30 23:14:57 +00:00
|
|
|
if (tsig.otherlen > 0) {
|
|
|
|
r.base = tsig.other;
|
|
|
|
r.length = tsig.otherlen;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(ctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_verify(ctx, &sig_r);
|
|
|
|
if (ret == DST_R_VERIFYFAILURE) {
|
2000-06-06 23:44:13 +00:00
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
2000-12-07 20:13:29 +00:00
|
|
|
tsig_log(msg->tsigkey, 2,
|
2006-12-04 01:54:53 +00:00
|
|
|
"signature failed to verify(1)");
|
2000-06-06 23:44:13 +00:00
|
|
|
goto cleanup_context;
|
2017-06-27 11:35:52 -07:00
|
|
|
} else if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2017-06-27 11:35:52 -07:00
|
|
|
}
|
2017-08-07 18:54:05 -07:00
|
|
|
msg->verified_sig = 1;
|
2020-03-25 17:46:26 +11:00
|
|
|
} else if (!response || (tsig.error != dns_tsigerror_badsig &&
|
|
|
|
tsig.error != dns_tsigerror_badkey))
|
2020-02-13 14:44:37 -08:00
|
|
|
{
|
2000-12-07 20:13:29 +00:00
|
|
|
tsig_log(msg->tsigkey, 2, "signature was empty");
|
1999-08-20 18:56:24 +00:00
|
|
|
return (DNS_R_TSIGVERIFYFAILURE);
|
|
|
|
}
|
|
|
|
|
2017-06-28 09:11:49 -07:00
|
|
|
/*
|
|
|
|
* Here at this point, the MAC has been verified. Even if any of
|
|
|
|
* the following code returns a TSIG error, the reply will be
|
|
|
|
* signed and WILL always include the request MAC in the digest
|
|
|
|
* computation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Is the time ok?
|
|
|
|
*/
|
|
|
|
if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) {
|
|
|
|
msg->tsigstatus = dns_tsigerror_badtime;
|
|
|
|
tsig_log(msg->tsigkey, 2, "signature has expired");
|
|
|
|
ret = DNS_R_CLOCKSKEW;
|
|
|
|
goto cleanup_context;
|
|
|
|
} else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge) {
|
|
|
|
msg->tsigstatus = dns_tsigerror_badtime;
|
|
|
|
tsig_log(msg->tsigkey, 2, "signature is in the future");
|
|
|
|
ret = DNS_R_CLOCKSKEW;
|
|
|
|
goto cleanup_context;
|
|
|
|
}
|
|
|
|
|
2017-09-06 10:57:40 -07:00
|
|
|
if (dns__tsig_algvalid(alg)) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t digestbits = dst_key_getbits(key);
|
2017-06-28 09:11:49 -07:00
|
|
|
|
|
|
|
if (tsig.siglen > 0 && digestbits != 0 &&
|
2022-11-02 19:33:14 +01:00
|
|
|
tsig.siglen < ((digestbits + 7) / 8))
|
|
|
|
{
|
2017-06-28 09:11:49 -07:00
|
|
|
msg->tsigstatus = dns_tsigerror_badtrunc;
|
|
|
|
tsig_log(msg->tsigkey, 2,
|
|
|
|
"truncated signature length too small");
|
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
|
|
|
goto cleanup_context;
|
|
|
|
}
|
2020-02-13 14:44:37 -08:00
|
|
|
if (tsig.siglen > 0 && digestbits == 0 && tsig.siglen < siglen)
|
|
|
|
{
|
2017-06-28 09:11:49 -07:00
|
|
|
msg->tsigstatus = dns_tsigerror_badtrunc;
|
|
|
|
tsig_log(msg->tsigkey, 2, "signature length too small");
|
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
|
|
|
goto cleanup_context;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-25 17:46:26 +11:00
|
|
|
if (response && tsig.error != dns_rcode_noerror) {
|
2017-06-27 11:35:52 -07:00
|
|
|
msg->tsigstatus = tsig.error;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tsig.error == dns_tsigerror_badtime) {
|
2017-06-27 11:35:52 -07:00
|
|
|
ret = DNS_R_CLOCKSKEW;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2017-06-27 11:35:52 -07:00
|
|
|
ret = DNS_R_TSIGERRORSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-06-27 11:35:52 -07:00
|
|
|
goto cleanup_context;
|
2001-03-07 20:53:32 +00:00
|
|
|
}
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2017-06-27 11:35:52 -07:00
|
|
|
msg->tsigstatus = dns_rcode_noerror;
|
|
|
|
ret = ISC_R_SUCCESS;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_context:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ctx != NULL) {
|
2000-06-02 18:59:33 +00:00
|
|
|
dst_context_destroy(&ctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-30 23:14:57 +00:00
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2000-01-21 20:18:41 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
2000-05-30 23:14:57 +00:00
|
|
|
dns_rdata_any_tsig_t tsig, querytsig;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_region_t r, source_r, header_r, sig_r;
|
|
|
|
isc_buffer_t databuf;
|
|
|
|
unsigned char data[32];
|
|
|
|
dns_name_t *keyname;
|
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
|
|
|
isc_stdtime_t now;
|
|
|
|
isc_result_t ret;
|
|
|
|
dns_tsigkey_t *tsigkey;
|
|
|
|
dst_key_t *key = NULL;
|
|
|
|
unsigned char header[DNS_MESSAGE_HEADERLEN];
|
|
|
|
uint16_t addcount, id;
|
|
|
|
bool has_tsig = false;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
unsigned int siglen;
|
|
|
|
unsigned int alg;
|
1999-09-10 14:56:36 +00:00
|
|
|
|
|
|
|
REQUIRE(source != NULL);
|
|
|
|
REQUIRE(msg != NULL);
|
2000-05-26 00:16:46 +00:00
|
|
|
REQUIRE(dns_message_gettsigkey(msg) != NULL);
|
1999-09-10 14:56:36 +00:00
|
|
|
REQUIRE(msg->tcp_continuation == 1);
|
2000-05-31 23:58:35 +00:00
|
|
|
REQUIRE(msg->querytsig != NULL);
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2017-06-27 11:35:52 -07:00
|
|
|
msg->verified_sig = 0;
|
|
|
|
msg->tsigstatus = dns_tsigerror_badsig;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (!is_response(msg)) {
|
2002-03-14 18:34:48 +00:00
|
|
|
return (DNS_R_EXPECTEDRESPONSE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-03-14 18:34:48 +00:00
|
|
|
|
2000-06-02 18:59:33 +00:00
|
|
|
mctx = msg->mctx;
|
|
|
|
|
2000-05-26 00:16:46 +00:00
|
|
|
tsigkey = dns_message_gettsigkey(msg);
|
2017-06-28 09:11:49 -07:00
|
|
|
key = tsigkey->key;
|
2000-05-26 00:16:46 +00:00
|
|
|
|
2000-06-23 00:48:28 +00:00
|
|
|
/*
|
|
|
|
* Extract and parse the previous TSIG
|
|
|
|
*/
|
|
|
|
ret = dns_rdataset_first(msg->querytsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-23 00:48:28 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-23 00:48:28 +00:00
|
|
|
dns_rdataset_current(msg->querytsig, &rdata);
|
|
|
|
ret = dns_rdata_tostruct(&rdata, &querytsig, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-23 00:48:28 +00:00
|
|
|
return (ret);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-10-31 03:22:05 +00:00
|
|
|
dns_rdata_reset(&rdata);
|
2000-06-23 00:48:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If there is a TSIG in this message, do some checks.
|
|
|
|
*/
|
2000-05-31 23:58:35 +00:00
|
|
|
if (msg->tsig != NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
has_tsig = true;
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-03-29 01:32:22 +00:00
|
|
|
keyname = msg->tsigname;
|
2000-05-31 23:58:35 +00:00
|
|
|
ret = dns_rdataset_first(msg->tsig);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-23 00:48:28 +00:00
|
|
|
goto cleanup_querystruct;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-05-31 23:58:35 +00:00
|
|
|
dns_rdataset_current(msg->tsig, &rdata);
|
2000-05-30 23:14:57 +00:00
|
|
|
ret = dns_rdata_tostruct(&rdata, &tsig, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-23 00:48:28 +00:00
|
|
|
goto cleanup_querystruct;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Do the key name and algorithm match that of the query?
|
|
|
|
*/
|
2000-05-26 00:16:46 +00:00
|
|
|
if (!dns_name_equal(keyname, &tsigkey->name) ||
|
2020-02-13 14:44:37 -08:00
|
|
|
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm))
|
|
|
|
{
|
1999-09-10 14:56:36 +00:00
|
|
|
msg->tsigstatus = dns_tsigerror_badkey;
|
2000-06-23 00:48:28 +00:00
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
2000-12-07 20:13:29 +00:00
|
|
|
tsig_log(msg->tsigkey, 2,
|
|
|
|
"key name and algorithm do not match");
|
2000-06-23 00:48:28 +00:00
|
|
|
goto cleanup_querystruct;
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
2017-06-28 09:11:49 -07:00
|
|
|
* Check digest length.
|
2000-05-08 14:38:29 +00:00
|
|
|
*/
|
2017-06-28 09:11:49 -07:00
|
|
|
alg = dst_key_alg(key);
|
|
|
|
ret = dst_key_sigsize(key, &siglen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2001-01-16 22:47:56 +00:00
|
|
|
goto cleanup_querystruct;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-06 10:57:40 -07:00
|
|
|
if (dns__tsig_algvalid(alg)) {
|
2017-06-28 09:11:49 -07:00
|
|
|
if (tsig.siglen > siglen) {
|
|
|
|
tsig_log(tsigkey, 2,
|
|
|
|
"signature length too big");
|
|
|
|
ret = DNS_R_FORMERR;
|
|
|
|
goto cleanup_querystruct;
|
|
|
|
}
|
|
|
|
if (tsig.siglen > 0 &&
|
|
|
|
(tsig.siglen < 10 ||
|
2022-11-02 19:33:14 +01:00
|
|
|
tsig.siglen < ((siglen + 1) / 2)))
|
|
|
|
{
|
2017-06-28 09:11:49 -07:00
|
|
|
tsig_log(tsigkey, 2,
|
|
|
|
"signature length below minimum");
|
|
|
|
ret = DNS_R_FORMERR;
|
|
|
|
goto cleanup_querystruct;
|
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (msg->tsigctx == NULL) {
|
2020-02-12 13:59:18 +01:00
|
|
|
ret = dst_context_create(key, mctx, DNS_LOGCATEGORY_DNSSEC,
|
2018-04-17 08:29:14 -07:00
|
|
|
false, 0, &msg->tsigctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-23 00:48:28 +00:00
|
|
|
goto cleanup_querystruct;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-06-23 00:48:28 +00:00
|
|
|
/*
|
|
|
|
* Digest the length of the query signature
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&databuf, data, sizeof(data));
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_putuint16(&databuf, querytsig.siglen);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(msg->tsigctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-23 00:48:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Digest the data of the query signature
|
|
|
|
*/
|
2000-05-30 23:14:57 +00:00
|
|
|
if (querytsig.siglen > 0) {
|
|
|
|
r.length = querytsig.siglen;
|
|
|
|
r.base = querytsig.signature;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(msg->tsigctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Extract the header.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(source, &r);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(header, r.base, DNS_MESSAGE_HEADERLEN);
|
1999-09-10 14:56:36 +00:00
|
|
|
isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Decrement the additional field counter if necessary.
|
|
|
|
*/
|
1999-09-10 14:56:36 +00:00
|
|
|
if (has_tsig) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t addcount_n;
|
2015-03-09 09:23:46 +05:30
|
|
|
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
|
2015-03-09 09:23:46 +05:30
|
|
|
addcount_n = ntohs(addcount);
|
2018-03-28 14:19:37 +02:00
|
|
|
addcount = htons((uint16_t)(addcount_n - 1));
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2017-09-13 09:50:51 +10:00
|
|
|
/*
|
|
|
|
* Put in the original id.
|
|
|
|
*
|
|
|
|
* XXX Can TCP transfers be forwarded? How would that
|
|
|
|
* work?
|
|
|
|
*/
|
2000-05-30 23:14:57 +00:00
|
|
|
id = htons(tsig.originalid);
|
2014-01-08 16:27:10 -08:00
|
|
|
memmove(&header[0], &id, 2);
|
2000-04-08 04:40:21 +00:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the modified header.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
header_r.base = (unsigned char *)header;
|
1999-09-10 14:56:36 +00:00
|
|
|
header_r.length = DNS_MESSAGE_HEADERLEN;
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(msg->tsigctx, &header_r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest all non-TSIG records.
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(source, &source_r);
|
1999-09-10 14:56:36 +00:00
|
|
|
r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (has_tsig) {
|
1999-11-02 19:55:45 +00:00
|
|
|
r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
1999-09-10 14:56:36 +00:00
|
|
|
r.length = source_r.length - DNS_MESSAGE_HEADERLEN;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(msg->tsigctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Digest the time signed and fudge.
|
|
|
|
*/
|
1999-09-10 14:56:36 +00:00
|
|
|
if (has_tsig) {
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&databuf, data, sizeof(data));
|
2006-12-04 01:54:53 +00:00
|
|
|
isc_buffer_putuint48(&databuf, tsig.timesigned);
|
2000-05-30 23:14:57 +00:00
|
|
|
isc_buffer_putuint16(&databuf, tsig.fudge);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_usedregion(&databuf, &r);
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_adddata(msg->tsigctx, &r);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-05-30 23:14:57 +00:00
|
|
|
sig_r.base = tsig.signature;
|
|
|
|
sig_r.length = tsig.siglen;
|
|
|
|
if (tsig.siglen == 0) {
|
2001-03-07 20:53:32 +00:00
|
|
|
if (tsig.error != dns_rcode_noerror) {
|
2017-06-27 11:35:52 -07:00
|
|
|
msg->tsigstatus = tsig.error;
|
|
|
|
if (tsig.error == dns_tsigerror_badtime) {
|
2001-03-07 20:53:32 +00:00
|
|
|
ret = DNS_R_CLOCKSKEW;
|
2017-06-27 11:35:52 -07:00
|
|
|
} else {
|
2001-03-07 20:53:32 +00:00
|
|
|
ret = DNS_R_TSIGERRORSET;
|
2017-06-27 11:35:52 -07:00
|
|
|
}
|
2001-03-07 20:53:32 +00:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
tsig_log(msg->tsigkey, 2, "signature is empty");
|
2000-03-16 23:13:25 +00:00
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
2000-12-07 20:13:29 +00:00
|
|
|
}
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2000-03-16 23:13:25 +00:00
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = dst_context_verify(msg->tsigctx, &sig_r);
|
|
|
|
if (ret == DST_R_VERIFYFAILURE) {
|
2000-12-07 20:13:29 +00:00
|
|
|
tsig_log(msg->tsigkey, 2,
|
2006-12-04 01:54:53 +00:00
|
|
|
"signature failed to verify(2)");
|
2000-06-02 18:59:33 +00:00
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
|
|
|
goto cleanup_context;
|
2017-06-27 11:35:52 -07:00
|
|
|
} else if (ret != ISC_R_SUCCESS) {
|
2000-06-02 18:59:33 +00:00
|
|
|
goto cleanup_context;
|
2017-06-27 11:35:52 -07:00
|
|
|
}
|
2017-08-07 18:54:05 -07:00
|
|
|
msg->verified_sig = 1;
|
1999-09-10 14:56:36 +00:00
|
|
|
|
2017-06-28 09:11:49 -07:00
|
|
|
/*
|
|
|
|
* Here at this point, the MAC has been verified. Even
|
|
|
|
* if any of the following code returns a TSIG error,
|
|
|
|
* the reply will be signed and WILL always include the
|
|
|
|
* request MAC in the digest computation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Is the time ok?
|
|
|
|
*/
|
2022-03-02 11:48:26 +01:00
|
|
|
if (msg->fuzzing) {
|
|
|
|
now = msg->fuzztime;
|
|
|
|
} else {
|
2023-03-30 21:13:41 +02:00
|
|
|
now = isc_stdtime_now();
|
2022-03-02 11:48:26 +01:00
|
|
|
}
|
2017-06-28 09:11:49 -07:00
|
|
|
|
|
|
|
if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) {
|
|
|
|
msg->tsigstatus = dns_tsigerror_badtime;
|
|
|
|
tsig_log(msg->tsigkey, 2, "signature has expired");
|
|
|
|
ret = DNS_R_CLOCKSKEW;
|
|
|
|
goto cleanup_context;
|
2020-02-13 14:44:37 -08:00
|
|
|
} else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge)
|
|
|
|
{
|
2017-06-28 09:11:49 -07:00
|
|
|
msg->tsigstatus = dns_tsigerror_badtime;
|
2020-02-12 13:59:18 +01:00
|
|
|
tsig_log(msg->tsigkey, 2, "signature is in the future");
|
2017-06-28 09:11:49 -07:00
|
|
|
ret = DNS_R_CLOCKSKEW;
|
|
|
|
goto cleanup_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
alg = dst_key_alg(key);
|
|
|
|
ret = dst_key_sigsize(key, &siglen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ret != ISC_R_SUCCESS) {
|
2017-06-28 09:11:49 -07:00
|
|
|
goto cleanup_context;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-09-06 10:57:40 -07:00
|
|
|
if (dns__tsig_algvalid(alg)) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t digestbits = dst_key_getbits(key);
|
2017-06-28 09:11:49 -07:00
|
|
|
|
|
|
|
if (tsig.siglen > 0 && digestbits != 0 &&
|
2022-11-02 19:33:14 +01:00
|
|
|
tsig.siglen < ((digestbits + 7) / 8))
|
|
|
|
{
|
2017-06-28 09:11:49 -07:00
|
|
|
msg->tsigstatus = dns_tsigerror_badtrunc;
|
|
|
|
tsig_log(msg->tsigkey, 2,
|
|
|
|
"truncated signature length "
|
|
|
|
"too small");
|
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
|
|
|
goto cleanup_context;
|
|
|
|
}
|
|
|
|
if (tsig.siglen > 0 && digestbits == 0 &&
|
2022-11-02 19:33:14 +01:00
|
|
|
tsig.siglen < siglen)
|
|
|
|
{
|
2017-06-28 09:11:49 -07:00
|
|
|
msg->tsigstatus = dns_tsigerror_badtrunc;
|
|
|
|
tsig_log(msg->tsigkey, 2,
|
|
|
|
"signature length too small");
|
|
|
|
ret = DNS_R_TSIGVERIFYFAILURE;
|
|
|
|
goto cleanup_context;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-27 11:35:52 -07:00
|
|
|
if (tsig.error != dns_rcode_noerror) {
|
|
|
|
msg->tsigstatus = tsig.error;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tsig.error == dns_tsigerror_badtime) {
|
2017-06-27 11:35:52 -07:00
|
|
|
ret = DNS_R_CLOCKSKEW;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2017-06-27 11:35:52 -07:00
|
|
|
ret = DNS_R_TSIGERRORSET;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-06-27 11:35:52 -07:00
|
|
|
goto cleanup_context;
|
|
|
|
}
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
msg->tsigstatus = dns_rcode_noerror;
|
2017-06-27 11:35:52 -07:00
|
|
|
ret = ISC_R_SUCCESS;
|
2000-06-02 18:59:33 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_context:
|
2017-07-07 23:19:05 +10:00
|
|
|
/*
|
|
|
|
* Except in error conditions, don't destroy the DST context
|
|
|
|
* for unsigned messages; it is a running sum till the next
|
|
|
|
* TSIG signed message.
|
|
|
|
*/
|
|
|
|
if ((ret != ISC_R_SUCCESS || has_tsig) && msg->tsigctx != NULL) {
|
2017-06-27 11:35:52 -07:00
|
|
|
dst_context_destroy(&msg->tsigctx);
|
2017-07-07 23:19:05 +10:00
|
|
|
}
|
2000-06-23 00:48:28 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_querystruct:
|
2000-06-23 00:48:28 +00:00
|
|
|
dns_rdata_freestruct(&querytsig);
|
|
|
|
|
2000-06-02 18:59:33 +00:00
|
|
|
return (ret);
|
1999-09-10 14:56:36 +00:00
|
|
|
}
|
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
|
2020-02-13 14:44:37 -08:00
|
|
|
const dns_name_t *algorithm, dns_tsig_keyring_t *ring) {
|
1999-10-08 18:37:24 +00:00
|
|
|
dns_tsigkey_t *key;
|
2023-03-30 21:13:41 +02:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
1999-08-20 18:56:24 +00:00
|
|
|
|
|
|
|
REQUIRE(tsigkey != NULL);
|
1999-10-08 20:14:47 +00:00
|
|
|
REQUIRE(*tsigkey == NULL);
|
1999-08-20 18:56:24 +00:00
|
|
|
REQUIRE(name != NULL);
|
2000-01-21 20:18:41 +00:00
|
|
|
REQUIRE(ring != NULL);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2006-12-04 01:54:53 +00:00
|
|
|
RWLOCK(&ring->lock, isc_rwlocktype_write);
|
|
|
|
cleanup_ring(ring);
|
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
|
|
|
|
|
2000-07-18 00:46:03 +00:00
|
|
|
RWLOCK(&ring->lock, isc_rwlocktype_read);
|
2000-07-21 20:53:59 +00:00
|
|
|
key = NULL;
|
|
|
|
result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
|
|
|
|
if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
|
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
|
|
|
return (ISC_R_NOTFOUND);
|
|
|
|
}
|
2000-08-14 18:13:11 +00:00
|
|
|
if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
|
2000-07-21 20:53:59 +00:00
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
|
|
|
return (ISC_R_NOTFOUND);
|
|
|
|
}
|
2010-07-09 05:13:15 +00:00
|
|
|
if (key->inception != key->expire && isc_serial_lt(key->expire, now)) {
|
2000-07-21 20:53:59 +00:00
|
|
|
/*
|
|
|
|
* The key has expired.
|
|
|
|
*/
|
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
|
|
|
RWLOCK(&ring->lock, isc_rwlocktype_write);
|
2010-07-09 05:13:15 +00:00
|
|
|
remove_fromring(key);
|
2000-07-21 20:53:59 +00:00
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
|
|
|
|
return (ISC_R_NOTFOUND);
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
2010-07-09 05:13:15 +00:00
|
|
|
#if 0
|
|
|
|
/*
|
|
|
|
* MPAXXX We really should look at the inception time.
|
|
|
|
*/
|
|
|
|
if (key->inception != key->expire &&
|
|
|
|
isc_serial_lt(key->inception, now)) {
|
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
|
|
|
adjust_lru(key);
|
|
|
|
return (ISC_R_NOTFOUND);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
#endif /* if 0 */
|
2018-08-17 15:16:59 +02:00
|
|
|
isc_refcount_increment(&key->refs);
|
2000-07-18 00:46:03 +00:00
|
|
|
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
2010-07-09 05:13:15 +00:00
|
|
|
adjust_lru(key);
|
2000-07-21 20:53:59 +00:00
|
|
|
*tsigkey = key;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
free_tsignode(void *node, void *_unused) {
|
2000-07-21 20:53:59 +00:00
|
|
|
dns_tsigkey_t *key;
|
|
|
|
|
|
|
|
REQUIRE(node != NULL);
|
|
|
|
|
2013-02-18 20:24:24 +11:00
|
|
|
UNUSED(_unused);
|
|
|
|
|
2000-07-21 20:53:59 +00:00
|
|
|
key = node;
|
2013-02-18 20:24:24 +11:00
|
|
|
if (key->generated) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ISC_LINK_LINKED(key, link)) {
|
2013-02-18 20:24:24 +11:00
|
|
|
ISC_LIST_UNLINK(key->ring->lru, key, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-02-18 20:24:24 +11:00
|
|
|
}
|
2000-07-21 20:53:59 +00:00
|
|
|
dns_tsigkey_detach(&key);
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) {
|
|
|
|
isc_result_t result;
|
2000-07-21 20:53:59 +00:00
|
|
|
dns_tsig_keyring_t *ring;
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-10-29 13:56:56 +00:00
|
|
|
REQUIRE(mctx != NULL);
|
2000-07-21 20:53:59 +00:00
|
|
|
REQUIRE(ringp != NULL);
|
|
|
|
REQUIRE(*ringp == NULL);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-07-21 20:53:59 +00:00
|
|
|
ring = isc_mem_get(mctx, sizeof(dns_tsig_keyring_t));
|
2000-08-01 01:33:37 +00:00
|
|
|
|
Add the reader-writer synchronization with modified C-RW-WP
This changes the internal isc_rwlock implementation to:
Irina Calciu, Dave Dice, Yossi Lev, Victor Luchangco, Virendra
J. Marathe, and Nir Shavit. 2013. NUMA-aware reader-writer locks.
SIGPLAN Not. 48, 8 (August 2013), 157–166.
DOI:https://doi.org/10.1145/2517327.24425
(The full article available from:
http://mcg.cs.tau.ac.il/papers/ppopp2013-rwlocks.pdf)
The implementation is based on the The Writer-Preference Lock (C-RW-WP)
variant (see the 3.4 section of the paper for the rationale).
The implemented algorithm has been modified for simplicity and for usage
patterns in rbtdb.c.
The changes compared to the original algorithm:
* We haven't implemented the cohort locks because that would require a
knowledge of NUMA nodes, instead a simple atomic_bool is used as
synchronization point for writer lock.
* The per-thread reader counters are not being used - this would
require the internal thread id (isc_tid_v) to be always initialized,
even in the utilities; the change has a slight performance penalty,
so we might revisit this change in the future. However, this change
also saves a lot of memory, because cache-line aligned counters were
used, so on 32-core machine, the rwlock would be 4096+ bytes big.
* The readers use a writer_barrier that will raise after a while when
readers lock can't be acquired to prevent readers starvation.
* Separate ingress and egress readers counters queues to reduce both
inter and intra-thread contention.
2021-03-24 17:52:56 +01:00
|
|
|
isc_rwlock_init(&ring->lock);
|
2000-07-21 20:53:59 +00:00
|
|
|
ring->keys = NULL;
|
|
|
|
result = dns_rbt_create(mctx, free_tsignode, NULL, &ring->keys);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
isc_rwlock_destroy(&ring->lock);
|
|
|
|
isc_mem_put(mctx, ring, sizeof(dns_tsig_keyring_t));
|
|
|
|
return (result);
|
|
|
|
}
|
1999-10-27 19:59:34 +00:00
|
|
|
|
2006-12-04 01:54:53 +00:00
|
|
|
ring->writecount = 0;
|
2008-01-02 04:24:59 +00:00
|
|
|
ring->mctx = NULL;
|
2010-07-09 05:13:15 +00:00
|
|
|
ring->generated = 0;
|
|
|
|
ring->maxgenerated = DNS_TSIG_MAXGENERATEDKEYS;
|
|
|
|
ISC_LIST_INIT(ring->lru);
|
2008-01-02 04:24:59 +00:00
|
|
|
isc_mem_attach(mctx, &ring->mctx);
|
2019-05-20 16:55:42 +02:00
|
|
|
isc_refcount_init(&ring->references, 1);
|
1999-08-20 18:56:24 +00:00
|
|
|
|
2000-07-21 20:53:59 +00:00
|
|
|
*ringp = ring;
|
1999-08-20 18:56:24 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2009-06-10 00:27:22 +00:00
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_tsigkeyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkey_t *tkey) {
|
2009-06-10 00:27:22 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
2023-05-21 12:59:38 -07:00
|
|
|
REQUIRE(VALID_TSIG_KEY(tkey));
|
|
|
|
REQUIRE(tkey->ring == NULL);
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
|
2009-06-10 00:27:22 +00:00
|
|
|
result = keyring_add(ring, name, tkey);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2018-08-17 15:16:59 +02:00
|
|
|
isc_refcount_increment(&tkey->refs);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-06-10 00:27:22 +00:00
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
1999-08-20 18:56:24 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkeyring_attach(dns_tsig_keyring_t *source,
|
|
|
|
dns_tsig_keyring_t **target) {
|
2011-01-10 05:32:04 +00:00
|
|
|
REQUIRE(source != NULL);
|
|
|
|
REQUIRE(target != NULL && *target == NULL);
|
|
|
|
|
2019-05-20 16:55:42 +02:00
|
|
|
isc_refcount_increment(&source->references);
|
|
|
|
|
2011-01-10 05:32:04 +00:00
|
|
|
*target = source;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp) {
|
2000-07-21 20:53:59 +00:00
|
|
|
dns_tsig_keyring_t *ring;
|
2000-01-21 22:51:48 +00:00
|
|
|
|
2000-07-21 20:53:59 +00:00
|
|
|
REQUIRE(ringp != NULL);
|
|
|
|
REQUIRE(*ringp != NULL);
|
2000-01-21 20:18:41 +00:00
|
|
|
|
2000-07-21 20:53:59 +00:00
|
|
|
ring = *ringp;
|
|
|
|
*ringp = NULL;
|
2000-01-21 20:18:41 +00:00
|
|
|
|
2019-05-20 16:55:42 +02:00
|
|
|
if (isc_refcount_decrement(&ring->references) == 1) {
|
2011-01-10 05:32:04 +00:00
|
|
|
destroyring(ring);
|
2019-05-20 16:55:42 +02:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp) {
|
2023-03-30 21:13:41 +02:00
|
|
|
isc_stdtime_t now = isc_stdtime_now();
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2011-01-10 05:32:04 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
result = restore_key(ring, now, fp);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_NOMORE) {
|
2011-01-10 05:32:04 +00:00
|
|
|
return;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (result == DNS_R_BADALG || result == DNS_R_EXPIRED) {
|
2011-01-10 05:32:04 +00:00
|
|
|
result = ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-01-10 05:32:04 +00:00
|
|
|
} while (result == ISC_R_SUCCESS);
|
1999-08-20 18:56:24 +00:00
|
|
|
}
|