tkey.c revision f879d3ee27d172ed7913bc0d6c36c610a3e48329
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence/*
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 1999 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * Permission to use, copy, modify, and distribute this software for any
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * purpose with or without fee is hereby granted, provided that the above
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * 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.
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrence/*
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * $Id: tkey.c,v 1.4 1999/10/26 21:57:52 bwelling Exp $
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Principal Author: Brian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
6b7257f756eb0530cdf54df9a7fab8d51a5001c3David Lawrence#include <config.h>
6b7257f756eb0530cdf54df9a7fab8d51a5001c3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <stdlib.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <string.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <isc/assertions.h>
ce2be9b7211ab5bacaa10fe74ef35def3a3f6089David Lawrence#include <isc/buffer.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <isc/error.h>
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence#include <isc/list.h>
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington#include <isc/log.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <isc/net.h>
f96b41064bcd427d8125a096fd646c1f068d8ed7David Lawrence#include <isc/result.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <isc/rwlock.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/stdtime.h>
f96b41064bcd427d8125a096fd646c1f068d8ed7David Lawrence#include <isc/types.h>
e19501436a92cd48eba2ff47d90fa49c661ec8d8Brian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <dns/dnssec.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <dns/keyvalues.h>
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington#include <dns/name.h>
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence#include <dns/message.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/rdata.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/rdatalist.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/rdataset.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/rdatastruct.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/tkey.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/tsig.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/confctx.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dst/dst.h>
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrence#include <dst/result.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#define dns_tsigerror_badalg 21
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#define RETERR(x) do { \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = (x); \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result != ISC_R_SUCCESS) \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto failure; \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington } while (0)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellingtonstatic dst_key_t *tkey_dhkey = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellingtonstatic dns_name_t *tkey_domain = NULL;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrenceisc_result_t
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrencedns_tkey_init(isc_log_t *lctx, dns_c_ctx_t *cfg, isc_mem_t *mctx) {
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrence isc_result_t result;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence char *s;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence int n;
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence isc_buffer_t b, *namebuf;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence RUNTIME_CHECK(tkey_domain == NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RUNTIME_CHECK(tkey_dhkey == NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington REQUIRE(lctx != NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington REQUIRE(cfg != NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington REQUIRE(mctx != NULL);
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington s = NULL;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence result = dns_c_ctx_gettkeydhkey(lctx, cfg, &s, &n);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence if (result == ISC_R_NOTFOUND)
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence return ISC_R_SUCCESS;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence RETERR(dst_key_fromfile(s, n, DNS_KEYALG_DH, DST_TYPE_PRIVATE,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence mctx, &tkey_dhkey));
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence s = NULL;
b435b1ded3def3159f597953d21dffc1615cb250Brian Wellington RETERR(dns_c_ctx_gettkeydomain(lctx, cfg, &s));
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence tkey_domain = (dns_name_t *) isc_mem_get(mctx, sizeof(dns_name_t));
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson if (tkey_domain == NULL)
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence return (ISC_R_NOMEMORY);
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson dns_name_init(tkey_domain, NULL);
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson isc_buffer_init(&b, s, strlen(s), ISC_BUFFERTYPE_TEXT);
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson isc_buffer_add(&b, strlen(s));
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson namebuf = NULL;
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson RETERR(isc_buffer_allocate(mctx, &namebuf, 1024,
8b3fb4bded905d65153678f48a006eed5c13b27eAndreas Gustafsson ISC_BUFFERTYPE_BINARY));
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson RETERR(dns_name_fromtext(tkey_domain, &b, dns_rootname, ISC_FALSE,
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson namebuf));
9719cb1205c4b30b46a98b4be7475e96befbea2bAndreas Gustafsson
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson return (ISC_R_SUCCESS);
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson
9e560b59a722d06a62b5aed761e71fec72638a7cBrian Wellington failure:
dfceef7e68b56f6970dd2e8eea9980ad16bcc653Brian Wellington if (tkey_dhkey != NULL) {
9e560b59a722d06a62b5aed761e71fec72638a7cBrian Wellington dst_key_free(tkey_dhkey);
5455f30a7532738d750252c00e649890c694ee30Brian Wellington tkey_dhkey = NULL;
5455f30a7532738d750252c00e649890c694ee30Brian Wellington }
b7ce2258cab8eadbd834de8ca9d0b6f4c71f8c48Brian Wellington if (tkey_domain != NULL) {
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence isc_mem_put(mctx, tkey_domain, sizeof(dns_name_t));
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence tkey_domain = NULL;
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence }
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence if (namebuf != NULL)
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence isc_buffer_free(&namebuf);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence return (result);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence}
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrencestatic isc_result_t
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellingtonadd_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_uint32_t ttl, dns_namelist_t *namelist)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington{
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_result_t result;
8b0c51974b4319076cca6adf6b5e11f98200353fDavid Lawrence isc_region_t r, newr;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdata_t *newrdata = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_name_t *newname = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdatalist_t *newlist = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_t *newset = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_t *tmprdatabuf = NULL, *tmpnamebuf = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_message_gettemprdata(msg, &newrdata));
8b0c51974b4319076cca6adf6b5e11f98200353fDavid Lawrence
8b0c51974b4319076cca6adf6b5e11f98200353fDavid Lawrence dns_rdata_toregion(rdata, &r);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_BUFFERTYPE_BINARY));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_available(tmprdatabuf, &newr);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington memcpy(newr.base, r.base, r.length);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_takebuffer(msg, &tmprdatabuf);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_name_toregion(name, &r);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_message_gettempname(msg, &newname));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_name_init(newname, NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &tmpnamebuf, r.length,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_BUFFERTYPE_BINARY));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_available(tmpnamebuf, &newr);
8b0c51974b4319076cca6adf6b5e11f98200353fDavid Lawrence memcpy(newr.base, r.base, r.length);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_name_fromregion(newname, &newr);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_takebuffer(msg, &tmpnamebuf);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_message_gettemprdatalist(msg, &newlist));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington newlist->rdclass = newrdata->rdclass;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington newlist->type = newrdata->type;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington newlist->ttl = ttl;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LIST_INIT(newlist->rdata);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LIST_APPEND(newlist->rdata, newrdata, link);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_message_gettemprdataset(msg, &newset));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_init(newset);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_rdatalist_tordataset(newlist, newset));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LIST_INIT(newname->list);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LIST_APPEND(newname->list, newset, link);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LIST_APPEND(*namelist, newname, link);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return (ISC_R_SUCCESS);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington failure:
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (newrdata != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_puttemprdata(msg, &newrdata);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (newname != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_puttempname(msg, &newname);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (newlist != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_puttemprdatalist(msg, &newlist);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (newset != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_puttemprdataset(msg, &newset);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return (result);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington}
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellingtonstatic isc_result_t
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellingtonprocess_dhtkey(dns_message_t *msg, dns_name_t *name,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdata_generic_tkey_t *tkeyin,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdata_generic_tkey_t *tkeyout, dns_namelist_t *namelist)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington{
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_result_t result = ISC_R_SUCCESS;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_name_t *keyname, ourname;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_t *keyset;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdata_t keyrdata, ourkeyrdata;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dst_key_t *pubkey = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_t ourkeybuf, ournamein, ournameout, *secret = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_region_t r, ourkeyr;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_uint32_t ourttl;
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington unsigned char keydata[DST_KEY_MAXSIZE];
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington unsigned char namedata[1024];
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_tsigkey_t *tsigkey;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington unsigned int secretsize;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence /* Look for a DH KEY record that will work with ours */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence while (result == ISC_R_SUCCESS) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence keyname = NULL;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence keyset = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_message_findtype(keyname, dns_rdatatype_key, 0,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &keyset);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result == ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_rdataset_first(keyset);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington while (result == ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_current(keyset, &keyrdata);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence pubkey = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_dnssec_keyfromrdata(keyname,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence &keyrdata,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington msg->mctx,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &pubkey);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result != ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_rdataset_next(keyset);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington continue;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (dst_key_alg(pubkey) == DNS_KEYALG_DH) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (dst_key_paramcompare(pubkey,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington tkey_dhkey))
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington found_key = ISC_TRUE;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto got_key;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington else
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington found_incompatible = ISC_TRUE;
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington }
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington dst_key_free(pubkey);
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington result = dns_rdataset_next(keyset);
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington }
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington got_key:
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (!found_key) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (found_incompatible) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington tkeyout->error = dns_tsigerror_badkey;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return ISC_R_SUCCESS;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return DNS_R_FORMERR;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(add_rdata_to_list(msg, keyname, &keyrdata, keyset->ttl,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington namelist));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata),
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_BUFFERTYPE_BINARY);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dst_key_todns(tkey_dhkey, &ourkeybuf));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_used(&ourkeybuf, &ourkeyr);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_in,
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington dns_rdatatype_key, &ourkeyr);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington isc_buffer_init(&ournamein, dst_key_name(tkey_dhkey),
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington strlen(dst_key_name(tkey_dhkey)), ISC_BUFFERTYPE_TEXT);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_add(&ournamein, strlen(dst_key_name(tkey_dhkey)));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_init(&ournameout, namedata, sizeof(namedata),
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_BUFFERTYPE_BINARY);
e19501436a92cd48eba2ff47d90fa49c661ec8d8Brian Wellington dns_name_init(&ourname, NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_name_fromtext(&ourname, &ournamein, dns_rootname, ISC_FALSE,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &ournameout));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ourttl = 0;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#if 0
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington /* Not sure how to do this without a view... */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington db = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_dbtable_find(client->view->dbtable, &ourname, &db);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result == ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_t set;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_fixedname_t foundname;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_init(&set);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_fixedname_init(&foundname);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_db_find(db, &ourname, NULL, dns_rdatatype_key,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington DNS_DBFIND_NOWILD, 0, NULL,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_fixedname_name(&foundname),
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &set, NULL);
35112a392f7baecfdfca9e32c6cf6188ce4f5a1cBrian Wellington if (result == ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ourttl = set.ttl;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rdataset_disassociate(&set);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#endif
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, ourttl,
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington namelist));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dst_secret_size(tkey_dhkey, &secretsize));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &secret, secretsize,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_BUFFERTYPE_BINARY));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dst_computesecret(pubkey, tkey_dhkey, secret);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result != ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_free(&secret);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto failure;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_used(secret, &r);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington tsigkey = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_tsigkey_create(name, &tkeyin->algorithm, r.base, r.length,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence ISC_TRUE, NULL, msg->mctx, &tsigkey);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence isc_buffer_free(&secret);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence if (result == ISC_R_NOTFOUND) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence tkeyout->error = dns_tsigerror_badalg;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dst_key_free(pubkey);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return (ISC_R_SUCCESS);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result != ISC_R_SUCCESS) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dst_key_free(pubkey);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto failure;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington /* This key is good for a long time */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence tkeyout->inception = 0;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence tkeyout->expire = 0x7FFFFFFF;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence return (ISC_R_SUCCESS);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence failure:
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence if (!ISC_LIST_EMPTY(*namelist)) {
504f7802d4c9b43db4820f496c4d00e078effa18David Lawrence dns_name_t *tname = ISC_LIST_HEAD(*namelist);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence while (tname != NULL) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_name_t *next = ISC_LIST_NEXT(tname, link);
504f7802d4c9b43db4820f496c4d00e078effa18David Lawrence dns_rdataset_t *tset;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence ISC_LIST_UNLINK(*namelist, tname, link);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence tset = ISC_LIST_HEAD(tname->list);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_message_puttemprdataset(msg, &tset);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_message_puttempname(msg, &tname);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence tname = next;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence return (result);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence}
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrencestatic isc_result_t
73a691c373488e4f70387a62462cd8ce0d991705David Lawrenceprocess_deletetkey(dns_message_t *msg, dns_name_t *name,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_rdata_generic_tkey_t *tkeyin,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_rdata_generic_tkey_t *tkeyout,
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_namelist_t *namelist)
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence{
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence isc_result_t result;
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence dns_tsigkey_t *tsigkey = NULL;
4716e94840921878b26e493576f84afe4fe08752Mark Andrews
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington /* Unused variables */
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington msg = msg;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout = tkeyout;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington namelist = namelist;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (result != ISC_R_SUCCESS)
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout->error = dns_tsigerror_badname;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington /*
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington * Only allow a delete if the message is signed by the key to
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington * be deleted or a key with the same creator.
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington */
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (msg->tsigkey == NULL)
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington return (DNS_R_REFUSED);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (!dns_name_equal(&msg->tsigkey->name, name)) {
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence if (msg->tsigkey->creator == NULL ||
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington tsigkey->creator == NULL ||
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington !dst_key_compare(msg->tsigkey->creator, tsigkey->creator))
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington return (DNS_R_REFUSED);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson /* If tsigkey->creator is NULL, log a warning here... */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson /*
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * Set the key to be deleted when no references are left. If the key
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * was not generated with TKEY and is in the config file, it may be
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * reloaded later.
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_tsigkey_setdeleted(tsigkey);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence /* Release the reference */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_tsigkey_free(&tsigkey);
6dc32b43da2c7af5bf460a45a17d03226c162c91Michael Sawyer
94b50bce2b5deeac93734457d5474736d7b76af1Michael Sawyer return (result);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence}
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrenceisc_result_t
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrencedns_tkey_processquery(dns_message_t *msg) {
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence isc_result_t result = ISC_R_SUCCESS;
5096958739769958dd7a6b69356bf41260033873David Lawrence dns_rdata_generic_tkey_t tkeyin, tkeyout;
299b673e8ed4f3d6239c61375c2376bfb63c7c01Brian Wellington dns_name_t *qname, *name, *keyname;
5096958739769958dd7a6b69356bf41260033873David Lawrence dns_rdataset_t *tkeyset;
5096958739769958dd7a6b69356bf41260033873David Lawrence dns_rdata_t tkeyrdata, *rdata = NULL;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence isc_buffer_t *dynbuf = NULL;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_namelist_t namelist;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence /* Need to do this to determine if this should be freed later */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence memset(&tkeyin, 0, sizeof(dns_rdata_generic_tkey_t));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence /* Interpret the question section */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence INSIST(result == DNS_R_SUCCESS);
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence qname = NULL;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_message_currentname(msg, DNS_SECTION_QUESTION, &qname);
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence /* Look for a TKEY record that matches the question */
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence tkeyset = NULL;
94b50bce2b5deeac93734457d5474736d7b76af1Michael Sawyer name = NULL;
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname,
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence dns_rdatatype_tkey, 0, &name, &tkeyset);
3734f3f1bad4160cdd7563bc4801bca7e82f8abdDavid Lawrence if (result != ISC_R_SUCCESS) {
3734f3f1bad4160cdd7563bc4801bca7e82f8abdDavid Lawrence result = DNS_R_FORMERR;
3734f3f1bad4160cdd7563bc4801bca7e82f8abdDavid Lawrence goto failure;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence result = dns_rdataset_first(tkeyset);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence if (result != ISC_R_SUCCESS) {
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence result = DNS_R_FORMERR;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence goto failure;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_rdataset_current(tkeyset, &tkeyrdata);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence RETERR(dns_rdata_tostruct(&tkeyrdata, &tkeyin, msg->mctx));
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence if (tkeyin.error != dns_rcode_noerror) {
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence result = DNS_R_FORMERR;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence goto failure;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence ISC_LIST_INIT(namelist);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
f96b41064bcd427d8125a096fd646c1f068d8ed7David Lawrence tkeyout.common.rdclass = tkeyin.common.rdclass;
f96b41064bcd427d8125a096fd646c1f068d8ed7David Lawrence tkeyout.common.rdtype = tkeyin.common.rdtype;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LINK_INIT(&tkeyout.common, link);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence tkeyout.mctx = msg->mctx;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_init(&tkeyout.algorithm, NULL);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington RETERR(dns_name_dup(&tkeyin.algorithm, msg->mctx, &tkeyout.algorithm));
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout.inception = tkeyout.expire = 0;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout.mode = tkeyin.mode;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout.error = 0;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout.keylen = tkeyout.otherlen = 0;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington tkeyout.key = tkeyout.other = NULL;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington /*
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington * A delete operation must have a fully specified key name. If not,
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington * we do the following:
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence * if qname is a subdomain of defaultdomain
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence * keyname = qname.
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence * else if (qname != ".")
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington * keyname = qname + defaultdomain
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence * else
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington * keyname = <random hex> + defaultdomain
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington */
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (tkeyin.mode != DNS_TKEYMODE_DELETE) {
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_t prefix;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington isc_buffer_t *buf = NULL;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington unsigned char tdata[64];
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence dns_tsigkey_t *tsigkey = NULL;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence keyname = NULL;
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence result = dns_message_gettempname(msg, &keyname);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_init(keyname, NULL);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_init(&prefix, NULL);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &buf, 256,
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington ISC_BUFFERTYPE_BINARY));
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (!dns_name_equal(qname, dns_rootname)) {
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington unsigned int n = dns_name_countlabels(qname);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_getlabelsequence(qname, 0, n - 1, &prefix);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington }
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington else {
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington static char hexdigits[16] = "0123456789ABCDEF";
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington unsigned char randomtext[32];
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington isc_buffer_t b, b2;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington int i;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
5096958739769958dd7a6b69356bf41260033873David Lawrence isc_buffer_init(&b, randomtext, sizeof(randomtext),
5096958739769958dd7a6b69356bf41260033873David Lawrence ISC_BUFFERTYPE_BINARY);
5096958739769958dd7a6b69356bf41260033873David Lawrence result = dst_random_get(sizeof(randomtext)/2, &b);
5096958739769958dd7a6b69356bf41260033873David Lawrence if (result != ISC_R_SUCCESS) {
5096958739769958dd7a6b69356bf41260033873David Lawrence dns_message_takebuffer(msg, &buf);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto failure;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington }
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington for (i = sizeof(randomtext) - 2; i >= 0; i -= 2) {
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington unsigned char val = randomtext[i/2];
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington randomtext[i] = hexdigits[val >> 4];
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington randomtext[i+1] = hexdigits[val & 0xF];
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence isc_buffer_init(&b, randomtext, sizeof(randomtext),
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence ISC_BUFFERTYPE_TEXT);
5096958739769958dd7a6b69356bf41260033873David Lawrence isc_buffer_init(&b2, tdata, sizeof(tdata),
5096958739769958dd7a6b69356bf41260033873David Lawrence ISC_BUFFERTYPE_BINARY);
5096958739769958dd7a6b69356bf41260033873David Lawrence isc_buffer_add(&b, sizeof(randomtext));
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington result = dns_name_fromtext(&prefix, &b, NULL,
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington ISC_FALSE, &b2);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (result != ISC_R_SUCCESS) {
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_message_takebuffer(msg, &buf);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington goto failure;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington }
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington }
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington result = dns_name_concatenate(&prefix, tkey_domain,
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington keyname, buf);
2f8380972f35efac09603f6ee7373304e5900d5eBrian Wellington dns_message_takebuffer(msg, &buf);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence if (result != ISC_R_SUCCESS)
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence goto failure;
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington result = dns_tsigkey_find(&tsigkey, keyname, NULL);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (result == ISC_R_SUCCESS) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence tkeyout.error = dns_tsigerror_badname;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_tsigkey_free(&tsigkey);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence goto failure_with_tkey;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington else if (result != ISC_R_NOTFOUND)
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence goto failure;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence else
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence keyname = qname;
947295d8868c24f75a858e42b579a271c1d2c3d2David Lawrence
947295d8868c24f75a858e42b579a271c1d2c3d2David Lawrence if (!dns_name_equal(&tkeyin.algorithm, DNS_TSIG_HMACMD5_NAME)) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington tkeyout.error = dns_tsigerror_badkey;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto failure_with_tkey;
947295d8868c24f75a858e42b579a271c1d2c3d2David Lawrence }
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington switch (tkeyin.mode) {
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington case DNS_TKEYMODE_DIFFIEHELLMAN:
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington RETERR(process_dhtkey(msg, keyname, &tkeyin,
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington &tkeyout, &namelist));
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington tkeyout.error = dns_rcode_noerror;
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington break;
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington case DNS_TKEYMODE_DELETE:
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington RETERR(process_deletetkey(msg, keyname, &tkeyin,
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington &tkeyout, &namelist));
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington tkeyout.error = dns_rcode_noerror;
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington break;
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington case DNS_TKEYMODE_SERVERASSIGNED:
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington case DNS_TKEYMODE_GSSAPI:
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence case DNS_TKEYMODE_RESOLVERASSIGNED:
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence result = DNS_R_NOTIMP;
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington goto failure;
5c3efef92647e208dd887afeacec02b9104d1516Brian Wellington default:
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington tkeyout.error = dns_tsigerror_badmode;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson failure_with_tkey:
6dc32b43da2c7af5bf460a45a17d03226c162c91Michael Sawyer dns_rdata_freestruct(&tkeyin);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson RETERR(dns_message_gettemprdata(msg, &rdata));
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 128,
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson ISC_BUFFERTYPE_BINARY));
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson result = dns_rdata_fromstruct(rdata, tkeyout.common.rdclass,
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson tkeyout.common.rdtype, &tkeyout, dynbuf);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson dns_rdata_freestruct(&tkeyout);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson if (result != ISC_R_SUCCESS)
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson goto failure;
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson RETERR(add_rdata_to_list(msg, keyname, rdata, 0, &namelist));
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson isc_buffer_free(&dynbuf);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson RETERR(dns_message_reply(msg, ISC_TRUE));
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson name = ISC_LIST_HEAD(namelist);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson while (name != NULL) {
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson dns_name_t *next = ISC_LIST_NEXT(name, link);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson ISC_LIST_UNLINK(namelist, name, link);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson name = next;
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson }
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence return (ISC_R_SUCCESS);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence failure:
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington if (tkeyin.common.rdtype == dns_rdatatype_tkey)
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_rdata_freestruct(&tkeyin);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence if (rdata != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_message_puttemprdata(msg, &rdata);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson if (dynbuf != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_free(&dynbuf);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence return (result);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington}
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
ff2add63ae297d3c0f925f7479aefc15fd9aec31David Lawrencestatic isc_result_t
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellingtonbuildquery(dns_message_t *msg, dns_name_t *name,
ff2add63ae297d3c0f925f7479aefc15fd9aec31David Lawrence dns_rdata_generic_tkey_t *tkey)
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington{
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_t *qname = NULL, *aname = NULL;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_rdataset_t *question = NULL, *tkeyset = NULL;
ff2add63ae297d3c0f925f7479aefc15fd9aec31David Lawrence dns_rdatalist_t *tkeylist = NULL;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington dns_rdata_t *rdata = NULL;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington isc_buffer_t *dynbuf = NULL;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington isc_result_t result;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington REQUIRE(msg != NULL);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington REQUIRE(name != NULL);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington REQUIRE(tkey != NULL);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence msg->id = 10; /* XXX should use isc_random_get */
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence RETERR(dns_message_gettempname(msg, &qname));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington RETERR(dns_message_gettempname(msg, &aname));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence RETERR(dns_message_gettemprdataset(msg, &question));
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_rdataset_init(question);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_rdataset_makequestion(question, dns_rdataclass_in /**/,
dns_rdatatype_tkey);
RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 512,
ISC_BUFFERTYPE_BINARY));
RETERR(dns_message_gettemprdata(msg, &rdata));
RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_in /**/,
dns_rdatatype_tkey, tkey, dynbuf));
dns_message_takebuffer(msg, &dynbuf);
RETERR(dns_message_gettemprdatalist(msg, &tkeylist));
tkeylist->rdclass = dns_rdataclass_in /**/;
tkeylist->type = dns_rdatatype_tkey;
tkeylist->covers = 0;
tkeylist->ttl = 0;
ISC_LIST_INIT(tkeylist->rdata);
ISC_LIST_APPEND(tkeylist->rdata, rdata, link);
RETERR(dns_message_gettemprdataset(msg, &tkeyset));
dns_rdataset_init(tkeyset);
RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset));
dns_name_init(qname, NULL);
dns_name_clone(name, qname);
dns_name_init(aname, NULL);
dns_name_clone(name, aname);
ISC_LIST_APPEND(qname->list, question, link);
ISC_LIST_APPEND(aname->list, tkeyset, link);
dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
return (ISC_R_SUCCESS);
failure:
if (qname != NULL)
dns_message_puttempname(msg, &qname);
if (aname != NULL)
dns_message_puttempname(msg, &aname);
if (question != NULL)
dns_message_puttemprdataset(msg, &question);
if (dynbuf != NULL)
isc_buffer_free(&dynbuf);
return (result);
}
isc_result_t
dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
dns_name_t *algorithm, isc_buffer_t *nonce)
{
dns_rdata_generic_tkey_t tkey;
dns_rdata_t *rdata = NULL;
isc_buffer_t src, *dynbuf = NULL;
isc_region_t r;
dns_name_t *keyname = NULL;
dns_namelist_t namelist;
isc_result_t result;
REQUIRE(msg != NULL);
REQUIRE(key != NULL);
REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
REQUIRE(dst_key_isprivate(key));
REQUIRE(name != NULL);
REQUIRE(algorithm != NULL);
nonce = nonce; /* until the new spec is done */
tkey.common.rdclass = dns_rdataclass_in /**/;
tkey.common.rdtype = dns_rdatatype_tkey;
ISC_LINK_INIT(&tkey.common, link);
tkey.mctx = msg->mctx;
dns_name_init(&tkey.algorithm, NULL);
dns_name_clone(algorithm, &tkey.algorithm);
tkey.inception = tkey.expire = 0;
tkey.mode = DNS_TKEYMODE_DIFFIEHELLMAN;
tkey.error = 0;
tkey.keylen = tkey.otherlen = 0;
tkey.key = tkey.other = NULL;
RETERR(buildquery(msg, name, &tkey));
RETERR(dns_message_gettemprdata(msg, &rdata));
RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024,
ISC_BUFFERTYPE_BINARY));
RETERR(dst_key_todns(key, dynbuf));
isc_buffer_used(dynbuf, &r);
dns_rdata_fromregion(rdata, dns_rdataclass_in,
dns_rdatatype_key, &r);
dns_message_takebuffer(msg, &dynbuf);
RETERR(dns_message_gettempname(msg, &keyname));
isc_buffer_init(&src, dst_key_name(key), strlen(dst_key_name(key)),
ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&src, strlen(dst_key_name(key)));
RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024,
ISC_BUFFERTYPE_BINARY));
dns_name_init(keyname, NULL);
RETERR(dns_name_fromtext(keyname, &src, dns_rootname, ISC_FALSE,
dynbuf));
dns_message_takebuffer(msg, &dynbuf);
ISC_LIST_INIT(namelist);
RETERR(add_rdata_to_list(msg, keyname, rdata, 0, &namelist));
dns_message_addname(msg, ISC_LIST_HEAD(namelist),
DNS_SECTION_ADDITIONAL);
return (ISC_R_SUCCESS);
failure:
if (dynbuf != NULL)
isc_buffer_free(&dynbuf);
return (result);
}
isc_result_t
dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) {
dns_rdata_generic_tkey_t tkey;
REQUIRE(msg != NULL);
REQUIRE(key != NULL);
tkey.common.rdclass = dns_rdataclass_in /**/;
tkey.common.rdtype = dns_rdatatype_tkey;
ISC_LINK_INIT(&tkey.common, link);
tkey.mctx = msg->mctx;
dns_name_init(&tkey.algorithm, NULL);
dns_name_clone(&key->algorithm, &tkey.algorithm);
tkey.inception = tkey.expire = 0;
tkey.mode = DNS_TKEYMODE_DELETE;
tkey.error = 0;
tkey.keylen = tkey.otherlen = 0;
tkey.key = tkey.other = NULL;
return (buildquery(msg, &key->name, &tkey));
}
static isc_result_t
find_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata) {
dns_rdataset_t *tkeyset;
isc_result_t result;
result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
while (result == ISC_R_SUCCESS) {
*name = NULL;
dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, name);
tkeyset = NULL;
result = dns_message_findtype(*name, dns_rdatatype_tkey, 0,
&tkeyset);
if (result == ISC_R_SUCCESS) {
result = dns_rdataset_first(tkeyset);
if (result != ISC_R_SUCCESS)
return (result);
dns_rdataset_current(tkeyset, rdata);
return (ISC_R_SUCCESS);
}
result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL);
}
if (result == ISC_R_NOMORE)
return (ISC_R_NOTFOUND);
return (result);
}
isc_result_t
dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dst_key_t *key, dns_tsigkey_t **outkey)
{
dns_rdata_t qtkeyrdata, rtkeyrdata;
dns_name_t keyname, *tkeyname, *theirkeyname, *ourkeyname, *tempname;
dns_rdataset_t *theirkeyset = NULL, *ourkeyset = NULL;
dns_rdata_t theirkeyrdata;
dst_key_t *theirkey;
dns_tsigkey_t *tsigkey;
dns_rdata_generic_tkey_t qtkey, rtkey;
unsigned char keydata[1024];
unsigned int secretsize;
isc_buffer_t keysrc, keybuf, *secret = NULL;
isc_region_t r;
isc_result_t result;
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
REQUIRE(key != NULL);
REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
REQUIRE(dst_key_isprivate(key));
if (outkey != NULL)
REQUIRE(*outkey == NULL);
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata));
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, qmsg->mctx));
if (rtkey.error != dns_rcode_noerror ||
rtkey.mode != DNS_TKEYMODE_DIFFIEHELLMAN ||
rtkey.mode != qtkey.mode ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
rmsg->rcode != dns_rcode_noerror)
{
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&rtkey);
goto failure;
}
isc_buffer_init(&keysrc, dst_key_name(key), strlen(dst_key_name(key)),
ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&keysrc, strlen(dst_key_name(key)));
isc_buffer_init(&keybuf, keydata, sizeof(keydata),
ISC_BUFFERTYPE_BINARY);
dns_name_init(&keyname, NULL);
RETERR(dns_name_fromtext(&keyname, &keysrc, dns_rootname,
ISC_FALSE, &keybuf));
ourkeyname = NULL;
ourkeyset = NULL;
RETERR(dns_message_findname(rmsg, DNS_SECTION_ADDITIONAL, &keyname,
dns_rdatatype_key, 0, &ourkeyname,
&ourkeyset));
result = dns_message_firstname(rmsg, DNS_SECTION_ADDITIONAL);
while (result == ISC_R_SUCCESS) {
theirkeyname = NULL;
dns_message_currentname(rmsg, DNS_SECTION_ADDITIONAL,
&theirkeyname);
if (dns_name_equal(theirkeyname, ourkeyname))
goto next;
theirkeyset = NULL;
result = dns_message_findtype(theirkeyname, dns_rdatatype_key,
0, &theirkeyset);
if (result == ISC_R_SUCCESS) {
RETERR(dns_rdataset_first(theirkeyset));
break;
}
next:
result = dns_message_nextname(rmsg, DNS_SECTION_ADDITIONAL);
}
if (theirkeyset == NULL) {
result = ISC_R_NOTFOUND;
goto failure;
}
dns_rdataset_current(theirkeyset, &theirkeyrdata);
theirkey = NULL;
RETERR(dns_dnssec_keyfromrdata(theirkeyname, &theirkeyrdata,
rmsg->mctx, &theirkey));
RETERR(dst_secret_size(key, &secretsize));
RETERR(isc_buffer_allocate(rmsg->mctx, &secret, secretsize,
ISC_BUFFERTYPE_BINARY));
result = dst_computesecret(theirkey, key, secret);
if (result != ISC_R_SUCCESS)
goto failure;
isc_buffer_used(secret, &r);
tsigkey = NULL;
result = dns_tsigkey_create(tkeyname, &rtkey.algorithm,
r.base, r.length, ISC_TRUE,
NULL, rmsg->mctx, &tsigkey);
isc_buffer_free(&secret);
if (outkey != NULL)
RETERR(dns_tsigkey_find(outkey, tkeyname, &rtkey.algorithm));
return (result);
failure:
if (secret != NULL)
isc_buffer_free(&secret);
return (result);
}
isc_result_t
dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg) {
dns_rdata_t qtkeyrdata, rtkeyrdata;
dns_name_t *tkeyname, *tempname;
dns_rdata_generic_tkey_t qtkey, rtkey;
dns_tsigkey_t *tsigkey = NULL;
isc_result_t result;
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata));
RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, qmsg->mctx));
if (rtkey.error != dns_rcode_noerror ||
rtkey.mode != DNS_TKEYMODE_DELETE ||
rtkey.mode != qtkey.mode ||
!dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
rmsg->rcode != dns_rcode_noerror)
{
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&rtkey);
goto failure;
}
RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm));
/* Mark the key as deleted */
dns_tsigkey_setdeleted(tsigkey);
/* Release the reference */
dns_tsigkey_free(&tsigkey);
failure:
return (result);
}