tsig.c revision 65f9103cc5980fe49268739205a089774d130926
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer/*
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Copyright (C) 1999 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Permission to use, copy, modify, and distribute this software for any
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * purpose with or without fee is hereby granted, provided that the above
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15a44745412679c30a6d022733925af70a38b715David Lawrence * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
15a44745412679c30a6d022733925af70a38b715David Lawrence * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15a44745412679c30a6d022733925af70a38b715David Lawrence * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15a44745412679c30a6d022733925af70a38b715David Lawrence * SOFTWARE.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
e32394a2ac3466a2235f79ee32c247a11be42a8dAndreas Gustafsson/*
47058d17266420179fa294de6b82d8fb5b918df4Michael Sawyer * $Id: tsig.c,v 1.32 1999/11/05 20:19:24 halley Exp $
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Principal Author: Brian Wellington
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <config.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <stdlib.h>
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <string.h>
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <isc/assertions.h>
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <isc/base64.h>
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <isc/buffer.h>
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <isc/error.h>
c9defbf4b968e8a61f391246431ac63d0d6a39abMichael Sawyer#include <isc/list.h>
1893b56ef9f5f2bc2a0fbe80d3c6b69df1bdc7c2Michael Sawyer#include <isc/net.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <isc/result.h>
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer#include <isc/rwlock.h>
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer#include <isc/stdtime.h>
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer#include <isc/types.h>
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer#include <dns/keyvalues.h>
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer#include <dns/name.h>
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer#include <dns/message.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dns/rdata.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dns/rdatalist.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dns/rdataset.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dns/rdatastruct.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dns/tsig.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dns/confctx.h>
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer#include <dns/confkeys.h>
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dst/dst.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#include <dst/result.h>
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#define TSIG_MAGIC 0x54534947 /* TSIG */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer#define VALID_TSIG_KEY(x) ((x) != NULL && (x)->magic == TSIG_MAGIC)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer/* XXXBEW If an unsorted list isn't good enough, this can be updated */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerstatic ISC_LIST(dns_tsigkey_t) tsigkeys;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerstatic isc_rwlock_t tsiglock;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerstatic isc_mem_t *tsig_mctx = NULL;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerdns_name_t *dns_tsig_hmacmd5_name = NULL;
1893b56ef9f5f2bc2a0fbe80d3c6b69df1bdc7c2Michael Sawyer
38cf6e52ce4b33795713388824b69d78e430b115Michael Sawyer#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerisc_result_t
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
6c6a62933dda281cb9193de1d54d4c9e74515f5aMichael Sawyer unsigned char *secret, int length, isc_boolean_t generated,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_name_t *creator, isc_mem_t *mctx, dns_tsigkey_t **key)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer{
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_t b, nameb;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer char namestr[1025];
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_uint16_t alg;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_tsigkey_t *tkey;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_result_t ret;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_region_t r;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer REQUIRE(key == NULL || *key == NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer REQUIRE(name != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(algorithm != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(length >= 0);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (length > 0)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer REQUIRE(secret != NULL);
a5ed46c9fd270775c39770bfd0250a52d374ebf2Michael Sawyer REQUIRE(mctx != NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (!dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME))
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return (ISC_R_NOTFOUND);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer else
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer alg = DST_ALG_HMACMD5;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t));
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (tkey == NULL)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return (ISC_R_NOMEMORY);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (key != NULL)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer *key = tkey;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_name_init(&tkey->name, NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer ret = dns_name_dup(name, mctx, &tkey->name);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (ret != ISC_R_SUCCESS)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer goto cleanup_key;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_name_downcase(&tkey->name, &tkey->name, NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_name_init(&tkey->algorithm, NULL);
a5ed46c9fd270775c39770bfd0250a52d374ebf2Michael Sawyer ret = dns_name_dup(algorithm, mctx, &tkey->algorithm);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_name;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_downcase(&tkey->algorithm, &tkey->algorithm, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (creator != NULL) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tkey->creator == NULL) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ret = ISC_R_NOMEMORY;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_init(tkey->creator, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_name_dup(algorithm, mctx, tkey->creator);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tkey->creator = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&nameb, namestr, sizeof(namestr) - 1,
e32394a2ac3466a2235f79ee32c247a11be42a8dAndreas Gustafsson ISC_BUFFERTYPE_TEXT);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_name_totext(name, ISC_FALSE, &nameb);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(&nameb, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer namestr[r.length] = '\0';
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (length > 0) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_tsigkey_t *tmp;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&b, secret, length, ISC_BUFFERTYPE_BINARY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_add(&b, length);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_key_frombuffer(namestr, alg,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer DNS_KEYOWNER_ENTITY,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer DNS_KEYPROTO_DNSSEC,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer &b, mctx, &tkey->key);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_LINK_INIT(tkey, link);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_rwlock_lock(&tsiglock, isc_rwlocktype_write);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tmp = ISC_LIST_HEAD(tsigkeys);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer while (tmp != NULL) {
cd720113a2fc8a781d4e33350b8a2b62857b31d8David Lawrence if (dns_name_equal(&tkey->name, &tmp->name)) {
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson ret = ISC_R_EXISTS;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_rwlock_unlock(&tsiglock,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_rwlocktype_write);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
38cf6e52ce4b33795713388824b69d78e430b115Michael Sawyer tmp = ISC_LIST_NEXT(tmp, link);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_LIST_APPEND(tsigkeys, tkey, link);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_rwlock_unlock(&tsiglock, isc_rwlocktype_write);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tkey->key = NULL;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer tkey->refs = 0;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (key != NULL)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer tkey->refs++;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson tkey->generated = generated;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson tkey->deleted = ISC_FALSE;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson tkey->mctx = mctx;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson ret = isc_mutex_init(&tkey->lock);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (ret != ISC_R_SUCCESS) {
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer UNEXPECTED_ERROR(__FILE__, __LINE__,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer "isc_mutex_init() failed: %s",
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_result_totext(ret));
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson return (DNS_R_UNEXPECTED);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson }
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer tkey->magic = TSIG_MAGIC;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return (ISC_R_SUCCESS);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyercleanup_algorithm:
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_name_free(&tkey->algorithm, mctx);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyercleanup_name:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_free(&tkey->name, mctx);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyercleanup_key:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_put(mctx, *key, sizeof(dns_tsigkey_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ret);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer}
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyervoid
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafssondns_tsigkey_free(dns_tsigkey_t **key) {
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson dns_tsigkey_t *tkey;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(key != NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer REQUIRE(VALID_TSIG_KEY(*key));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tkey = *key;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer *key = NULL;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_mutex_lock(&tkey->lock);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer tkey->refs--;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tkey->refs > 0 || !tkey->deleted) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mutex_unlock(&tkey->lock);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_mutex_unlock(&tkey->lock);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tkey->magic = 0;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (tkey->key != NULL) {
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_rwlock_lock(&tsiglock, isc_rwlocktype_write);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer ISC_LIST_UNLINK(tsigkeys, tkey, link);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_rwlock_unlock(&tsiglock, isc_rwlocktype_write);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson dns_name_free(&tkey->name, tkey->mctx);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson dns_name_free(&tkey->algorithm, tkey->mctx);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tkey->key != NULL)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dst_key_free(tkey->key);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tkey->creator != NULL) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_free(tkey->creator, tkey->mctx);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_put(tkey->mctx, tkey->creator, sizeof(dns_name_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_put(tkey->mctx, tkey, sizeof(dns_tsigkey_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer}
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyervoid
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_tsigkey_setdeleted(dns_tsigkey_t *key) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer INSIST(VALID_TSIG_KEY(key));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mutex_lock(&key->lock);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer key->deleted = ISC_TRUE;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mutex_unlock(&key->lock);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer}
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerisc_result_t
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_tsig_sign(dns_message_t *msg) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_tsigkey_t *key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_any_tsig_t *tsig;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned char data[128];
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_t databuf, sigbuf;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_t *dynbuf;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_t *owner;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_t *rdata;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdatalist_t *datalist;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdataset_t *dataset;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_region_t r, r2;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_stdtime_t now;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dst_context_t ctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_t *mctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_result_t ret;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(msg != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(VALID_TSIG_KEY(msg->tsigkey));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(msg->tsig == NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
a5ed46c9fd270775c39770bfd0250a52d374ebf2Michael Sawyer /* If this is a response, there should be a query tsig */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (is_response(msg) && msg->querytsig == NULL)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (DNS_R_EXPECTEDTSIG);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dynbuf = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer mctx = msg->mctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer key = msg->tsigkey;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig = (dns_rdata_any_tsig_t *)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig == NULL)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ISC_R_NOMEMORY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->mctx = mctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->common.rdclass = dns_rdataclass_any;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->common.rdtype = dns_rdatatype_tsig;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_LINK_INIT(&tsig->common, link);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_init(&tsig->algorithm, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_name_dup(&key->algorithm, mctx, &tsig->algorithm);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_struct;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = isc_stdtime_get(&now);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->timesigned = now;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->fudge = DNS_TSIG_FUDGE;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->originalid = msg->id;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&databuf, data, sizeof(data), ISC_BUFFERTYPE_BINARY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (!dns_tsigkey_empty(key)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_sign(DST_SIGMODE_INIT, key->key, &ctx, NULL, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (is_response(msg)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (!dns_tsigkey_empty(key)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_available(&databuf, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (r.length < msg->querytsig->siglen)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ISC_R_NOSPACE);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer memcpy(r.base, msg->querytsig->signature,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->querytsig->siglen);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_add(&databuf, msg->querytsig->siglen);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(&databuf, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer NULL);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_algorithm;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->error = msg->querytsigstatus;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson else
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->error = dns_rcode_noerror;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig->error != dns_tsigerror_badtime) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->otherlen = 0;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence tsig->other = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_t otherbuf;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->otherlen = 6;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->other = (unsigned char *) isc_mem_get(mctx, 6);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig->other == NULL) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ret = ISC_R_NOMEMORY;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_other;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer }
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_init(&otherbuf, tsig->other, tsig->otherlen = 6,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_BUFFERTYPE_BINARY);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_putuint16(&otherbuf,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer (isc_uint16_t)(tsig->timesigned >> 32));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint32(&otherbuf,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer (isc_uint32_t)(tsig->timesigned &
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer 0xFFFFFFFF));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (!dns_tsigkey_empty(key) && tsig->error != dns_tsigerror_badsig) {
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer unsigned char header[DNS_MESSAGE_HEADERLEN];
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_t headerbuf;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer unsigned int sigsize;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /* Digest the header */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_init(&headerbuf, header, sizeof header,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ISC_BUFFERTYPE_BINARY);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_message_renderheader(msg, &headerbuf);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_used(&headerbuf, &r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r, NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson /* Digest the remainder of the message */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_used(msg->buffer, &r);
38cf6e52ce4b33795713388824b69d78e430b115Michael Sawyer isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r, NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson if (msg->tcp_continuation == 0) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /* Digest the name, class, ttl, alg */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_name_toregion(&key->name, &r);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_clear(&databuf);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson isc_buffer_putuint16(&databuf, dns_rdataclass_any);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint32(&databuf, 0); /* ttl */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_used(&databuf, &r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_name_toregion(&tsig->algorithm, &r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /* Digest the timesigned and fudge */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_clear(&databuf);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (tsig->error != dns_tsigerror_badtime) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint16(&databuf,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer (isc_uint16_t)(tsig->timesigned >>
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer 32));
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint32(&databuf,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer (isc_uint32_t)(tsig->timesigned &
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer 0xFFFFFFFF));
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer else {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_uint64_t querysigned = msg->querytsig->timesigned;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint16(&databuf,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer (isc_uint16_t)(querysigned >>
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer 32));
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint32(&databuf,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer (isc_uint16_t)(querysigned &
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer 0xFFFFFFFF));
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint16(&databuf, tsig->fudge);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_used(&databuf, &r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r, NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
a5ed46c9fd270775c39770bfd0250a52d374ebf2Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (msg->tcp_continuation == 0) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /* Digest the error and other data length */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_clear(&databuf);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint16(&databuf, tsig->error);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_putuint16(&databuf, tsig->otherlen);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_used(&databuf, &r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /* Digest the error and other data */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (tsig->otherlen > 0) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer r.length = tsig->otherlen;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer r.base = tsig->other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_UPDATE, key->key,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer &ctx, &r, NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sig_size(key->key, &sigsize);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer tsig->siglen = sigsize;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer tsig->signature = (unsigned char *)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_mem_get(mctx, tsig->siglen);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (tsig->signature == NULL) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = ISC_R_NOMEMORY;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_other;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_init(&sigbuf, tsig->signature, tsig->siglen,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ISC_BUFFERTYPE_BINARY);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dst_sign(DST_SIGMODE_FINAL, key->key, &ctx, NULL,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer &sigbuf);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_signature;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer else {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer tsig->siglen = 0;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson tsig->signature = NULL;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer }
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson rdata = NULL;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dns_message_gettemprdata(msg, &rdata);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence goto cleanup_signature;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ISC_BUFFERTYPE_BINARY);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_signature;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_rdatatype_tsig, tsig, dynbuf);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_dynbuf;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_message_takebuffer(msg, &dynbuf);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer msg->tsig = tsig;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer owner = NULL;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = dns_message_gettempname(msg, &owner);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_dynbuf;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_name_toregion(&key->name, &r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dynbuf = NULL;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ret = isc_buffer_allocate(mctx, &dynbuf, r.length,
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer ISC_BUFFERTYPE_BINARY);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ret != ISC_R_SUCCESS)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer goto cleanup_dynbuf;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_available(dynbuf, &r2);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer memcpy(r2.base, r.base, r.length);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_init(owner, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_fromregion(owner, &r2);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_message_takebuffer(msg, &dynbuf);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson datalist = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_message_gettemprdatalist(msg, &datalist);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_dynbuf;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer datalist->rdclass = dns_rdataclass_any;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer datalist->type = dns_rdatatype_tsig;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer datalist->covers = 0;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer datalist->ttl = 0;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_LIST_INIT(datalist->rdata);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_LIST_APPEND(datalist->rdata, rdata, link);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dataset = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_message_gettemprdataset(msg, &dataset);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson goto cleanup_dynbuf;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdataset_init(dataset);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_rdatalist_tordataset(datalist, dataset);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson ISC_LIST_APPEND(owner->list, dataset, link);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_message_addname(msg, owner, DNS_SECTION_TSIG);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ISC_R_SUCCESS);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyercleanup_dynbuf:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (dynbuf != NULL)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_free(&dynbuf);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyercleanup_signature:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig->signature != NULL)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_mem_put(mctx, tsig->signature, tsig->siglen);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafssoncleanup_other:
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (tsig->other != NULL)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_mem_put(mctx, tsig->other, tsig->otherlen);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyercleanup_algorithm:
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_name_free(&tsig->algorithm, mctx);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyercleanup_struct:
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson msg->tsig = NULL;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ret);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson}
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrenceisc_result_t
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_tsig_verify(isc_buffer_t *source, dns_message_t *msg) {
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer dns_rdata_any_tsig_t *tsig;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson isc_region_t r, source_r, header_r, sig_r;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_t databuf;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer unsigned char data[32];
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_name_t *keyname;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_rdataset_t *dataset;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_rdata_t rdata;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_stdtime_t now;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_result_t ret;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_tsigkey_t *tsigkey = NULL;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dst_key_t *key = NULL;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer unsigned char header[DNS_MESSAGE_HEADERLEN];
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dst_context_t ctx;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_mem_t *mctx;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_uint16_t addcount, id;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence REQUIRE(source != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(msg != NULL);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer REQUIRE(msg->tsig == NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (msg->tsigkey != NULL)
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer REQUIRE(VALID_TSIG_KEY(msg->tsigkey));
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /* There should be a TSIG record... */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (ISC_LIST_EMPTY(msg->sections[DNS_SECTION_TSIG]))
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer return (DNS_R_EXPECTEDTSIG);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer /*
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * If this is a response and there's no key or query TSIG, there
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * shouldn't be one on the response.
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer */
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if (is_response(msg) &&
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer (msg->tsigkey == NULL || msg->querytsig == NULL))
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return (DNS_R_UNEXPECTEDTSIG);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson mctx = msg->mctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer /*
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * If we're here, we know the message is well formed and contains a
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * TSIG record.
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer */
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson ret = dns_message_firstname(msg, DNS_SECTION_TSIG);
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer if (ret != ISC_R_SUCCESS)
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson return (ret);
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer keyname = NULL;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson dns_message_currentname(msg, DNS_SECTION_TSIG, &keyname);
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer dataset = ISC_LIST_HEAD(keyname->list);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_rdataset_first(dataset);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (ret != ISC_R_SUCCESS)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return (ret);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer dns_rdataset_current(dataset, &rdata);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer tsig = (dns_rdata_any_tsig_t *)
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (tsig == NULL)
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer return (ISC_R_NOMEMORY);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer msg->tsig = tsig;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer ret = dns_rdata_tostruct(&rdata, tsig, mctx);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (ret != ISC_R_SUCCESS)
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer goto cleanup_emptystruct;
5564b21be5cf3e7b8f751af268f2c1522c1744e3David Lawrence
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer /* Do the key name and algorithm match that of the query? */
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (is_response(msg) &&
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer (!dns_name_equal(keyname, &msg->tsigkey->name) ||
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer !dns_name_equal(&tsig->algorithm, &msg->querytsig->algorithm)))
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer {
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer msg->tsigstatus = dns_tsigerror_badkey;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer }
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer /* Find dns_tsigkey_t based on keyname */
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (msg->tsigkey == NULL) {
5564b21be5cf3e7b8f751af268f2c1522c1744e3David Lawrence ret = dns_tsigkey_find(&tsigkey, keyname, &tsig->algorithm);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (ret != ISC_R_SUCCESS) {
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer msg->tsigstatus = dns_tsigerror_badkey;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer msg->tsigkey = NULL;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer ret = dns_tsigkey_create(keyname, &tsig->algorithm,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer NULL, 0, ISC_FALSE, NULL,
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer mctx, &msg->tsigkey);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_struct;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigkey = tsigkey;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsigkey = msg->tsigkey;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer key = tsigkey->key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer /* Is the time ok? */
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer ret = isc_stdtime_get(&now);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (abs(now - tsig->timesigned) > tsig->fudge) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigstatus = dns_tsigerror_badtime;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer if (tsig->siglen > 0) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer sig_r.base = tsig->signature;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer sig_r.length = tsig->siglen;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_INIT, key, &ctx, NULL, &sig_r);
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (is_response(msg)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&databuf, data, sizeof(data),
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_BUFFERTYPE_BINARY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(&databuf, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (msg->querytsig->siglen > 0) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer r.length = msg->querytsig->siglen;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer r.base = msg->querytsig->signature;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer &ctx, &r, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer /* Extract the header */
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer isc_buffer_used(source, &r);
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyer memcpy(header, r.base, DNS_MESSAGE_HEADERLEN);
f8fec75ee8f429821137aee090f56ab678404a56Michael Sawyer isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
6c6a62933dda281cb9193de1d54d4c9e74515f5aMichael Sawyer
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer /* Decrement the additional field counter */
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer addcount = htons(ntohs(addcount) - 1);
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer /* Put in the original id */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer id = htons(tsig->originalid);
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer memcpy(&header[0], &id, 2);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer /* Digest the modified header */
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer header_r.base = (unsigned char *) header;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer header_r.length = DNS_MESSAGE_HEADERLEN;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &header_r,
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer &sig_r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson goto cleanup_key;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer /* Digest all non-TSIG records. */
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer isc_buffer_used(source, &source_r);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r, &sig_r);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (ret != ISC_R_SUCCESS)
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer goto cleanup_key;
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Digest the key name */
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer dns_name_toregion(&tsigkey->name, &r);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r, &sig_r);
cd720113a2fc8a781d4e33350b8a2b62857b31d8David Lawrence if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&databuf, data, sizeof(data),
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_BUFFERTYPE_BINARY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(&databuf, tsig->common.rdclass);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_putuint32(&databuf, dataset->ttl);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(&databuf, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r, &sig_r);
9fe3676b8490319aa65182f2072cbf5086097979Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Digest the key algorithm */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_toregion(&tsigkey->algorithm, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r, &sig_r);
17747cd5ee98901b435cd2b3019c52937955a981Michael Sawyer if (ret != ISC_R_SUCCESS)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer goto cleanup_key;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_clear(&databuf);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig->timesigned
38cf6e52ce4b33795713388824b69d78e430b115Michael Sawyer >> 32));
48674819ebf9176b5d5582ae851e485c324c1159Michael Sawyer isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig->timesigned
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer & 0xFFFFFFFF));
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_putuint16(&databuf, tsig->fudge);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(&databuf, tsig->error);
cd720113a2fc8a781d4e33350b8a2b62857b31d8David Lawrence isc_buffer_putuint16(&databuf, tsig->otherlen);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(&databuf, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r, &sig_r);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig->otherlen > 0) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer r.base = tsig->other;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer r.length = tsig->otherlen;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer &sig_r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_FINAL, key, &ctx, NULL, &sig_r);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (ret == DST_R_VERIFYFINALFAILURE) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigstatus = dns_tsigerror_badsig;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_key;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else if (tsig->error != dns_tsigerror_badsig &&
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig->error != dns_tsigerror_badkey)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigstatus = dns_tsigerror_badsig;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigstatus = dns_rcode_noerror;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig->error != dns_rcode_noerror) {
cd720113a2fc8a781d4e33350b8a2b62857b31d8David Lawrence if (is_response(msg)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* XXXBEW Log a message */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ISC_R_SUCCESS);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer else
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (DNS_R_TSIGERRORSET);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ISC_R_SUCCESS);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyercleanup_key:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (dns_tsigkey_empty(msg->tsigkey)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_tsigkey_free(&msg->tsigkey);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigkey = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyercleanup_struct:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_freestruct(tsig);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyercleanup_emptystruct:
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsig = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ret);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence}
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrenceisc_result_t
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_any_tsig_t *tsig = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_region_t r, source_r, header_r, sig_r;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_t databuf;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned char data[32];
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_name_t *keyname;
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer dns_rdataset_t *dataset;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_t rdata;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_stdtime_t now;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson isc_result_t ret;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dst_key_t *key = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned char header[DNS_MESSAGE_HEADERLEN];
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_t *mctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_uint16_t addcount, id;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_boolean_t has_tsig = ISC_FALSE;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(source != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(msg != NULL);
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer REQUIRE(msg->tsig == NULL);
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer REQUIRE(msg->tsigkey != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(msg->tcp_continuation == 1);
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer REQUIRE(is_response(msg));
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer REQUIRE(msg->querytsig != NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
19c8df90f1f23c3df870c1771c89c1acdb15020eMichael Sawyer mctx = msg->mctx;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_message_firstname(msg, DNS_SECTION_TSIG);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret == ISC_R_SUCCESS) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer has_tsig = ISC_TRUE;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer keyname = NULL;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_message_currentname(msg, DNS_SECTION_TSIG, &keyname);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dataset = ISC_LIST_HEAD(keyname->list);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_rdataset_first(dataset);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ret);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdataset_current(dataset, &rdata);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer tsig = (dns_rdata_any_tsig_t *)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (tsig == NULL)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (ISC_R_NOMEMORY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsig = tsig;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dns_rdata_tostruct(&rdata, tsig, mctx);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_emptystruct;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Do the key name and algorithm match that of the query? */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (!dns_name_equal(keyname, &msg->tsigkey->name) ||
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer !dns_name_equal(&tsig->algorithm,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer &msg->querytsig->algorithm))
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigstatus = dns_tsigerror_badkey;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer }
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Is the time ok? */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = isc_stdtime_get(&now);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_struct;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (abs(now - tsig->timesigned) > tsig->fudge) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer msg->tsigstatus = dns_tsigerror_badtime;
e715e011788a529446b8013239c33599542ece32Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
e715e011788a529446b8013239c33599542ece32Michael Sawyer }
e715e011788a529446b8013239c33599542ece32Michael Sawyer }
e715e011788a529446b8013239c33599542ece32Michael Sawyer
e715e011788a529446b8013239c33599542ece32Michael Sawyer key = msg->tsigkey->key;
e715e011788a529446b8013239c33599542ece32Michael Sawyer
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (msg->tsigctx == NULL) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_INIT, key, &msg->tsigctx,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer NULL, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_struct;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&databuf, data, sizeof(data),
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ISC_BUFFERTYPE_BINARY);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(&databuf, &r);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence &r, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer goto cleanup_struct;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (msg->querytsig->siglen > 0) {
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer r.length = msg->querytsig->siglen;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer r.base = msg->querytsig->signature;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer &msg->tsigctx, &r, NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer if (ret != ISC_R_SUCCESS)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer goto cleanup_struct;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer }
38cf6e52ce4b33795713388824b69d78e430b115Michael Sawyer }
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer /* Extract the header */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_used(source, &r);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer memcpy(header, r.base, DNS_MESSAGE_HEADERLEN);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer /* Decrement the additional field counter if necessary */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (has_tsig) {
f8fec75ee8f429821137aee090f56ab678404a56Michael Sawyer memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
6c6a62933dda281cb9193de1d54d4c9e74515f5aMichael Sawyer addcount = htons(ntohs(addcount) - 1);
88301f84d1391e96ec87a9a308aa18f45553a56bAndreas Gustafsson memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
6c6a62933dda281cb9193de1d54d4c9e74515f5aMichael Sawyer }
ad7bb5bff3e796f5648835bf87a203d23d8319e4David Lawrence
88301f84d1391e96ec87a9a308aa18f45553a56bAndreas Gustafsson /* Put in the original id */
f8fec75ee8f429821137aee090f56ab678404a56Michael Sawyer id = htons(tsig->originalid);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer memcpy(&header[0], &id, 2);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Digest the modified header */
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer header_r.base = (unsigned char *) header;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer header_r.length = DNS_MESSAGE_HEADERLEN;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &header_r,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_struct;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer /* Digest all non-TSIG records. */
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_used(source, &source_r);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (has_tsig)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer else
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer r.length = source_r.length - DNS_MESSAGE_HEADERLEN;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ret = dst_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &r, NULL);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer if (ret != ISC_R_SUCCESS)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer goto cleanup_struct;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer
9fe3676b8490319aa65182f2072cbf5086097979Michael Sawyer /* Digest the time signed and fudge */
9fe3676b8490319aa65182f2072cbf5086097979Michael Sawyer if (has_tsig) {
9fe3676b8490319aa65182f2072cbf5086097979Michael Sawyer isc_buffer_init(&databuf, data, sizeof(data),
9fe3676b8490319aa65182f2072cbf5086097979Michael Sawyer ISC_BUFFERTYPE_BINARY);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig->timesigned
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer >> 32));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig->timesigned
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer & 0xFFFFFFFF));
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer isc_buffer_putuint16(&databuf, tsig->fudge);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson isc_buffer_used(&databuf, &r);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson ret = dst_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &r,
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer NULL);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer sig_r.base = tsig->signature;
1893b56ef9f5f2bc2a0fbe80d3c6b69df1bdc7c2Michael Sawyer sig_r.length = tsig->siglen;
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson
1893b56ef9f5f2bc2a0fbe80d3c6b69df1bdc7c2Michael Sawyer ret = dst_verify(DST_SIGMODE_FINAL, key, &msg->tsigctx, NULL,
1893b56ef9f5f2bc2a0fbe80d3c6b69df1bdc7c2Michael Sawyer &sig_r);
bf9163715dca2bfa7645d714dc091881e7183f73Brian Wellington if (ret == DST_R_VERIFYFINALFAILURE) {
db8b100cae62de849ecf4ba9ad3be811fb375b53Michael Sawyer msg->tsigstatus = dns_tsigerror_badsig;
db8b100cae62de849ecf4ba9ad3be811fb375b53Michael Sawyer return (DNS_R_TSIGVERIFYFAILURE);
db8b100cae62de849ecf4ba9ad3be811fb375b53Michael Sawyer }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence else if (ret != ISC_R_SUCCESS)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence goto cleanup_struct;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer msg->tsigctx = NULL;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer }
msg->tsigstatus = dns_rcode_noerror;
return (ISC_R_SUCCESS);
cleanup_struct:
dns_rdata_freestruct(tsig);
cleanup_emptystruct:
msg->tsig = NULL;
isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
return (ret);
}
isc_result_t
dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
dns_name_t *algorithm)
{
dns_tsigkey_t *key;
REQUIRE(tsigkey != NULL);
REQUIRE(*tsigkey == NULL);
REQUIRE(name != NULL);
isc_rwlock_lock(&tsiglock, isc_rwlocktype_read);
key = ISC_LIST_HEAD(tsigkeys);
while (key != NULL) {
if (dns_name_equal(&key->name, name) &&
(algorithm == NULL ||
dns_name_equal(&key->algorithm, algorithm)) &&
!key->deleted)
{
isc_mutex_lock(&key->lock);
key->refs++;
isc_mutex_unlock(&key->lock);
*tsigkey = key;
isc_rwlock_unlock(&tsiglock, isc_rwlocktype_read);
return (ISC_R_SUCCESS);
}
key = ISC_LIST_NEXT(key, link);
}
isc_rwlock_unlock(&tsiglock, isc_rwlocktype_read);
*tsigkey = NULL;
return (ISC_R_NOTFOUND);
}
static isc_result_t
add_initial_keys(dns_c_kdeflist_t *list, isc_mem_t *mctx) {
isc_lex_t *lex = NULL;
dns_c_kdef_t *key;
unsigned char *secret = NULL;
int secretlen = 0;
isc_result_t ret;
key = ISC_LIST_HEAD(list->keydefs);
while (key != NULL) {
dns_name_t keyname;
dns_name_t alg;
char keynamedata[1024], algdata[1024];
isc_buffer_t keynamesrc, keynamebuf, algsrc, algbuf;
isc_buffer_t secretsrc, secretbuf;
dns_name_init(&keyname, NULL);
dns_name_init(&alg, NULL);
/* Create the key name */
isc_buffer_init(&keynamesrc, key->keyid, strlen(key->keyid),
ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&keynamesrc, strlen(key->keyid));
isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata),
ISC_BUFFERTYPE_BINARY);
ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
ISC_TRUE, &keynamebuf);
if (ret != ISC_R_SUCCESS)
goto failure;
/* Create the algorithm */
if (strcasecmp(key->algorithm, "hmac-md5") == 0)
alg = *dns_tsig_hmacmd5_name;
else {
isc_buffer_init(&algsrc, key->algorithm,
strlen(key->algorithm),
ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&algsrc, strlen(key->algorithm));
isc_buffer_init(&algbuf, algdata, sizeof(algdata),
ISC_BUFFERTYPE_BINARY);
ret = dns_name_fromtext(&alg, &algsrc, dns_rootname,
ISC_TRUE, &algbuf);
if (ret != ISC_R_SUCCESS)
goto failure;
}
if (strlen(key->secret) % 4 != 0) {
ret = ISC_R_BADBASE64;
goto failure;
}
secretlen = strlen(key->secret) * 3 / 4;
secret = isc_mem_get(mctx, secretlen);
if (secret == NULL) {
ret = ISC_R_NOMEMORY;
goto failure;
}
isc_buffer_init(&secretsrc, key->secret, strlen(key->secret),
ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&secretsrc, strlen(key->secret));
isc_buffer_init(&secretbuf, secret, secretlen,
ISC_BUFFERTYPE_BINARY);
ret = isc_lex_create(mctx, strlen(key->secret), &lex);
if (ret != ISC_R_SUCCESS)
goto failure;
ret = isc_lex_openbuffer(lex, &secretsrc);
if (ret != ISC_R_SUCCESS)
goto failure;
ret = isc_base64_tobuffer(lex, &secretbuf, -1);
if (ret != ISC_R_SUCCESS)
goto failure;
isc_lex_close(lex);
lex = NULL;
ret = dns_tsigkey_create(&keyname, &alg, secret, secretlen,
ISC_FALSE, NULL, mctx, NULL);
isc_mem_put(mctx, secret, secretlen);
secret = NULL;
if (ret != ISC_R_SUCCESS)
goto failure;
key = ISC_LIST_NEXT(key, next);
}
return (ISC_R_SUCCESS);
failure:
if (lex != NULL)
isc_lex_close(lex);
if (secret != NULL)
isc_mem_put(mctx, secret, secretlen);
return (ret);
}
isc_result_t
dns_tsig_init(isc_log_t *lctx, dns_c_ctx_t *confctx, isc_mem_t *mctx) {
isc_buffer_t hmacsrc, namebuf;
isc_result_t ret;
dns_name_t hmac_name;
unsigned char data[32];
dns_c_kdeflist_t *keylist = NULL;
REQUIRE(lctx != NULL);
REQUIRE(mctx != NULL);
ret = isc_rwlock_init(&tsiglock, 0, 0);
if (ret != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_rwlock_init() failed: %s",
isc_result_totext(ret));
return (DNS_R_UNEXPECTED);
}
ISC_LIST_INIT(tsigkeys);
isc_buffer_init(&hmacsrc, DNS_TSIG_HMACMD5,
strlen(DNS_TSIG_HMACMD5), ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&hmacsrc, strlen(DNS_TSIG_HMACMD5));
isc_buffer_init(&namebuf, data, sizeof(data), ISC_BUFFERTYPE_BINARY);
dns_name_init(&hmac_name, NULL);
ret = dns_name_fromtext(&hmac_name, &hmacsrc, NULL, ISC_TRUE, &namebuf);
if (ret != ISC_R_SUCCESS)
return (ret);
dns_tsig_hmacmd5_name = isc_mem_get(mctx, sizeof(dns_name_t));
if (dns_tsig_hmacmd5_name == NULL)
return (ISC_R_NOMEMORY);
dns_name_init(dns_tsig_hmacmd5_name, NULL);
ret = dns_name_dup(&hmac_name, mctx, dns_tsig_hmacmd5_name);
if (ret != ISC_R_SUCCESS)
goto failure;
if (confctx != NULL) {
ret = dns_c_ctx_getkdeflist(lctx, confctx, &keylist);
if (ret == ISC_R_SUCCESS)
ret = add_initial_keys(keylist, mctx);
else if (ret != ISC_R_NOTFOUND)
goto failure;
}
tsig_mctx = mctx;
return (ISC_R_SUCCESS);
failure:
isc_mem_put(mctx, dns_tsig_hmacmd5_name, sizeof(dns_name_t));
return (ret);
}
void
dns_tsig_destroy() {
if (tsig_mctx == NULL)
return;
while (!ISC_LIST_EMPTY(tsigkeys)) {
dns_tsigkey_t *key = ISC_LIST_HEAD(tsigkeys);
key->refs = 0;
key->deleted = ISC_TRUE;
dns_tsigkey_free(&key);
}
dns_name_free(dns_tsig_hmacmd5_name, tsig_mctx);
isc_mem_put(tsig_mctx, dns_tsig_hmacmd5_name, sizeof(dns_name_t));
}