tkey.c revision 1c1d1a5a96624c7e6382c97f8d78765e05c246a1
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington/*
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * Copyright (C) 1999 Internet Software Consortium.
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington *
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * Permission to use, copy, modify, and distribute this software for any
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * purpose with or without fee is hereby granted, provided that the above
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * copyright notice and this permission notice appear in all copies.
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington *
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * SOFTWARE.
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington/*
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington * $Id: tkey.c,v 1.7 1999/10/28 20:00:04 bwelling Exp $
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * Principal Author: Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <config.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <stdlib.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <string.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/assertions.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/buffer.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/error.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/list.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/log.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/net.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/result.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/rwlock.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/stdtime.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <isc/types.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/dnssec.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/keyvalues.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/name.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/message.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/rdata.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/rdatalist.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/rdataset.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/rdatastruct.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/tkey.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/tsig.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dns/confctx.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dst/dst.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#include <dst/result.h>
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#define dns_tsigerror_badalg 21
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington#define TKEY_RANDOM_AMOUNT 16
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
ff936a56ea2ec850748f82df46e67a8a614af49bBob Halley#define RETERR(x) do { \
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = (x); \
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS) \
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure; \
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington } while (0)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic dst_key_t *tkey_dhkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic dns_name_t *tkey_domain = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonisc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtondns_tkey_init(isc_log_t *lctx, dns_c_ctx_t *cfg, isc_mem_t *mctx) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington char *s;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington int n;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t b, *namebuf;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RUNTIME_CHECK(tkey_domain == NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RUNTIME_CHECK(tkey_dhkey == NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(lctx != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(cfg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(mctx != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington s = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_c_ctx_gettkeydhkey(lctx, cfg, &s, &n);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_NOTFOUND)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return ISC_R_SUCCESS;
ff936a56ea2ec850748f82df46e67a8a614af49bBob Halley RETERR(dst_key_fromfile(s, n, DNS_KEYALG_DH, DST_TYPE_PRIVATE,
ff936a56ea2ec850748f82df46e67a8a614af49bBob Halley mctx, &tkey_dhkey));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington s = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_c_ctx_gettkeydomain(lctx, cfg, &s));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey_domain = (dns_name_t *) isc_mem_get(mctx, sizeof(dns_name_t));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (tkey_domain == NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_NOMEMORY);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(tkey_domain, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&b, s, strlen(s), ISC_BUFFERTYPE_TEXT);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_add(&b, strlen(s));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington namebuf = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(mctx, &namebuf, 1024,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_name_fromtext(tkey_domain, &b, dns_rootname, ISC_FALSE,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington namebuf));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (tkey_dhkey != NULL) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dst_key_free(tkey_dhkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey_dhkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (tkey_domain != NULL) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_mem_put(mctx, tkey_domain, sizeof(dns_name_t));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey_domain = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (namebuf != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_free(&namebuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic isc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonadd_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_uint32_t ttl, dns_namelist_t *namelist)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington{
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_region_t r, newr;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t *newrdata = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *newname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdatalist_t *newlist = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *newset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t *tmprdatabuf = NULL, *tmpnamebuf = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
ff936a56ea2ec850748f82df46e67a8a614af49bBob Halley RETERR(dns_message_gettemprdata(msg, &newrdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_toregion(rdata, &r);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_available(tmprdatabuf, &newr);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington memcpy(newr.base, r.base, r.length);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &tmprdatabuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_toregion(name, &r);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettempname(msg, &newname));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(newname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &tmpnamebuf, r.length,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_available(tmpnamebuf, &newr);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington memcpy(newr.base, r.base, r.length);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_fromregion(newname, &newr);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &tmpnamebuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdatalist(msg, &newlist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington newlist->rdclass = newrdata->rdclass;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington newlist->type = newrdata->type;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington newlist->ttl = ttl;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_INIT(newlist->rdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_APPEND(newlist->rdata, newrdata, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdataset(msg, &newset));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_init(newset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdatalist_tordataset(newlist, newset));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_INIT(newname->list);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_APPEND(newname->list, newset, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_APPEND(*namelist, newname, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (newrdata != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttemprdata(msg, &newrdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (newname != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttempname(msg, &newname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (newlist != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttemprdatalist(msg, &newlist);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (newset != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttemprdataset(msg, &newset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellingtonstatic isc_result_t
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellingtoncompute_secret(isc_buffer_t *shared, isc_region_t *randomness,
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_t *secret)
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington{
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington dst_context_t ctx;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_result_t result;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_region_t r;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_used(shared, &r);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_digest(DST_SIGMODE_INIT, DST_DIGEST_MD5, &ctx, NULL, NULL));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_digest(DST_SIGMODE_UPDATE, DST_DIGEST_MD5, &ctx, &r, NULL));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington if (randomness->length != 0)
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_digest(DST_SIGMODE_UPDATE, DST_DIGEST_MD5,
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington &ctx, randomness, secret));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_digest(DST_SIGMODE_FINAL, DST_DIGEST_MD5, &ctx, NULL,
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington secret));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington failure:
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington return result;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington}
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic isc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonprocess_dhtkey(dns_message_t *msg, dns_name_t *name,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t *tkeyin,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t *tkeyout, dns_namelist_t *namelist)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington{
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result = ISC_R_SUCCESS;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *keyname, ourname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *keyset;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t keyrdata, ourkeyrdata;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dst_key_t *pubkey = NULL;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_t ourkeybuf, ournamein, ournameout, *shared = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_region_t r, ourkeyr;
ff936a56ea2ec850748f82df46e67a8a614af49bBob Halley isc_uint32_t ourttl;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington unsigned char keydata[DST_KEY_MAXSIZE];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington unsigned char namedata[1024];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_t *tsigkey;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington unsigned int sharedsize;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_t randombuf, secret;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington unsigned char *randomdata = NULL, secretdata[TKEY_RANDOM_AMOUNT];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Look for a DH KEY record that will work with ours */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington while (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington keyname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington keyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_findtype(keyname, dns_rdatatype_key, 0,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &keyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_rdataset_first(keyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington while (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_current(keyset, &keyrdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington pubkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_dnssec_keyfromrdata(keyname,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &keyrdata,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington msg->mctx,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &pubkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_rdataset_next(keyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington continue;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (dst_key_alg(pubkey) == DNS_KEYALG_DH) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (dst_key_paramcompare(pubkey,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey_dhkey))
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington found_key = ISC_TRUE;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto got_key;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington else
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington found_incompatible = ISC_TRUE;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dst_key_free(pubkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_rdataset_next(keyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington got_key:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (!found_key) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (found_incompatible) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout->error = dns_tsigerror_badkey;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington return (DNS_R_FORMERR);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(add_rdata_to_list(msg, keyname, &keyrdata, keyset->ttl,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington namelist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dst_key_todns(tkey_dhkey, &ourkeybuf));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_used(&ourkeybuf, &ourkeyr);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_in,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdatatype_key, &ourkeyr);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&ournamein, dst_key_name(tkey_dhkey),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington strlen(dst_key_name(tkey_dhkey)), ISC_BUFFERTYPE_TEXT);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_add(&ournamein, strlen(dst_key_name(tkey_dhkey)));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&ournameout, namedata, sizeof(namedata),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(&ourname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_name_fromtext(&ourname, &ournamein, dns_rootname, ISC_FALSE,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &ournameout));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ourttl = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#if 0
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Not sure how to do this without a view... */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington db = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_dbtable_find(client->view->dbtable, &ourname, &db);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t set;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_fixedname_t foundname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_init(&set);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_fixedname_init(&foundname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_db_find(db, &ourname, NULL, dns_rdatatype_key,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington DNS_DBFIND_NOWILD, 0, NULL,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_fixedname_name(&foundname),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &set, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ourttl = set.ttl;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_disassociate(&set);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington#endif
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, ourttl,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington namelist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_secret_size(tkey_dhkey, &sharedsize));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &shared, sharedsize,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_computesecret(pubkey, tkey_dhkey, shared));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_init(&secret, secretdata, sizeof(secretdata),
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington ISC_BUFFERTYPE_BINARY);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington randomdata = isc_mem_get(tkeyout->mctx, TKEY_RANDOM_AMOUNT);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington if (randomdata == NULL) {
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington result = ISC_R_NOMEMORY;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_init(&randombuf, randomdata, TKEY_RANDOM_AMOUNT,
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington ISC_BUFFERTYPE_BINARY);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_random_get(TKEY_RANDOM_AMOUNT, &randombuf));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_used(&randombuf, &r);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(compute_secret(shared, &r, &secret));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
894612819061ccc7f75b5cb4882371789f9cb27aBrian Wellington dst_key_free(pubkey);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_used(&secret, &r);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tsigkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_tsigkey_create(name, &tkeyin->algorithm, r.base, r.length,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_TRUE, NULL, msg->mctx, &tsigkey);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_free(&shared);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington shared = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_NOTFOUND) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout->error = dns_tsigerror_badalg;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
894612819061ccc7f75b5cb4882371789f9cb27aBrian Wellington if (result != ISC_R_SUCCESS)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* This key is good for a long time */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout->inception = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout->expire = 0x7FFFFFFF;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington tkeyout->key = randomdata;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington tkeyout->keylen = TKEY_RANDOM_AMOUNT;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (!ISC_LIST_EMPTY(*namelist)) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *tname = ISC_LIST_HEAD(*namelist);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington while (tname != NULL) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *next = ISC_LIST_NEXT(tname, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *tset;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_UNLINK(*namelist, tname, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tset = ISC_LIST_HEAD(tname->list);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttemprdataset(msg, &tset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttempname(msg, &tname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tname = next;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington if (shared != NULL)
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_free(&shared);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic isc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonprocess_deletetkey(dns_message_t *msg, dns_name_t *name,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t *tkeyin,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t *tkeyout,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_namelist_t *namelist)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington{
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_t *tsigkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Unused variables */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington msg = msg;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout = tkeyout;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington namelist = namelist;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout->error = dns_tsigerror_badname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /*
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * Only allow a delete if the message is signed by the key to
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * be deleted or a key with the same creator.
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (msg->tsigkey == NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (DNS_R_REFUSED);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (!dns_name_equal(&msg->tsigkey->name, name)) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (msg->tsigkey->creator == NULL ||
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tsigkey->creator == NULL ||
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington !dst_key_compare(msg->tsigkey->creator, tsigkey->creator))
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (DNS_R_REFUSED);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* If tsigkey->creator is NULL, log a warning here... */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /*
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * Set the key to be deleted when no references are left. If the key
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * was not generated with TKEY and is in the config file, it may be
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * reloaded later.
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_setdeleted(tsigkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Release the reference */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_free(&tsigkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonisc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtondns_tkey_processquery(dns_message_t *msg) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result = ISC_R_SUCCESS;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t tkeyin, tkeyout;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *qname, *name, *keyname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *tkeyset;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t tkeyrdata, *rdata = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t *dynbuf = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_namelist_t namelist;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Need to do this to determine if this should be freed later */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington memset(&tkeyin, 0, sizeof(dns_rdata_generic_tkey_t));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Interpret the question section */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington INSIST(result == DNS_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington qname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_currentname(msg, DNS_SECTION_QUESTION, &qname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Look for a TKEY record that matches the question */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington name = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdatatype_tkey, 0, &name, &tkeyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = DNS_R_FORMERR;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_rdataset_first(tkeyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = DNS_R_FORMERR;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_current(tkeyset, &tkeyrdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdata_tostruct(&tkeyrdata, &tkeyin, msg->mctx));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (tkeyin.error != dns_rcode_noerror) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = DNS_R_FORMERR;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_INIT(namelist);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.common.rdclass = tkeyin.common.rdclass;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.common.rdtype = tkeyin.common.rdtype;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LINK_INIT(&tkeyout.common, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.mctx = msg->mctx;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(&tkeyout.algorithm, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_name_dup(&tkeyin.algorithm, msg->mctx, &tkeyout.algorithm));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.inception = tkeyout.expire = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.mode = tkeyin.mode;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.error = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.keylen = tkeyout.otherlen = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.key = tkeyout.other = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /*
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * A delete operation must have a fully specified key name. If not,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * we do the following:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * if qname is a subdomain of defaultdomain
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * keyname = qname.
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * else if (qname != ".")
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * keyname = qname + defaultdomain
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * else
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington * keyname = <random hex> + defaultdomain
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (tkeyin.mode != DNS_TKEYMODE_DELETE) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t prefix;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t *buf = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington unsigned char tdata[64];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_t *tsigkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington keyname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_gettempname(msg, &keyname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(keyname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(&prefix, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &buf, 256,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (!dns_name_equal(qname, dns_rootname)) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington unsigned int n = dns_name_countlabels(qname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_getlabelsequence(qname, 0, n - 1, &prefix);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington else {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington static char hexdigits[16] = "0123456789ABCDEF";
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington unsigned char randomtext[32];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t b, b2;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington int i;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&b, randomtext, sizeof(randomtext),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dst_random_get(sizeof(randomtext)/2, &b);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &buf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington for (i = sizeof(randomtext) - 2; i >= 0; i -= 2) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington unsigned char val = randomtext[i/2];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington randomtext[i] = hexdigits[val >> 4];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington randomtext[i+1] = hexdigits[val & 0xF];
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&b, randomtext, sizeof(randomtext),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_TEXT);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&b2, tdata, sizeof(tdata),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_add(&b, sizeof(randomtext));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_name_fromtext(&prefix, &b, NULL,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_FALSE, &b2);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &buf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_name_concatenate(&prefix, tkey_domain,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington keyname, buf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &buf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_tsigkey_find(&tsigkey, keyname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.error = dns_tsigerror_badname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_free(&tsigkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure_with_tkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington else if (result != ISC_R_NOTFOUND)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington else
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington keyname = qname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (!dns_name_equal(&tkeyin.algorithm, DNS_TSIG_HMACMD5_NAME)) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.error = dns_tsigerror_badkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure_with_tkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington switch (tkeyin.mode) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington case DNS_TKEYMODE_DIFFIEHELLMAN:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(process_dhtkey(msg, keyname, &tkeyin,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &tkeyout, &namelist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.error = dns_rcode_noerror;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington break;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington case DNS_TKEYMODE_DELETE:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(process_deletetkey(msg, keyname, &tkeyin,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &tkeyout, &namelist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.error = dns_rcode_noerror;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington break;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington case DNS_TKEYMODE_SERVERASSIGNED:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington case DNS_TKEYMODE_GSSAPI:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington case DNS_TKEYMODE_RESOLVERASSIGNED:
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington result = DNS_R_NOTIMP;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington default:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.error = dns_tsigerror_badmode;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure_with_tkey:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_freestruct(&tkeyin);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdata(msg, &rdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 128,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_rdata_fromstruct(rdata, tkeyout.common.rdclass,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyout.common.rdtype, &tkeyout, dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_freestruct(&tkeyout);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(add_rdata_to_list(msg, keyname, rdata, 0, &namelist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_free(&dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_reply(msg, ISC_TRUE));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington name = ISC_LIST_HEAD(namelist);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington while (name != NULL) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *next = ISC_LIST_NEXT(name, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_UNLINK(namelist, name, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington name = next;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (tkeyin.common.rdtype == dns_rdatatype_tkey)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_freestruct(&tkeyin);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (rdata != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttemprdata(msg, &rdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (dynbuf != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_free(&dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic isc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonbuildquery(dns_message_t *msg, dns_name_t *name,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t *tkey)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington{
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *qname = NULL, *aname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *question = NULL, *tkeyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdatalist_t *tkeylist = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t *rdata = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t *dynbuf = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(msg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(name != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(tkey != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington msg->id = 10; /* XXX should use isc_random_get */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettempname(msg, &qname));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettempname(msg, &aname));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdataset(msg, &question));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_init(question);
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington dns_rdataset_makequestion(question, dns_rdataclass_in /**/,
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington dns_rdatatype_tkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 512,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdata(msg, &rdata));
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_in /**/,
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington dns_rdatatype_tkey, tkey, dynbuf));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdatalist(msg, &tkeylist));
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington tkeylist->rdclass = dns_rdataclass_in /**/;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeylist->type = dns_rdatatype_tkey;
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington tkeylist->covers = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeylist->ttl = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_INIT(tkeylist->rdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_APPEND(tkeylist->rdata, rdata, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdataset(msg, &tkeyset));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_init(tkeyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(qname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_clone(name, qname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(aname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_clone(name, aname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_APPEND(qname->list, question, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_APPEND(aname->list, tkeyset, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (qname != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttempname(msg, &qname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (aname != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttempname(msg, &aname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (question != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_puttemprdataset(msg, &question);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (dynbuf != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_free(&dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonisc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtondns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *algorithm, isc_buffer_t *nonce)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington{
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t tkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t *rdata = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_t src, *dynbuf = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_region_t r;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *keyname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_namelist_t namelist;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(msg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(key != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(dst_key_isprivate(key));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(name != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(algorithm != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington nonce = nonce; /* until the new spec is done */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington tkey.common.rdclass = dns_rdataclass_in /**/;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.common.rdtype = dns_rdatatype_tkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LINK_INIT(&tkey.common, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.mctx = msg->mctx;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(&tkey.algorithm, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_clone(algorithm, &tkey.algorithm);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.inception = tkey.expire = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.mode = DNS_TKEYMODE_DIFFIEHELLMAN;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.error = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.keylen = tkey.otherlen = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.key = tkey.other = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(buildquery(msg, name, &tkey));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettemprdata(msg, &rdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dst_key_todns(key, dynbuf));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_used(dynbuf, &r);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_fromregion(rdata, dns_rdataclass_in,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdatatype_key, &r);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_gettempname(msg, &keyname));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&src, dst_key_name(key), strlen(dst_key_name(key)),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_TEXT);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_add(&src, strlen(dst_key_name(key)));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(keyname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_name_fromtext(keyname, &src, dns_rootname, ISC_FALSE,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dynbuf));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_takebuffer(msg, &dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LIST_INIT(namelist);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(add_rdata_to_list(msg, keyname, rdata, 0, &namelist));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_addname(msg, ISC_LIST_HEAD(namelist),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (dynbuf != NULL)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_free(&dynbuf);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonisc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtondns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t tkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(msg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(key != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington tkey.common.rdclass = dns_rdataclass_in /**/;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.common.rdtype = dns_rdatatype_tkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_LINK_INIT(&tkey.common, link);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.mctx = msg->mctx;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(&tkey.algorithm, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_clone(&key->algorithm, &tkey.algorithm);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.inception = tkey.expire = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.mode = DNS_TKEYMODE_DELETE;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.error = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.keylen = tkey.otherlen = 0;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkey.key = tkey.other = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (buildquery(msg, &key->name, &tkey));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonstatic isc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonfind_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *tkeyset;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington while (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington *name = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, name);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tkeyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_findtype(*name, dns_rdatatype_tkey, 0,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &tkeyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_rdataset_first(tkeyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result != ISC_R_SUCCESS)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_current(tkeyset, rdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_SUCCESS);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_NOMORE)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (ISC_R_NOTFOUND);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonisc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtondns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington dst_key_t *key, dns_tsigkey_t **outkey)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington{
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t qtkeyrdata, rtkeyrdata;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t keyname, *tkeyname, *theirkeyname, *ourkeyname, *tempname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_t *theirkeyset = NULL, *ourkeyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t theirkeyrdata;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dst_key_t *theirkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_t *tsigkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t qtkey, rtkey;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington unsigned char keydata[1024], secretdata[16];
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington unsigned int sharedsize;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_t keysrc, keybuf, *shared = NULL, secret;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_region_t r;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(qmsg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(rmsg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(key != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(dst_key_isprivate(key));
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington if (outkey != NULL)
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington REQUIRE(*outkey == NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, qmsg->mctx));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (rtkey.error != dns_rcode_noerror ||
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington rtkey.mode != DNS_TKEYMODE_DIFFIEHELLMAN ||
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington rtkey.mode != qtkey.mode ||
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington rmsg->rcode != dns_rcode_noerror)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington {
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington result = DNS_R_INVALIDTKEY;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_freestruct(&rtkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&keysrc, dst_key_name(key), strlen(dst_key_name(key)),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_TEXT);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_add(&keysrc, strlen(dst_key_name(key)));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_buffer_init(&keybuf, keydata, sizeof(keydata),
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_init(&keyname, NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_name_fromtext(&keyname, &keysrc, dns_rootname,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_FALSE, &keybuf));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ourkeyname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ourkeyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_message_findname(rmsg, DNS_SECTION_ADDITIONAL, &keyname,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdatatype_key, 0, &ourkeyname,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &ourkeyset));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_firstname(rmsg, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington while (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington theirkeyname = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_message_currentname(rmsg, DNS_SECTION_ADDITIONAL,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington &theirkeyname);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (dns_name_equal(theirkeyname, ourkeyname))
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto next;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington theirkeyset = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_findtype(theirkeyname, dns_rdatatype_key,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington 0, &theirkeyset);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (result == ISC_R_SUCCESS) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdataset_first(theirkeyset));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington break;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington next:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_message_nextname(rmsg, DNS_SECTION_ADDITIONAL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (theirkeyset == NULL) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = ISC_R_NOTFOUND;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdataset_current(theirkeyset, &theirkeyrdata);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington theirkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_dnssec_keyfromrdata(theirkeyname, &theirkeyrdata,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington rmsg->mctx, &theirkey));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_secret_size(key, &sharedsize));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(isc_buffer_allocate(rmsg->mctx, &shared, sharedsize,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington ISC_BUFFERTYPE_BINARY));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(dst_computesecret(theirkey, key, shared));
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_init(&secret, secretdata, sizeof(secretdata),
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington ISC_BUFFERTYPE_BINARY);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington r.base = rtkey.key;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington r.length = rtkey.keylen;
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington RETERR(compute_secret(shared, &r, &secret));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_used(&secret, &r);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington tsigkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington result = dns_tsigkey_create(tkeyname, &rtkey.algorithm,
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington r.base, r.length, ISC_TRUE,
e552b980379e3a7ffce1411a939c62e27f953133Brian Wellington NULL, rmsg->mctx, outkey);
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_free(&shared);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington if (shared != NULL)
1c1d1a5a96624c7e6382c97f8d78765e05c246a1Brian Wellington isc_buffer_free(&shared);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtonisc_result_t
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellingtondns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg) {
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_t qtkeyrdata, rtkeyrdata;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_name_t *tkeyname, *tempname;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_generic_tkey_t qtkey, rtkey;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_t *tsigkey = NULL;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington isc_result_t result;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(qmsg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington REQUIRE(rmsg != NULL);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, qmsg->mctx));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington if (rtkey.error != dns_rcode_noerror ||
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington rtkey.mode != DNS_TKEYMODE_DELETE ||
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington rtkey.mode != qtkey.mode ||
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
f879d3ee27d172ed7913bc0d6c36c610a3e48329Brian Wellington rmsg->rcode != dns_rcode_noerror)
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington {
84ac4c606462387e8287cd60dc9bf86d736f9425Brian Wellington result = DNS_R_INVALIDTKEY;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_rdata_freestruct(&rtkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington goto failure;
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington }
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm));
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Mark the key as deleted */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_setdeleted(tsigkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington /* Release the reference */
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington dns_tsigkey_free(&tsigkey);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington failure:
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington return (result);
d864d899d729b9d84ba6c0b5511023aeab215ea1Brian Wellington}