tkey.c revision 7d86ce8dfc42d4122c95bde3935bda6d08df5a84
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews * Copyright (C) 1999 Internet Software Consortium.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * SOFTWARE.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
f8aae502686e2448c48f56697c212a50e2a1cbaeAndreas Gustafsson/*
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff * $Id: tkey.c,v 1.20 2000/01/24 20:19:51 bwelling Exp $
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff * Principal Author: Brian Wellington
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff */
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
3761c433912beabe43abeed2c3513b6201c59f64Mark Andrews#include <config.h>
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <stdlib.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <string.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews#include <isc/assertions.h>
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews#include <isc/buffer.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <isc/error.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/list.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/log.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/mem.h>
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#include <isc/net.h>
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#include <isc/result.h>
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews#include <isc/rwlock.h>
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#include <isc/stdtime.h>
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#include <isc/types.h>
c1e7aff941dbf40090fec49300e728ad017d4f0cMark Andrews
4fd3e3482c7e4ce01e2cf28f13e0152c8e50d746Mark Andrews#include <dns/dnssec.h>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#include <dns/keyvalues.h>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#include <dns/name.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <dns/message.h>
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews#include <dns/rdata.h>
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews#include <dns/rdatalist.h>
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews#include <dns/rdataset.h>
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews#include <dns/rdatastruct.h>
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews#include <dns/tkey.h>
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews#include <dns/tsig.h>
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson#include <dns/confctx.h>
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson#include <dst/dst.h>
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson#include <dst/result.h>
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson#define TKEY_RANDOM_AMOUNT 16
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson#define RETERR(x) do { \
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson result = (x); \
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (result != ISC_R_SUCCESS) \
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson goto failure; \
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson } while (0)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsisc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_tkeyctx_create(isc_mem_t *mctx, dns_tkey_ctx_t **tctx) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(mctx != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(tctx != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(*tctx == NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *tctx = isc_mem_get(mctx, sizeof(dns_tkey_ctx_t));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (*tctx == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOMEMORY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (*tctx)->mctx = mctx;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (*tctx)->dhkey = NULL;
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews (*tctx)->domain = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
1e00606f58bc78e3562d54a28749175268a03a89Bob Halley
1e00606f58bc78e3562d54a28749175268a03a89Bob Halleyvoid
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrewsdns_tkeyctx_destroy(dns_tkey_ctx_t **tctx) {
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_mem_t *mctx;
1e00606f58bc78e3562d54a28749175268a03a89Bob Halley
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews REQUIRE(tctx != NULL);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews REQUIRE(*tctx != NULL);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if ((*tctx)->dhkey != NULL)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dst_key_free((*tctx)->dhkey);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if ((*tctx)->domain != NULL) {
8a17d1e7cdba9fdcf71fb2f821a954a251204105Mark Andrews dns_name_free((*tctx)->domain, (*tctx)->mctx);
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews isc_mem_put((*tctx)->mctx, (*tctx)->domain, sizeof(dns_name_t));
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews }
3a4ec3da9fa14511cbc3660f75817cfacb3f4d1eMark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews mctx = (*tctx)->mctx;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews isc_mem_put(mctx, *tctx, sizeof(dns_tkey_ctx_t));
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews}
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrewsstatic isc_result_t
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrewsadd_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata,
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews isc_uint32_t ttl, dns_namelist_t *namelist)
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews{
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews isc_result_t result;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews isc_region_t r, newr;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dns_rdata_t *newrdata = NULL;
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley dns_name_t *newname = NULL;
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley dns_rdatalist_t *newlist = NULL;
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley dns_rdataset_t *newset = NULL;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson isc_buffer_t *tmprdatabuf = NULL, *tmpnamebuf = NULL;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews RETERR(dns_message_gettemprdata(msg, &newrdata));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_toregion(rdata, &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY));
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews isc_buffer_available(tmprdatabuf, &newr);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews memcpy(newr.base, r.base, r.length);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews dns_message_takebuffer(msg, &tmprdatabuf);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
fcf8db89e6c5740822838380c3a4ffcfb7754992Mark Andrews dns_name_toregion(name, &r);
fcf8db89e6c5740822838380c3a4ffcfb7754992Mark Andrews RETERR(dns_message_gettempname(msg, &newname));
06a49674418e8a74e879b63ea4ce4cb2261bbc70Mark Andrews dns_name_init(newname, NULL);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews RETERR(isc_buffer_allocate(msg->mctx, &tmpnamebuf, r.length,
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews ISC_BUFFERTYPE_BINARY));
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews isc_buffer_available(tmpnamebuf, &newr);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews memcpy(newr.base, r.base, r.length);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews dns_name_fromregion(newname, &newr);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews dns_message_takebuffer(msg, &tmpnamebuf);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews RETERR(dns_message_gettemprdatalist(msg, &newlist));
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews newlist->rdclass = newrdata->rdclass;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews newlist->type = newrdata->type;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews newlist->covers = 0;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews newlist->ttl = ttl;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews ISC_LIST_INIT(newlist->rdata);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews ISC_LIST_APPEND(newlist->rdata, newrdata, link);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(dns_message_gettemprdataset(msg, &newset));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dns_rdataset_init(newset);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(dns_rdatalist_tordataset(newlist, newset));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews ISC_LIST_INIT(newname->list);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews ISC_LIST_APPEND(newname->list, newset, link);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews ISC_LIST_APPEND(*namelist, newname, link);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews return (ISC_R_SUCCESS);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews failure:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (newrdata != NULL)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dns_message_puttemprdata(msg, &newrdata);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (newname != NULL)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dns_message_puttempname(msg, &newname);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (newlist != NULL)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dns_message_puttemprdatalist(msg, &newlist);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (newset != NULL) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dns_rdataset_disassociate(newset);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_message_puttemprdataset(msg, &newset);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (result);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsstatic isc_result_t
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewscompute_secret(isc_buffer_t *shared, isc_region_t *queryrandomness,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews isc_region_t *serverrandomness, isc_buffer_t *secret)
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews{
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews dst_context_t ctx;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews isc_result_t result;
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews isc_region_t r, r2;
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews char digests[32];
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews isc_buffer_t b;
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews unsigned int i;
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews isc_buffer_init(&b, digests, sizeof(digests), ISC_BUFFERTYPE_BINARY);
bcd7fdf06ca76eb2f6eb157f56b612c503e062a7Mark Andrews isc_buffer_used(shared, &r);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews /* MD5 ( query data | DH value ) */
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dst_digest(DST_SIGMODE_INIT, DST_DIGEST_MD5, &ctx, NULL, NULL));
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews RETERR(dst_digest(DST_SIGMODE_UPDATE, DST_DIGEST_MD5, &ctx,
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews queryrandomness, NULL));
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews RETERR(dst_digest(DST_SIGMODE_UPDATE, DST_DIGEST_MD5, &ctx, &r, NULL));
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews RETERR(dst_digest(DST_SIGMODE_FINAL, DST_DIGEST_MD5, &ctx, NULL, &b));
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews /* MD5 ( server data | DH value ) */
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dst_digest(DST_SIGMODE_INIT, DST_DIGEST_MD5, &ctx, NULL, NULL));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dst_digest(DST_SIGMODE_UPDATE, DST_DIGEST_MD5, &ctx,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews serverrandomness, NULL));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(dst_digest(DST_SIGMODE_UPDATE, DST_DIGEST_MD5, &ctx, &r, NULL));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dst_digest(DST_SIGMODE_FINAL, DST_DIGEST_MD5, &ctx, NULL, &b));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* XOR ( DH value, MD5-1 | MD5-2) */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_available(secret, &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_used(shared, &r2);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (r.length < sizeof(digests) || r.length < r2.length)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (r2.length > sizeof(digests)) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews memcpy(r.base, r2.base, r2.length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews for (i = 0; i < sizeof(digests); i++)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r.base[i] ^= digests[i];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_add(secret, r2.length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews memcpy(r.base, digests, sizeof(digests));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews for (i = 0; i < r2.length; i++)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r.base[i] ^= r2.base[i];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_add(secret, sizeof(digests));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews failure:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return result;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews}
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsprocess_dhtkey(dns_message_t *msg, dns_name_t *name,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_generic_tkey_t *tkeyin, dns_tkey_ctx_t *tctx,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_generic_tkey_t *tkeyout,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_tsig_keyring_t *ring, dns_namelist_t *namelist)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews{
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_result_t result = ISC_R_SUCCESS;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t *keyname, ourname, signer, *creator;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_t *keyset;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_t keyrdata, ourkeyrdata;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dst_key_t *pubkey = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t ourkeybuf, ournamein, ournameout, *shared = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t r, r2, ourkeyr;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_uint32_t ourttl;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned char keydata[DST_KEY_MAXSIZE];
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned char namedata[1024];
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dns_tsigkey_t *tsigkey;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned int sharedsize;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_buffer_t randombuf, secret;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews unsigned char *randomdata = NULL, secretdata[256];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_stdtime_t now;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Look for a DH KEY record that will work with ours */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (result == ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews keyname = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews keyset = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_findtype(keyname, dns_rdatatype_key, 0,
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews &keyset);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews if (result == ISC_R_SUCCESS) {
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews result = dns_rdataset_first(keyset);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (result == ISC_R_SUCCESS) {
19d365e4448f1782611280b020987988b7ac3210Mark Andrews dns_rdataset_current(keyset, &keyrdata);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews pubkey = NULL;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews result = dns_dnssec_keyfromrdata(keyname,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &keyrdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews msg->mctx,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &pubkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_rdataset_next(keyset);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews continue;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dst_key_alg(pubkey) == DNS_KEYALG_DH) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dst_key_paramcompare(pubkey,
19d365e4448f1782611280b020987988b7ac3210Mark Andrews tctx->dhkey))
19d365e4448f1782611280b020987988b7ac3210Mark Andrews {
19d365e4448f1782611280b020987988b7ac3210Mark Andrews found_key = ISC_TRUE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto got_key;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews found_incompatible = ISC_TRUE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews dst_key_free(pubkey);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews result = dns_rdataset_next(keyset);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews }
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews }
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews got_key:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (!found_key) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (found_incompatible) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout->error = dns_tsigerror_badkey;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews return (ISC_R_SUCCESS);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
19d365e4448f1782611280b020987988b7ac3210Mark Andrews return (DNS_R_FORMERR);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(add_rdata_to_list(msg, keyname, &keyrdata, keyset->ttl,
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews namelist));
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata),
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dst_key_todns(tctx->dhkey, &ourkeybuf));
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_buffer_used(&ourkeybuf, &ourkeyr);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_in,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdatatype_key, &ourkeyr);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&ournamein, dst_key_name(tctx->dhkey),
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews strlen(dst_key_name(tctx->dhkey)), ISC_BUFFERTYPE_TEXT);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_buffer_add(&ournamein, strlen(dst_key_name(tctx->dhkey)));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&ournameout, namedata, sizeof(namedata),
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_init(&ourname, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_name_fromtext(&ourname, &ournamein, dns_rootname, ISC_FALSE,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &ournameout));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ourttl = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if 0
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Not sure how to do this without a view... */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews db = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_dbtable_find(client->view->dbtable, &ourname, &db);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result == ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_t set;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_fixedname_t foundname;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_init(&set);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews dns_fixedname_init(&foundname);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews result = dns_db_find(db, &ourname, NULL, dns_rdatatype_key,
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews DNS_DBFIND_NOWILD, 0, NULL,
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_fixedname_name(&foundname),
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley &set, NULL);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (result == ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ourttl = set.ttl;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews dns_rdataset_disassociate(&set);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews }
19d365e4448f1782611280b020987988b7ac3210Mark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, ourttl,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews namelist));
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley RETERR(dst_secret_size(tctx->dhkey, &sharedsize));
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley RETERR(isc_buffer_allocate(msg->mctx, &shared, sharedsize,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY));
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley RETERR(dst_computesecret(pubkey, tctx->dhkey, shared));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&secret, secretdata, sizeof(secretdata),
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews ISC_BUFFERTYPE_BINARY);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
c1e7aff941dbf40090fec49300e728ad017d4f0cMark Andrews randomdata = isc_mem_get(tkeyout->mctx, TKEY_RANDOM_AMOUNT);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (randomdata == NULL) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = ISC_R_NOMEMORY;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto failure;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&randombuf, randomdata, TKEY_RANDOM_AMOUNT,
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews ISC_BUFFERTYPE_BINARY);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews RETERR(dst_random_get(TKEY_RANDOM_AMOUNT, &randombuf));
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews isc_buffer_used(&randombuf, &r);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews r2.base = tkeyin->key;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews r2.length = tkeyin->keylen;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(compute_secret(shared, &r2, &r, &secret));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_name_init(&signer, NULL);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews result = dns_message_signer(msg, &signer);
f305d86668bfd4d4727c3e0f70e7e97a2fa1b772Bob Halley /* handle DNS_R_NOTVERIFIEDYET */
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (result == ISC_R_SUCCESS)
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews creator = &signer;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews else
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews creator = NULL;
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dst_key_free(pubkey);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews isc_buffer_used(&secret, &r);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews tsigkey = NULL;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews result = dns_tsigkey_create(name, &tkeyin->algorithm, r.base, r.length,
19d365e4448f1782611280b020987988b7ac3210Mark Andrews ISC_TRUE, creator, msg->mctx, ring,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews NULL);
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff isc_buffer_free(&shared);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews shared = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result == ISC_R_NOTFOUND) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout->error = dns_tsigerror_badalg;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (ISC_R_SUCCESS);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews }
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (result != ISC_R_SUCCESS)
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews goto failure;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews /* This key is good for a long time */
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews isc_stdtime_get(&now);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews tkeyout->inception = tkeyin->inception;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews tkeyout->expire = tkeyin->expire;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews tkeyout->key = randomdata;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews tkeyout->keylen = TKEY_RANDOM_AMOUNT;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews return (ISC_R_SUCCESS);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews failure:
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews if (!ISC_LIST_EMPTY(*namelist)) {
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews dns_name_t *tname = ISC_LIST_HEAD(*namelist);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews while (tname != NULL) {
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews dns_name_t *next = ISC_LIST_NEXT(tname, link);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews dns_rdataset_t *tset;
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews ISC_LIST_UNLINK(*namelist, tname, link);
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews tset = ISC_LIST_HEAD(tname->list);
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews dns_rdataset_disassociate(tset);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews dns_message_puttemprdataset(msg, &tset);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews dns_message_puttempname(msg, &tname);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews tname = next;
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews }
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews }
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews if (shared != NULL)
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews isc_buffer_free(&shared);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews return (result);
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews}
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrews
fdd04623a6a36aad8449ef0877d8801a558873b8Mark Andrewsstatic isc_result_t
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrewsprocess_deletetkey(dns_message_t *msg, dns_name_t *name,
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews dns_rdata_generic_tkey_t *tkeyin,
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews dns_rdata_generic_tkey_t *tkeyout,
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_tsig_keyring_t *ring,
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_namelist_t *namelist)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews{
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_result_t result;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_tsigkey_t *tsigkey = NULL;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews dns_name_t signer;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews /* Unused variables */
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews msg = msg;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews tkeyout = tkeyout;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews namelist = namelist;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews if (result != ISC_R_SUCCESS)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews tkeyout->error = dns_tsigerror_badname;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Only allow a delete if the identity that created the key is the
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * same as the identity that signed the message.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_init(&signer, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_signer(msg, &signer);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* handle DNS_R_NOTVERIFIEDYET */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result == DNS_R_NOIDENTITY) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Special case - there is no identity associated with the
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * TSIG key that signed the message, but it's that key
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * being deleted. This is OK.
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley */
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley if (!dns_name_equal(&signer, name))
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley return (DNS_R_REFUSED);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews else if (result != ISC_R_SUCCESS) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (DNS_R_REFUSED);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
19d365e4448f1782611280b020987988b7ac3210Mark Andrews else {
19d365e4448f1782611280b020987988b7ac3210Mark Andrews dns_name_t *identity = dns_tsigkey_identity(tsigkey);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (identity == NULL || !dns_name_equal(identity, &signer))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (DNS_R_REFUSED);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
f8aae502686e2448c48f56697c212a50e2a1cbaeAndreas Gustafsson
f8aae502686e2448c48f56697c212a50e2a1cbaeAndreas Gustafsson /*
f8aae502686e2448c48f56697c212a50e2a1cbaeAndreas Gustafsson * Set the key to be deleted when no references are left. If the key
f8aae502686e2448c48f56697c212a50e2a1cbaeAndreas Gustafsson * was not generated with TKEY and is in the config file, it may be
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * reloaded later.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_tsigkey_setdeleted(tsigkey);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews /* Release the reference */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_tsigkey_free(&tsigkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafssonisc_result_t
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafssondns_tkey_processquery(dns_message_t *msg, dns_tkey_ctx_t *tctx,
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson dns_tsig_keyring_t *ring)
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson{
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson isc_result_t result = ISC_R_SUCCESS;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson dns_rdata_generic_tkey_t tkeyin, tkeyout;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson dns_name_t *qname, *name, *keyname, tempkeyname;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson dns_rdataset_t *tkeyset;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson dns_rdata_t tkeyrdata, *rdata = NULL;
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley isc_buffer_t *dynbuf = NULL;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson dns_namelist_t namelist;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson REQUIRE(msg != NULL);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson REQUIRE(tctx != NULL);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson REQUIRE(ring != NULL);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson /* Need to do this to determine if this should be freed later */
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson memset(&tkeyin, 0, sizeof(dns_rdata_generic_tkey_t));
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson /* Interpret the question section */
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson INSIST(result == DNS_R_SUCCESS);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson qname = NULL;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson dns_message_currentname(msg, DNS_SECTION_QUESTION, &qname);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson /* Look for a TKEY record that matches the question */
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson tkeyset = NULL;
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley name = NULL;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname,
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson dns_rdatatype_tkey, 0, &name, &tkeyset);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_SUCCESS) {
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews result = DNS_R_FORMERR;
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews goto failure;
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews }
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews result = dns_rdataset_first(tkeyset);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (result != ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = DNS_R_FORMERR;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto failure;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_current(tkeyset, &tkeyrdata);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
19d365e4448f1782611280b020987988b7ac3210Mark Andrews RETERR(dns_rdata_tostruct(&tkeyrdata, &tkeyin, msg->mctx));
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff if (tkeyin.error != dns_rcode_noerror) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = DNS_R_FORMERR;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto failure;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews ISC_LIST_INIT(namelist);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout.common.rdclass = tkeyin.common.rdclass;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout.common.rdtype = tkeyin.common.rdtype;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_LINK_INIT(&tkeyout.common, link);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout.mctx = msg->mctx;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_init(&tkeyout.algorithm, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_name_dup(&tkeyin.algorithm, msg->mctx, &tkeyout.algorithm));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout.inception = tkeyout.expire = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout.mode = tkeyin.mode;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyout.error = 0;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews tkeyout.keylen = tkeyout.otherlen = 0;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews tkeyout.key = tkeyout.other = NULL;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
19d365e4448f1782611280b020987988b7ac3210Mark Andrews * A delete operation must have a fully specified key name. If this
19d365e4448f1782611280b020987988b7ac3210Mark Andrews * is not a delete, we do the following:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * if (qname != ".")
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * keyname = qname + defaultdomain
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * else
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * keyname = <random hex> + defaultdomain
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (tkeyin.mode != DNS_TKEYMODE_DELETE) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t prefix;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t *buf = NULL;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews unsigned char tdata[64];
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews dns_tsigkey_t *tsigkey = NULL;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews dns_name_init(&tempkeyname, NULL);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews keyname = &tempkeyname;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews dns_name_init(&prefix, NULL);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews RETERR(isc_buffer_allocate(msg->mctx, &buf, 256,
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews ISC_BUFFERTYPE_BINARY));
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (!dns_name_equal(qname, dns_rootname)) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned int n = dns_name_countlabels(qname);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_name_getlabelsequence(qname, 0, n - 1, &prefix);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews else {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews static char hexdigits[16] = {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews '0', '1', '2', '3', '4', '5', '6', '7',
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews unsigned char randomtext[32];
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews isc_buffer_t b, b2;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews int i;
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews isc_buffer_init(&b, randomtext, sizeof(randomtext),
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews ISC_BUFFERTYPE_BINARY);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews result = dst_random_get(sizeof(randomtext)/2, &b);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (result != ISC_R_SUCCESS) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_message_takebuffer(msg, &buf);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews goto failure;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews for (i = sizeof(randomtext) - 2; i >= 0; i -= 2) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews unsigned char val = randomtext[i/2];
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews randomtext[i] = hexdigits[val >> 4];
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews randomtext[i+1] = hexdigits[val & 0xF];
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews isc_buffer_init(&b, randomtext, sizeof(randomtext),
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews ISC_BUFFERTYPE_TEXT);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews isc_buffer_init(&b2, tdata, sizeof(tdata),
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews ISC_BUFFERTYPE_BINARY);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews isc_buffer_add(&b, sizeof(randomtext));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews result = dns_name_fromtext(&prefix, &b, NULL,
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews ISC_FALSE, &b2);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (result != ISC_R_SUCCESS) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_message_takebuffer(msg, &buf);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews goto failure;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews result = dns_name_concatenate(&prefix, tctx->domain,
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews keyname, buf);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_message_takebuffer(msg, &buf);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (result != ISC_R_SUCCESS)
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews goto failure;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews result = dns_tsigkey_find(&tsigkey, keyname, NULL, ring);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews if (result == ISC_R_SUCCESS) {
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews tkeyout.error = dns_tsigerror_badname;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_tsigkey_free(&tsigkey);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews goto failure_with_tkey;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews else if (result != ISC_R_NOTFOUND)
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews goto failure;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews else
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews keyname = qname;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (!dns_name_equal(&tkeyin.algorithm, DNS_TSIG_HMACMD5_NAME)) {
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews tkeyout.error = dns_tsigerror_badkey;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews goto failure_with_tkey;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews switch (tkeyin.mode) {
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews case DNS_TKEYMODE_DIFFIEHELLMAN:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(process_dhtkey(msg, keyname, &tkeyin, tctx,
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews &tkeyout, ring, &namelist));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews tkeyout.error = dns_rcode_noerror;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews break;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews case DNS_TKEYMODE_DELETE:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(process_deletetkey(msg, keyname, &tkeyin,
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews &tkeyout, ring, &namelist));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews tkeyout.error = dns_rcode_noerror;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews break;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews case DNS_TKEYMODE_SERVERASSIGNED:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews case DNS_TKEYMODE_GSSAPI:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews case DNS_TKEYMODE_RESOLVERASSIGNED:
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews result = DNS_R_NOTIMP;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews goto failure;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews default:
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews tkeyout.error = dns_tsigerror_badmode;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews failure_with_tkey:
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_rdata_freestruct(&tkeyin);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews RETERR(dns_message_gettemprdata(msg, &rdata));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 128,
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews ISC_BUFFERTYPE_BINARY));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews result = dns_rdata_fromstruct(rdata, tkeyout.common.rdclass,
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews tkeyout.common.rdtype, &tkeyout, dynbuf);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dns_rdata_freestruct(&tkeyout);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews if (result != ISC_R_SUCCESS)
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews goto failure;
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(add_rdata_to_list(msg, keyname, rdata, 0, &namelist));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews isc_buffer_free(&dynbuf);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews RETERR(dns_message_reply(msg, ISC_TRUE));
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews name = ISC_LIST_HEAD(namelist);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews while (name != NULL) {
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_name_t *next = ISC_LIST_NEXT(name, link);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews ISC_LIST_UNLINK(namelist, name, link);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews name = next;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews }
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (ISC_R_SUCCESS);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews failure:
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (tkeyin.common.rdtype == dns_rdatatype_tkey)
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdata_freestruct(&tkeyin);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (rdata != NULL)
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_message_puttemprdata(msg, &rdata);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews if (dynbuf != NULL)
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews isc_buffer_free(&dynbuf);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews return (result);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews}
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsstatic isc_result_t
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrewsbuildquery(dns_message_t *msg, dns_name_t *name,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdata_generic_tkey_t *tkey)
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews{
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_name_t *qname = NULL, *aname = NULL;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdataset_t *question = NULL, *tkeyset = NULL;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdatalist_t *tkeylist = NULL;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdata_t *rdata = NULL;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews isc_buffer_t *dynbuf = NULL;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews isc_result_t result;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews REQUIRE(msg != NULL);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews REQUIRE(name != NULL);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews REQUIRE(tkey != NULL);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_message_gettempname(msg, &qname));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_message_gettempname(msg, &aname));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_message_gettemprdataset(msg, &question));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdataset_init(question);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdataset_makequestion(question, dns_rdataclass_in /* _any */,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdatatype_tkey);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 512,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews ISC_BUFFERTYPE_BINARY));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_message_gettemprdata(msg, &rdata));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_in /* _any */,
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdatatype_tkey, tkey, dynbuf));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_message_takebuffer(msg, &dynbuf);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_message_gettemprdatalist(msg, &tkeylist));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews tkeylist->rdclass = dns_rdataclass_in /* _any */;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews tkeylist->type = dns_rdatatype_tkey;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews tkeylist->covers = 0;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews tkeylist->ttl = 0;
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews ISC_LIST_INIT(tkeylist->rdata);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews ISC_LIST_APPEND(tkeylist->rdata, rdata, link);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_message_gettemprdataset(msg, &tkeyset));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_rdataset_init(tkeyset);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset));
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_name_init(qname, NULL);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_name_clone(name, qname);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_name_init(aname, NULL);
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews dns_name_clone(name, aname);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_LIST_APPEND(qname->list, question, link);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_LIST_APPEND(aname->list, tkeyset, link);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews failure:
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley if (qname != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_message_puttempname(msg, &qname);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (aname != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_message_puttempname(msg, &aname);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (question != NULL) {
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley dns_rdataset_disassociate(question);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_message_puttemprdataset(msg, &question);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dynbuf != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_free(&dynbuf);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsisc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t *algorithm, isc_buffer_t *nonce,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_uint32_t lifetime)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews{
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_generic_tkey_t tkey;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_t *rdata = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t src, *dynbuf = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t r;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t *keyname = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_namelist_t namelist;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_result_t result;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_stdtime_t now;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(msg != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(key != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(dst_key_isprivate(key));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(name != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(algorithm != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.common.rdclass = dns_rdataclass_in /* _any */;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.common.rdtype = dns_rdatatype_tkey;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_LINK_INIT(&tkey.common, link);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.mctx = msg->mctx;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_init(&tkey.algorithm, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_clone(algorithm, &tkey.algorithm);
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley isc_stdtime_get(&now);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.inception = now;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.expire = now + lifetime;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.mode = DNS_TKEYMODE_DIFFIEHELLMAN;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (nonce != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_region(nonce, &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r.base = NULL;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews r.length = 0;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews }
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.error = 0;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.key = r.base;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.keylen = r.length;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.other = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.otherlen = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews RETERR(buildquery(msg, name, &tkey));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
f0ff273b530afa730025e1c5ad311950f7ff4328Mark Andrews RETERR(dns_message_gettemprdata(msg, &rdata));
f0ff273b530afa730025e1c5ad311950f7ff4328Mark Andrews RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024,
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews ISC_BUFFERTYPE_BINARY));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews RETERR(dst_key_todns(key, dynbuf));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_used(dynbuf, &r);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_rdata_fromregion(rdata, dns_rdataclass_in,
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_rdatatype_key, &r);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_message_takebuffer(msg, &dynbuf);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews RETERR(dns_message_gettempname(msg, &keyname));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews isc_buffer_init(&src, dst_key_name(key), strlen(dst_key_name(key)),
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews ISC_BUFFERTYPE_TEXT);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews isc_buffer_add(&src, strlen(dst_key_name(key)));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 1024,
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews ISC_BUFFERTYPE_BINARY));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_name_init(keyname, NULL);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews RETERR(dns_name_fromtext(keyname, &src, dns_rootname, ISC_FALSE,
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dynbuf));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_message_takebuffer(msg, &dynbuf);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews ISC_LIST_INIT(namelist);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews RETERR(add_rdata_to_list(msg, keyname, rdata, 0, &namelist));
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_message_addname(msg, ISC_LIST_HEAD(namelist),
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews DNS_SECTION_ADDITIONAL);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews return (ISC_R_SUCCESS);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews failure:
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews if (dynbuf != NULL)
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews isc_buffer_free(&dynbuf);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews return (result);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews}
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrewsisc_result_t
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrewsdns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key) {
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_rdata_generic_tkey_t tkey;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews REQUIRE(msg != NULL);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews REQUIRE(key != NULL);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.common.rdclass = dns_rdataclass_in /* _any */;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.common.rdtype = dns_rdatatype_tkey;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews ISC_LINK_INIT(&tkey.common, link);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews tkey.mctx = msg->mctx;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_name_init(&tkey.algorithm, NULL);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews dns_name_clone(&key->algorithm, &tkey.algorithm);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.inception = tkey.expire = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.mode = DNS_TKEYMODE_DELETE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.error = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.keylen = tkey.otherlen = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkey.key = tkey.other = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (buildquery(msg, &key->name, &tkey));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
26b0f58b6c4d65bc8b131debf40b8c376c2978bfBob Halleystatic isc_result_t
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrewsfind_tkey(dns_message_t *msg, dns_name_t **name, dns_rdata_t *rdata) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dns_rdataset_t *tkeyset;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_result_t result;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (result == ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *name = NULL;
bfb2a81b65579882a80855c279cedc45aebd62e8Mark Andrews dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, name);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews tkeyset = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_findtype(*name, dns_rdatatype_tkey, 0,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &tkeyset);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result == ISC_R_SUCCESS) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_rdataset_first(tkeyset);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_SUCCESS)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_current(tkeyset, rdata);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result == ISC_R_NOMORE)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOTFOUND);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsisc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dst_key_t *key, isc_buffer_t *nonce,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews{
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_t qtkeyrdata, rtkeyrdata;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t keyname, *tkeyname, *theirkeyname, *ourkeyname, *tempname;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_t *theirkeyset = NULL, *ourkeyset = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_t theirkeyrdata;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dst_key_t *theirkey;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_tsigkey_t *tsigkey;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_generic_tkey_t qtkey, rtkey;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned char keydata[1024], secretdata[256];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int sharedsize;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_t keysrc, keybuf, *shared = NULL, secret;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_region_t r, r2;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_result_t result;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(qmsg != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(rmsg != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(key != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(dst_key_alg(key) == DNS_KEYALG_DH);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(dst_key_isprivate(key));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (outkey != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(*outkey == NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews REQUIRE(ring != NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rmsg->rcode != dns_rcode_noerror)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return(ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, qmsg->mctx));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rtkey.error != dns_rcode_noerror ||
26b0f58b6c4d65bc8b131debf40b8c376c2978bfBob Halley rtkey.mode != DNS_TKEYMODE_DIFFIEHELLMAN ||
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rtkey.mode != qtkey.mode ||
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rmsg->rcode != dns_rcode_noerror)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = DNS_R_INVALIDTKEY;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_freestruct(&rtkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto failure;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&keysrc, dst_key_name(key), strlen(dst_key_name(key)),
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_TEXT);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_buffer_add(&keysrc, strlen(dst_key_name(key)));
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews isc_buffer_init(&keybuf, keydata, sizeof(keydata),
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_init(&keyname, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_name_fromtext(&keyname, &keysrc, dns_rootname,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_FALSE, &keybuf));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08Mark Andrews ourkeyname = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ourkeyset = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_message_findname(rmsg, DNS_SECTION_ADDITIONAL, &keyname,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdatatype_key, 0, &ourkeyname,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews &ourkeyset));
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_firstname(rmsg, DNS_SECTION_ADDITIONAL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (result == ISC_R_SUCCESS) {
1c3191528684f3dd93ebb122298c2f8ebfc6d397Mark Andrews theirkeyname = NULL;
1c3191528684f3dd93ebb122298c2f8ebfc6d397Mark Andrews dns_message_currentname(rmsg, DNS_SECTION_ADDITIONAL,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &theirkeyname);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dns_name_equal(theirkeyname, ourkeyname))
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto next;
e4653123ecc6cdbfc0b9eda6e98e44af3b1f9a08Mark Andrews theirkeyset = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_findtype(theirkeyname, dns_rdatatype_key,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews 0, &theirkeyset);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result == ISC_R_SUCCESS) {
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson RETERR(dns_rdataset_first(theirkeyset));
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson break;
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson }
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson next:
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson result = dns_message_nextname(rmsg, DNS_SECTION_ADDITIONAL);
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson }
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson if (theirkeyset == NULL) {
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson result = ISC_R_NOTFOUND;
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson goto failure;
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson }
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson dns_rdataset_current(theirkeyset, &theirkeyrdata);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews theirkey = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dns_dnssec_keyfromrdata(theirkeyname, &theirkeyrdata,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rmsg->mctx, &theirkey));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews RETERR(dst_secret_size(key, &sharedsize));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(isc_buffer_allocate(rmsg->mctx, &shared, sharedsize,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RETERR(dst_computesecret(theirkey, key, shared));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_init(&secret, secretdata, sizeof(secretdata),
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ISC_BUFFERTYPE_BINARY);
15330e4fa27c82ac04cc2ce234ec930e4b6b42d3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r.base = rtkey.key;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r.length = rtkey.keylen;
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews if (nonce != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_region(nonce, &r2);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r2.base = NULL;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews r2.length = 0;
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson }
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson RETERR(compute_secret(shared, &r2, &r, &secret));
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson isc_buffer_used(&secret, &r);
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson tsigkey = NULL;
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson result = dns_tsigkey_create(tkeyname, &rtkey.algorithm,
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson r.base, r.length, ISC_TRUE,
5a219d878f0bd786e86da2c9b92999260dda3f8dAndreas Gustafsson NULL, rmsg->mctx, ring, outkey);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews isc_buffer_free(&shared);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (result);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews failure:
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (shared != NULL)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson isc_buffer_free(&shared);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (result);
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews}
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews
25870d4a37ab4bc8e675502b08335200167cc044Bob Halleyisc_result_t
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrewsdns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
25870d4a37ab4bc8e675502b08335200167cc044Bob Halley dns_tsig_keyring_t *ring)
25870d4a37ab4bc8e675502b08335200167cc044Bob Halley{
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews dns_rdata_t qtkeyrdata, rtkeyrdata;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews dns_name_t *tkeyname, *tempname;
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews dns_rdata_generic_tkey_t qtkey, rtkey;
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews dns_tsigkey_t *tsigkey = NULL;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews isc_result_t result;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews REQUIRE(qmsg != NULL);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews REQUIRE(rmsg != NULL);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews if (rmsg->rcode != dns_rcode_noerror)
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return(ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata));
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata));
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, qmsg->mctx));
2192b4497348ccab94ca6f3f779cec399c72a8efMark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews if (rtkey.error != dns_rcode_noerror ||
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews rtkey.mode != DNS_TKEYMODE_DELETE ||
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews rtkey.mode != qtkey.mode ||
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews !dns_name_equal(&rtkey.algorithm, &qtkey.algorithm) ||
25870d4a37ab4bc8e675502b08335200167cc044Bob Halley rmsg->rcode != dns_rcode_noerror)
035504dbd8ca5949e8380b860873b3385a4e61e5Mark Andrews {
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews result = DNS_R_INVALIDTKEY;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dns_rdata_freestruct(&rtkey);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews goto failure;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews }
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm, ring));
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews /* Mark the key as deleted */
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dns_tsigkey_setdeleted(tsigkey);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews /* Release the reference */
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews dns_tsigkey_free(&tsigkey);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews failure:
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews return (result);
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews}
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews