tsig.c revision 7077846f3bf941f626a8623bd29a56a5ce7a1e11
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson/*
0e27506ce3135f9bd49e12564ad0e15256135118Automatic Updater * Copyright (C) 1999, 2000 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * copyright notice and this permission notice appear in all copies.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * SOFTWARE.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
d9eebc08497af272b2d44c07f4eb85153dec4253Evan Hunt/*
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * $Id: tsig.c,v 1.65 2000/05/27 00:24:07 bwelling Exp $
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Principal Author: Brian Wellington
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#include <config.h>
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson#include <stdlib.h> /* Required for abs(). */
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews#include <isc/mem.h>
3e14b69d196a3ebeecc4662c426344dcfd7db678Andreas Gustafsson#include <isc/once.h>
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews#include <isc/string.h> /* Required for HP/UX (and others?) */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/util.h>
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence#include <dns/keyvalues.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dns/message.h>
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews#include <dns/rdata.h>
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews#include <dns/rdatalist.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <dns/rdataset.h>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#include <dns/result.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dns/tsig.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews#include <dst/result.h>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews#define TSIG_MAGIC 0x54534947 /* TSIG */
3e14b69d196a3ebeecc4662c426344dcfd7db678Andreas Gustafsson#define VALID_TSIG_KEY(x) ISC_MAGIC_VALID(x, TSIG_MAGIC)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonstatic isc_once_t once = ISC_ONCE_INIT;
673ce7aebbb6d01c75b95f6df1ec491d6422b951Andreas Gustafssonstatic dns_name_t hmacmd5_name;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondns_name_t *dns_tsig_hmacmd5_name = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonisc_result_t
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews unsigned char *secret, int length, isc_boolean_t generated,
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews dns_name_t *creator, isc_stdtime_t inception,
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_stdtime_t expire, isc_mem_t *mctx,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsig_keyring_t *ring, dns_tsigkey_t **key)
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence{
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence isc_buffer_t b;
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence isc_uint16_t alg;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsigkey_t *tkey;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_result_t ret;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews REQUIRE(key == NULL || *key == NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews REQUIRE(name != NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews REQUIRE(algorithm != NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews REQUIRE(length >= 0);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (length > 0)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(secret != NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(mctx != NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (!dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (ISC_R_NOTFOUND);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson alg = DST_ALG_HMACMD5;
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (tkey == NULL)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return (ISC_R_NOMEMORY);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence dns_name_init(&tkey->name, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_name_dup(name, mctx, &tkey->name);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_downcase(&tkey->name, &tkey->name, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_name_init(&tkey->algorithm, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_name_dup(algorithm, mctx, &tkey->algorithm);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_name;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_downcase(&tkey->algorithm, &tkey->algorithm, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (creator != NULL) {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t));
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (tkey->creator == NULL) {
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews ret = ISC_R_NOMEMORY;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_algorithm;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_init(tkey->creator, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_name_dup(algorithm, mctx, tkey->creator);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS) {
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_algorithm;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey->creator = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey->key = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey->ring = NULL;
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt if (length > 0) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsigkey_t *tmp;
b76715a02fbe0c373a5a03c4f09ac0d6de5abc43Mark Andrews
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington isc_buffer_init(&b, secret, length);
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington isc_buffer_add(&b, length);
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews ret = dst_key_frombuffer(name, alg,
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews DNS_KEYOWNER_ENTITY,
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews DNS_KEYPROTO_DNSSEC,
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews &b, mctx, &tkey->key);
b76715a02fbe0c373a5a03c4f09ac0d6de5abc43Mark Andrews if (ret != ISC_R_SUCCESS)
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews goto cleanup_algorithm;
d0aebc5a55b6145297d94f8aee939852357c59fcMark Andrews
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer ISC_LINK_INIT(tkey, link);
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington isc_rwlock_lock(&ring->lock, isc_rwlocktype_write);
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington tmp = ISC_LIST_HEAD(ring->keys);
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington while (tmp != NULL) {
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington if (dns_name_equal(&tkey->name, &tmp->name) &&
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington !tmp->deleted)
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington {
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt ret = ISC_R_EXISTS;
19f4d25fd5b35b1375b0b9f13b66770ee4a66154Brian Wellington isc_rwlock_unlock(&ring->lock,
b76715a02fbe0c373a5a03c4f09ac0d6de5abc43Mark Andrews isc_rwlocktype_write);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_algorithm;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny Mayer tmp = ISC_LIST_NEXT(tmp, link);
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington }
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington ISC_LIST_APPEND(ring->keys, tkey, link);
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington isc_rwlock_unlock(&ring->lock, isc_rwlocktype_write);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson tkey->ring = ring;
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson }
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
b76715a02fbe0c373a5a03c4f09ac0d6de5abc43Mark Andrews tkey->refs = 0;
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington if (key != NULL)
2883651930dc85cacae940fe2a81277dfc14807dBrian Wellington tkey->refs++;
459d31fa838619cee728a90984d27d18345dc18aAndreas Gustafsson tkey->generated = generated;
459d31fa838619cee728a90984d27d18345dc18aAndreas Gustafsson tkey->inception = inception;
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer tkey->expire = expire;
b76715a02fbe0c373a5a03c4f09ac0d6de5abc43Mark Andrews tkey->deleted = ISC_FALSE;
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer tkey->mctx = mctx;
c67496c94321dfb68d209019f2b5872a81289c66Michael Sawyer ret = isc_mutex_init(&tkey->lock);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if (ret != ISC_R_SUCCESS) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson UNEXPECTED_ERROR(__FILE__, __LINE__,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson "isc_mutex_init() failed: %s",
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer isc_result_totext(ret));
bfe313722d5b2eff6c80336ed1f19c2f99a53de6Andreas Gustafsson return (ISC_R_UNEXPECTED);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington }
b76715a02fbe0c373a5a03c4f09ac0d6de5abc43Mark Andrews
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey->magic = TSIG_MAGIC;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (key != NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson *key = tkey;
68e4926b2262571e004b4be00b905ec776c01d9cMichael Graff
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (ISC_R_SUCCESS);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
68e4926b2262571e004b4be00b905ec776c01d9cMichael Graffcleanup_algorithm:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_free(&tkey->algorithm, mctx);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉cleanup_name:
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews dns_name_free(&tkey->name, mctx);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewscleanup_key:
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_mem_put(mctx, *key, sizeof(dns_tsigkey_t));
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return (ret);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews}
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsvoid
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsdns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) {
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(VALID_TSIG_KEY(source));
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(targetp != NULL && *targetp == NULL);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_mutex_lock(&source->lock);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews source->refs++;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_mutex_unlock(&source->lock);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews *targetp = source;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews}
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsstatic void
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewstsigkey_free(dns_tsigkey_t *key) {
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews dns_tsig_keyring_t *ring;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews REQUIRE(VALID_TSIG_KEY(key));
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ring = key->ring;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews key->magic = 0;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews if (key->key != NULL) {
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 isc_rwlock_lock(&ring->lock, isc_rwlocktype_write);
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson ISC_LIST_UNLINK(ring->keys, key, link);
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater isc_rwlock_unlock(&ring->lock, isc_rwlocktype_write);
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews }
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dns_name_free(&key->name, key->mctx);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence dns_name_free(&key->algorithm, key->mctx);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (key->key != NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dst_key_free(&key->key);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (key->creator != NULL) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff dns_name_free(key->creator, key->mctx);
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley isc_mem_put(key->mctx, key->creator, sizeof(dns_name_t));
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley }
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley isc_mem_put(key->mctx, key, sizeof(dns_tsigkey_t));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson}
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
544f5611e1fc84597db819d111c8fd98bb719de6Bob Halleyvoid
544f5611e1fc84597db819d111c8fd98bb719de6Bob Halleydns_tsigkey_detach(dns_tsigkey_t **key) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsigkey_t *tkey;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(key != NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(VALID_TSIG_KEY(*key));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey = *key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson *key = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_mutex_lock(&tkey->lock);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tkey->refs--;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (tkey->refs > 0 || (!tkey->deleted && tkey->key != NULL)) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mutex_unlock(&tkey->lock);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence return;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff isc_mutex_unlock(&tkey->lock);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsigkey_free(tkey);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence}
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonvoid
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondns_tsigkey_setdeleted(dns_tsigkey_t *key) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson INSIST(VALID_TSIG_KEY(key));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mutex_lock(&key->lock);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson key->deleted = ISC_TRUE;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mutex_unlock(&key->lock);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson}
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonisc_result_t
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondns_tsig_sign(dns_message_t *msg) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsigkey_t *key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdata_any_tsig_t tsig;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson unsigned char data[128];
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_t databuf, sigbuf;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_t *dynbuf;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence dns_name_t *owner;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdata_t *rdata;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff dns_rdatalist_t *datalist;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdataset_t *dataset;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_region_t r, r2;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_stdtime_t now;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dst_context_t ctx;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mem_t *mctx;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_result_t ret;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_boolean_t algfreed = ISC_FALSE;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(msg != NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg)));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(msg->tsig == NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * If this is a response, there should be a query tsig.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (is_response(msg) && msg->querytsig == NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (DNS_R_EXPECTEDTSIG);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence dynbuf = NULL;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence mctx = msg->mctx;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson key = dns_message_gettsigkey(msg);
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson tsig.mctx = mctx;
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson tsig.common.rdclass = dns_rdataclass_any;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence tsig.common.rdtype = dns_rdatatype_tsig;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ISC_LINK_INIT(&tsig.common, link);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_init(&tsig.algorithm, NULL);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = dns_name_dup(&key->algorithm, mctx, &tsig.algorithm);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (ret != ISC_R_SUCCESS)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence goto cleanup_struct;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_stdtime_get(&now);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig.timesigned = now;
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley tsig.fudge = DNS_TSIG_FUDGE;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley tsig.originalid = msg->id;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_buffer_init(&databuf, data, sizeof(data));
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (is_response(msg))
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley tsig.error = msg->querytsigstatus;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig.error = dns_rcode_noerror;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (tsig.error != dns_tsigerror_badtime) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig.otherlen = 0;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig.other = NULL;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence else {
47b7dfffe5d806c6a5e99ef17f07bcde812c2132Francis Dupont isc_buffer_t otherbuf;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig.otherlen = 6;
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley tsig.other = (unsigned char *)isc_mem_get(mctx, tsig.otherlen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (tsig.other == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff ret = ISC_R_NOMEMORY;
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley goto cleanup_other;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_buffer_putuint16(&otherbuf,
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence (isc_uint16_t)(tsig.timesigned >> 32));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_putuint32(&otherbuf,
2e715dbdc263f859c01b57a9d733c1dfbf28b90eBob Halley (isc_uint32_t)(tsig.timesigned &
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson 0xFFFFFFFF));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (!dns_tsigkey_empty(key) && tsig.error != dns_tsigerror_badsig) {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson unsigned char header[DNS_MESSAGE_HEADERLEN];
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_t headerbuf;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson unsigned int sigsize;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews ret = dst_key_sign(DST_SIGMODE_INIT, key->key, &ctx, NULL,
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson NULL);
ec7493d8d1966a3dc5f5306fc0a96519e0de6dceAndreas Gustafsson if (ret != ISC_R_SUCCESS)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence goto cleanup_algorithm;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * If this is a response, digest the query signature.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (is_response(msg)) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_availableregion(&databuf, &r);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (r.length < msg->querytsig->siglen)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (ISC_R_NOSPACE);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington memcpy(r.base, msg->querytsig->signature,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson msg->querytsig->siglen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_add(&databuf, msg->querytsig->siglen);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson isc_buffer_usedregion(&databuf, &r);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx,
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson &r, NULL);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if (ret != ISC_R_SUCCESS)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson goto cleanup_algorithm;
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson }
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson /*
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson * Digest the header.
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson */
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson isc_buffer_init(&headerbuf, header, sizeof(header));
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson dns_message_renderheader(msg, &headerbuf);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson isc_buffer_usedregion(&headerbuf, &r);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson NULL);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if (ret != ISC_R_SUCCESS)
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews goto cleanup_other;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews /*
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews * Digest the remainder of the message.
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews */
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_usedregion(msg->buffer, &r);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (ret != ISC_R_SUCCESS)
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews goto cleanup_other;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (msg->tcp_continuation == 0) {
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews /*
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews * Digest the name, class, ttl, alg.
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews */
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews dns_name_toregion(&key->name, &r);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx,
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews &r, NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (ret != ISC_R_SUCCESS)
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews goto cleanup_other;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_clear(&databuf);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_putuint16(&databuf, dns_rdataclass_any);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_putuint32(&databuf, 0); /* ttl */
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_usedregion(&databuf, &r);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx,
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews &r, NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (ret != ISC_R_SUCCESS)
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt goto cleanup_other;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews dns_name_toregion(&tsig.algorithm, &r);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx,
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews &r, NULL);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (ret != ISC_R_SUCCESS)
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews goto cleanup_other;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews }
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews /* Digest the timesigned and fudge */
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_clear(&databuf);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (tsig.error != dns_tsigerror_badtime) {
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_putuint16(&databuf,
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews (isc_uint16_t)(tsig.timesigned >>
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews 32));
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews isc_buffer_putuint32(&databuf,
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews (isc_uint32_t)(tsig.timesigned &
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson 0xFFFFFFFF));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson else {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_uint64_t querysigned = msg->querytsig->timesigned;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_putuint16(&databuf,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson (isc_uint16_t)(querysigned >>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson 32));
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_buffer_putuint32(&databuf,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson (isc_uint16_t)(querysigned &
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson 0xFFFFFFFF));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_putuint16(&databuf, tsig.fudge);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_usedregion(&databuf, &r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx, &r,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_other;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (msg->tcp_continuation == 0) {
11c7a43642def4aaa2bed001ff018a0bb0b65c29Danny Mayer /*
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt * Digest the error and other data length.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_clear(&databuf);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_buffer_putuint16(&databuf, tsig.error);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews isc_buffer_putuint16(&databuf, tsig.otherlen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_usedregion(&databuf, &r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &r, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
84f0bd3bc7ac72289cc0dfedd3d17872ad1169feEvan Hunt goto cleanup_other;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Digest the error and other data.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (tsig.otherlen > 0) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson r.length = tsig.otherlen;
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley r.base = tsig.other;
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley ret = dst_key_sign(DST_SIGMODE_UPDATE,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson key->key, &ctx, &r, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_other;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_sigsize(key->key, &sigsize);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence goto cleanup_other;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence tsig.siglen = sigsize;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence tsig.signature = (unsigned char *)
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews isc_mem_get(mctx, tsig.siglen);
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews if (tsig.signature == NULL) {
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews ret = ISC_R_NOMEMORY;
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews goto cleanup_other;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_init(&sigbuf, tsig.signature, tsig.siglen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_sign(DST_SIGMODE_FINAL, key->key, &ctx, NULL,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &sigbuf);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews goto cleanup_signature;
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews }
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson else {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence tsig.siglen = 0;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig.signature = NULL;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson rdata = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_message_gettemprdata(msg, &rdata);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_signature;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_signature;
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdatatype_tsig, &tsig, dynbuf);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_dynbuf;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (tsig.signature != NULL) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_mem_put(mctx, tsig.signature, tsig.siglen);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence tsig.signature = NULL;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence }
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews if (tsig.other != NULL) {
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews isc_mem_put(mctx, tsig.other, tsig.otherlen);
b9efcf0a377381b29960137e54ecaf4db85a35c8Mark Andrews tsig.other = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_free(&tsig.algorithm, mctx);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson algfreed = ISC_TRUE;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley msg->tsig = isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley if (msg->tsig == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff ret = ISC_R_NOMEMORY;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_dynbuf;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_rdata_tostruct(rdata, msg->tsig, mctx);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence goto cleanup_tsig;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence dns_message_takebuffer(msg, &dynbuf);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt owner = NULL;
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson ret = dns_message_gettempname(msg, &owner);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if (ret != ISC_R_SUCCESS)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson goto cleanup_tsig;
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson dns_name_toregion(&key->name, &r);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson dynbuf = NULL;
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt ret = isc_buffer_allocate(mctx, &dynbuf, r.length);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt if (ret != ISC_R_SUCCESS)
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt goto cleanup_tsig;
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt isc_buffer_availableregion(dynbuf, &r2);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt memcpy(r2.base, r.base, r.length);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt dns_name_init(owner, NULL);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt dns_name_fromregion(owner, &r2);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt dns_message_takebuffer(msg, &dynbuf);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence datalist = NULL;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = dns_message_gettemprdatalist(msg, &datalist);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (ret != ISC_R_SUCCESS)
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson goto cleanup_tsig;
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt datalist->rdclass = dns_rdataclass_any;
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews datalist->type = dns_rdatatype_tsig;
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews datalist->covers = 0;
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews datalist->ttl = 0;
d788d738e3d29037651b42566519c9a0a66ba219Mark Andrews ISC_LIST_INIT(datalist->rdata);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews ISC_LIST_APPEND(datalist->rdata, rdata, link);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews dataset = NULL;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews ret = dns_message_gettemprdataset(msg, &dataset);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews if (ret != ISC_R_SUCCESS)
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews goto cleanup_tsig;
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews dns_rdataset_init(dataset);
47d89fcd4fb850b066f87dc3313afe1cfe92cd99Mark Andrews dns_rdatalist_tordataset(datalist, dataset);
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson msg->tsigset = dataset;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews msg->tsigname = owner;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (ISC_R_SUCCESS);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssoncleanup_tsig:
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson dns_rdata_freestruct(msg->tsig);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson isc_mem_put(mctx, msg->tsig, sizeof *msg->tsig);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssoncleanup_dynbuf:
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (dynbuf != NULL)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson isc_buffer_free(&dynbuf);
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Huntcleanup_signature:
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (tsig.signature != NULL)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson isc_mem_put(mctx, tsig.signature, tsig.siglen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssoncleanup_other:
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence if (tsig.other != NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mem_put(mctx, tsig.other, tsig.otherlen);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffcleanup_algorithm:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (!algfreed)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_free(&tsig.algorithm, mctx);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssoncleanup_struct:
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson msg->tsig = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (ret);
84f0bd3bc7ac72289cc0dfedd3d17872ad1169feEvan Hunt}
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffisc_result_t
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsig_keyring_t *sring, dns_tsig_keyring_t *dring)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson{
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdata_any_tsig_t *tsig;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_region_t r, source_r, header_r, sig_r;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_buffer_t databuf;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson unsigned char data[32];
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence dns_name_t *keyname;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdata_t rdata;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_stdtime_t now;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_result_t ret;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsigkey_t *tsigkey;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dst_key_t *key = NULL;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff unsigned char header[DNS_MESSAGE_HEADERLEN];
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dst_context_t ctx;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mem_t *mctx;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_uint16_t addcount, id;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(source != NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(DNS_MESSAGE_VALID(msg));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(msg->tsig == NULL);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff tsigkey = dns_message_gettsigkey(msg);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson msg->verify_attempted = 1;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (msg->tcp_continuation)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return(dns_tsig_verify_tcp(source, msg));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff /*
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley * There should be a TSIG record...
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (msg->tsigset == NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (DNS_R_EXPECTEDTSIG);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * If this is a response and there's no key or query TSIG, there
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * shouldn't be one on the response.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (is_response(msg) &&
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson (tsigkey == NULL || msg->querytsig == NULL))
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (DNS_R_UNEXPECTEDTSIG);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson mctx = msg->mctx;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * If we're here, we know the message is well formed and contains a
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * TSIG record.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson keyname = msg->tsigname;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_rdataset_first(msg->tsigset);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ret);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdataset_current(msg->tsigset, &rdata);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson tsig = (dns_rdata_any_tsig_t *)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (tsig == NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson return (ISC_R_NOMEMORY);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson msg->tsig = tsig;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_rdata_tostruct(&rdata, tsig, mctx);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_emptystruct;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Do the key name and algorithm match that of the query?
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (is_response(msg) &&
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley (!dns_name_equal(keyname, &tsigkey->name) ||
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence !dns_name_equal(&tsig->algorithm, &msg->querytsig->algorithm)))
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->tsigstatus = dns_tsigerror_badkey;
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley return (DNS_R_TSIGVERIFYFAILURE);
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley }
c801dd02ed98321f3ccab93c159a1dce61961c58Bob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Get the current time.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_stdtime_get(&now);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Find dns_tsigkey_t based on keyname.
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (tsigkey == NULL) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = ISC_R_NOTFOUND;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (sring != NULL)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff ret = dns_tsigkey_find(&tsigkey, keyname,
bfe313722d5b2eff6c80336ed1f19c2f99a53de6Andreas Gustafsson &tsig->algorithm, sring);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret == ISC_R_NOTFOUND && dring != NULL)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_tsigkey_find(&tsigkey, keyname,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &tsig->algorithm, dring);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (dring == NULL) {
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = DNS_R_TSIGVERIFYFAILURE;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_struct;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson msg->tsigstatus = dns_tsigerror_badkey;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dns_tsigkey_create(keyname, &tsig->algorithm,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson NULL, 0, ISC_FALSE, NULL,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson now, now,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson mctx, dring, &msg->tsigkey);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence goto cleanup_struct;
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson return (DNS_R_TSIGVERIFYFAILURE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence }
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson msg->tsigkey = tsigkey;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson key = tsigkey->key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson * Is the time ok?
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson */
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if (abs(now - tsig->timesigned) > tsig->fudge) {
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson msg->tsigstatus = dns_tsigerror_badtime;
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson return (DNS_R_TSIGVERIFYFAILURE);
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson }
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if (tsig->siglen > 0) {
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson sig_r.base = tsig->signature;
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson sig_r.length = tsig->siglen;
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson ret = dst_key_verify(DST_SIGMODE_INIT, key, &ctx, NULL,
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson &sig_r);
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if (ret != ISC_R_SUCCESS)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson goto cleanup_key;
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if (is_response(msg)) {
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson isc_buffer_init(&databuf, data, sizeof(data));
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson isc_buffer_usedregion(&databuf, &r);
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson NULL);
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson if (ret != ISC_R_SUCCESS)
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson goto cleanup_key;
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson if (msg->querytsig->siglen > 0) {
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson r.length = msg->querytsig->siglen;
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson r.base = msg->querytsig->signature;
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key,
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson &ctx, &r, NULL);
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson if (ret != ISC_R_SUCCESS)
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson goto cleanup_key;
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson }
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson }
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson
bed7a352934efc8055902d83c750dca2d0cd6aaaAndreas Gustafsson /*
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson * Extract the header.
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson */
421551db8a61283420b0b6aed4ac28f9d76b9770Andreas Gustafsson isc_buffer_usedregion(source, &r);
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉 memcpy(header, r.base, DNS_MESSAGE_HEADERLEN);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Decrement the additional field counter.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson addcount = htons(ntohs(addcount) - 1);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Put in the original id.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson id = htons(tsig->originalid);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff memcpy(&header[0], &id, 2);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Digest the modified header.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence header_r.base = (unsigned char *) header;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence header_r.length = DNS_MESSAGE_HEADERLEN;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &header_r,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &sig_r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Digest all non-TSIG records.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_usedregion(source, &source_r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &sig_r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Digest the key name.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_toregion(&tsigkey->name, &r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence &sig_r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_init(&databuf, data, sizeof(data));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_putuint16(&databuf, tsig->common.rdclass);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_buffer_putuint32(&databuf, msg->tsigset->ttl);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_usedregion(&databuf, &r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &sig_r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_key;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * Digest the key algorithm.
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_toregion(&tsigkey->algorithm, &r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff &sig_r);
4e57d3ff7d92abdef4b0b6aebc23a9dfae2ba040Andreas Gustafsson if (ret != ISC_R_SUCCESS)
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence goto cleanup_key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff isc_buffer_clear(&databuf);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig->timesigned
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson >> 32));
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig->timesigned
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence & 0xFFFFFFFF));
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence isc_buffer_putuint16(&databuf, tsig->fudge);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_putuint16(&databuf, tsig->error);
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence isc_buffer_putuint16(&databuf, tsig->otherlen);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_usedregion(&databuf, &r);
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &sig_r);
c0d0a59d1b665423b8a0d1829d0f0da121cb3473Andreas Gustafsson
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence if (tsig->otherlen > 0) {
d8e34837cd6c88c42b3ecdb9107a43ecf8252e79David Lawrence r.base = tsig->other;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson r.length = tsig->otherlen;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff &sig_r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson goto cleanup_key;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ret = dst_key_verify(DST_SIGMODE_FINAL, key, &ctx, NULL,
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson &sig_r);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (ret == DST_R_VERIFYFINALFAILURE) {
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson msg->tsigstatus = dns_tsigerror_badsig;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (DNS_R_TSIGVERIFYFAILURE);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson else if (ret != ISC_R_SUCCESS)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson goto cleanup_key;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson else if (tsig->error != dns_tsigerror_badsig &&
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson tsig->error != dns_tsigerror_badkey)
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews {
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson msg->tsigstatus = dns_tsigerror_badsig;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (DNS_R_TSIGVERIFYFAILURE);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson msg->tsigstatus = dns_rcode_noerror;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (tsig->error != dns_rcode_noerror) {
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (is_response(msg)) {
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson /* XXXBEW Log a message */
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (ISC_R_SUCCESS);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson else
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (DNS_R_TSIGERRORSET);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson msg->verified_sig = 1;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (ISC_R_SUCCESS);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafssoncleanup_key:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (dns_tsigkey_empty(tsigkey))
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson dns_tsigkey_detach(&tsigkey);
e694d4e2016c0ab1f3c2bbe493c45379770e830dDavid Lawrencecleanup_struct:
e694d4e2016c0ab1f3c2bbe493c45379770e830dDavid Lawrence dns_rdata_freestruct(tsig);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafssoncleanup_emptystruct:
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson msg->tsig = NULL;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (ret);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson}
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafssonstatic isc_result_t
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafssondns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson dns_rdata_any_tsig_t *tsig = NULL;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_region_t r, source_r, header_r, sig_r;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_buffer_t databuf;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson unsigned char data[32];
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson dns_name_t *keyname;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson dns_rdata_t rdata;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_stdtime_t now;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_result_t ret;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dns_tsigkey_t *tsigkey;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dst_key_t *key = NULL;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson unsigned char header[DNS_MESSAGE_HEADERLEN];
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_mem_t *mctx;
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews isc_uint16_t addcount, id;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_boolean_t has_tsig = ISC_FALSE;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson REQUIRE(source != NULL);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson REQUIRE(msg != NULL);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson REQUIRE(msg->tsig == NULL);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson REQUIRE(dns_message_gettsigkey(msg) != NULL);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson REQUIRE(msg->tcp_continuation == 1);
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews REQUIRE(is_response(msg));
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews REQUIRE(msg->querytsig != NULL);
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews mctx = msg->mctx;
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews tsigkey = dns_message_gettsigkey(msg);
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews if (msg->tsigset != NULL) {
692ae2fff922f1c072169d1ddda8e600cb572a9bMark Andrews has_tsig = ISC_TRUE;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson keyname = msg->tsigname;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ret = dns_rdataset_first(msg->tsigset);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (ret != ISC_R_SUCCESS)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (ret);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson dns_rdataset_current(msg->tsigset, &rdata);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson tsig = (dns_rdata_any_tsig_t *)
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (tsig == NULL)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson return (ISC_R_NOMEMORY);
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington msg->tsig = tsig;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ret = dns_rdata_tostruct(&rdata, tsig, mctx);
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington if (ret != ISC_R_SUCCESS)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson goto cleanup_emptystruct;
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson
4100ae5109c69d8269a8fa626f217a15a633cd7fMark Andrews /*
4100ae5109c69d8269a8fa626f217a15a633cd7fMark Andrews * Do the key name and algorithm match that of the query?
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt */
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if (!dns_name_equal(keyname, &tsigkey->name) ||
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson !dns_name_equal(&tsig->algorithm,
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson &msg->querytsig->algorithm))
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson {
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson msg->tsigstatus = dns_tsigerror_badkey;
f621719829356f27e831507b75e88e8a655e48d8Danny Mayer return (DNS_R_TSIGVERIFYFAILURE);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson }
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson
123a3dddc94534d3a6c6f81c118a5b63dc5994c3Andreas Gustafsson /*
123a3dddc94534d3a6c6f81c118a5b63dc5994c3Andreas Gustafsson * Is the time ok?
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson */
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews isc_stdtime_get(&now);
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews if (abs(now - tsig->timesigned) > tsig->fudge) {
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews msg->tsigstatus = dns_tsigerror_badtime;
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews return (DNS_R_TSIGVERIFYFAILURE);
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews }
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews }
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews key = tsigkey->key;
a76b380643a22f23a67a9df284e86cd7ef7608c1Mark Andrews
e482a1c91ecb5e47bc26617bf310d6b5c41fad91Andreas Gustafsson if (msg->tsigctx == NULL) {
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington ret = dst_key_verify(DST_SIGMODE_INIT, key, &msg->tsigctx,
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington NULL, NULL);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (ret != ISC_R_SUCCESS)
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson goto cleanup_struct;
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_buffer_init(&databuf, data, sizeof(data));
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson isc_buffer_usedregion(&databuf, &r);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx,
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson &r, NULL);
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (ret != ISC_R_SUCCESS)
674f1cfb1d7dfa92e52db950dbe80e60ef8f5cddBrian Wellington goto cleanup_struct;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson if (msg->querytsig->siglen > 0) {
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson r.length = msg->querytsig->siglen;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson r.base = msg->querytsig->signature;
593cb00bd17e5e2ab0dcb7c635a9a81082dc5d0eAndreas Gustafsson ret = dst_key_verify(DST_SIGMODE_UPDATE, key,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson &msg->tsigctx, &r, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (ret != ISC_R_SUCCESS)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews goto cleanup_struct;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * Extract the header.
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_buffer_usedregion(source, &r);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews memcpy(header, r.base, DNS_MESSAGE_HEADERLEN);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_region_consume(&r, DNS_MESSAGE_HEADERLEN);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * Decrement the additional field counter if necessary.
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (has_tsig) {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews addcount = htons(ntohs(addcount) - 1);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * Put in the original id.
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /* XXX Can TCP transfers be forwarded? How would that work? */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (tsig != NULL) {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews id = htons(tsig->originalid);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews memcpy(&header[0], &id, 2);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * Digest the modified header.
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews header_r.base = (unsigned char *) header;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews header_r.length = DNS_MESSAGE_HEADERLEN;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &header_r,
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (ret != ISC_R_SUCCESS)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews goto cleanup_struct;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * Digest all non-TSIG records.
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_buffer_usedregion(source, &source_r);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (has_tsig)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews else
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews r.length = source_r.length - DNS_MESSAGE_HEADERLEN;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &r, NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (ret != ISC_R_SUCCESS)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews goto cleanup_struct;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
203629e729b756601646c639c0dbfb267030a617Mark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * Digest the time signed and fudge.
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (has_tsig) {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_buffer_init(&databuf, data, sizeof(data));
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig->timesigned
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews >> 32));
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig->timesigned
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews & 0xFFFFFFFF));
203629e729b756601646c639c0dbfb267030a617Mark Andrews isc_buffer_putuint16(&databuf, tsig->fudge);
203629e729b756601646c639c0dbfb267030a617Mark Andrews isc_buffer_usedregion(&databuf, &r);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx,
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews &r, NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews sig_r.base = tsig->signature;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews sig_r.length = tsig->siglen;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (tsig->siglen == 0) {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (tsig->error != dns_rcode_noerror)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ret = DNS_R_TSIGERRORSET;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews else
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ret = DNS_R_TSIGVERIFYFAILURE;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews goto cleanup_struct;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews ret = dst_key_verify(DST_SIGMODE_FINAL, key, &msg->tsigctx,
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews NULL, &sig_r);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (ret == DST_R_VERIFYFINALFAILURE) {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews msg->tsigstatus = dns_tsigerror_badsig;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews return (DNS_R_TSIGVERIFYFAILURE);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews else if (ret != ISC_R_SUCCESS)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews goto cleanup_struct;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews msg->tsigctx = NULL;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews msg->tsigstatus = dns_rcode_noerror;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews return (ISC_R_SUCCESS);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewscleanup_struct:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dns_rdata_freestruct(tsig);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewscleanup_emptystruct:
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews msg->tsig = NULL;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews return (ret);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews}
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewsisc_result_t
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrewsdns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dns_name_t *algorithm, dns_tsig_keyring_t *ring)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews{
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dns_tsigkey_t *key;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_stdtime_t now;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews REQUIRE(tsigkey != NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews REQUIRE(*tsigkey == NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews REQUIRE(name != NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews REQUIRE(ring != NULL);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_stdtime_get(&now);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_rwlock_lock(&ring->lock, isc_rwlocktype_read);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews key = ISC_LIST_HEAD(ring->keys);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews while (key != NULL) {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (dns_name_equal(&key->name, name) &&
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews (algorithm == NULL ||
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dns_name_equal(&key->algorithm, algorithm)) &&
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews !key->deleted)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews if (key->inception != key->expire &&
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews key->expire < now)
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews {
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews /*
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews * The key has expired.
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt */
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews key->deleted = ISC_TRUE;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews continue;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_mutex_lock(&key->lock);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews key->refs++;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_mutex_unlock(&key->lock);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews *tsigkey = key;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews isc_rwlock_unlock(&ring->lock, isc_rwlocktype_read);
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews return (ISC_R_SUCCESS);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews key = ISC_LIST_NEXT(key, link);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews }
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews isc_rwlock_unlock(&ring->lock, isc_rwlocktype_read);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews *tsigkey = NULL;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews return (ISC_R_NOTFOUND);
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews}
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonstatic void
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssondns_tsig_inithmac() {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_region_t r;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson char *str = "\010HMAC-MD5\007SIG-ALG\003REG\003INT";
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_init(&hmacmd5_name, NULL);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson r.base = (unsigned char *)str;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence r.length = strlen(str) + 1;
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews dns_name_fromregion(&hmacmd5_name, &r);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_tsig_hmacmd5_name = &hmacmd5_name;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson}
68e4926b2262571e004b4be00b905ec776c01d9cMichael Graff
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonisc_result_t
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsdns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ring)
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews{
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_result_t ret;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(mctx != NULL);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(ring != NULL);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(*ring == NULL);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
d99f88add1e61555e3193e9b33701c1a1ffa677aMichael Graff RUNTIME_CHECK(isc_once_do(&once, dns_tsig_inithmac) == ISC_R_SUCCESS);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews *ring = isc_mem_get(mctx, sizeof(dns_tsig_keyring_t));
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews if (ring == NULL)
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return (ISC_R_NOMEMORY);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews ret = isc_rwlock_init(&(*ring)->lock, 0, 0);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews if (ret != ISC_R_SUCCESS) {
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews "isc_rwlock_init() failed: %s",
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_result_totext(ret));
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return (ISC_R_UNEXPECTED);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews }
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews ISC_LIST_INIT((*ring)->keys);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews (*ring)->mctx = mctx;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews return (ISC_R_SUCCESS);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews}
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsvoid
9aba20edee4e704433a464ae43b070b0775de506Mark Andrewsdns_tsigkeyring_destroy(dns_tsig_keyring_t **ring) {
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_mem_t *mctx;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(ring != NULL);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews REQUIRE(*ring != NULL);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews while (!ISC_LIST_EMPTY((*ring)->keys)) {
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews dns_tsigkey_t *key = ISC_LIST_HEAD((*ring)->keys);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews key->refs = 0;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews key->deleted = ISC_TRUE;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews tsigkey_free(key);
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews }
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews isc_rwlock_destroy(&(*ring)->lock);
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews mctx = (*ring)->mctx;
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews isc_mem_put(mctx, *ring, sizeof(dns_tsig_keyring_t));
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews *ring = NULL;
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews}
9aba20edee4e704433a464ae43b070b0775de506Mark Andrews