diff --git a/CHANGES b/CHANGES
index b5de78372f..e70a3284ed 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,17 @@
+3744. [experimental] SIT: send and process Source Identity Tokens
+ (which are similar to DNS Cookies by Donald Eastlake)
+ and are designed to help clients detect off path
+ spoofed responses and for servers to detect legitimate
+ clients.
+
+ SIT use a experimental EDNS option code (65001).
+
+ SIT can be enabled via --enable-developer or
+ --enable-sit. It is on by default in Windows.
+
+ RRL processing as been updated to know about SIT with
+ legitimate clients not being rate limited. [RT #35389]
+
3743. [bug] delegation-only flag wasn't working in forward zone
declarations despite being documented. This is
needed to support turning off forwarding and turning
diff --git a/bin/dig/dig.c b/bin/dig/dig.c
index 2d47579d04..d0d3ed01d6 100644
--- a/bin/dig/dig.c
+++ b/bin/dig/dig.c
@@ -63,6 +63,9 @@ static char *argv0;
static int addresscount = 0;
static char domainopt[DNS_NAME_MAXTEXT];
+#ifdef ISC_PLATFORM_USESIT
+static char sitvalue[256];
+#endif
static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE,
ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE,
@@ -223,6 +226,9 @@ help(void) {
" +[no]trace (Trace delegation down from root [+dnssec])\n"
" +[no]dnssec (Request DNSSEC records)\n"
" +[no]nsid (Request Name Server ID)\n"
+#ifdef ISC_PLATFORM_USESIT
+" +[no]sit (Request a Source Identity Token)\n"
+#endif
#ifdef DIG_SIGCHASE
" +[no]sigchase (Chase DNSSEC signatures)\n"
" +trusted-key=#### (Trusted Key when chasing DNSSEC sigs)\n"
@@ -1086,14 +1092,34 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto invalid_option;
}
break;
+ case 'i':
+ switch (cmd[2]) {
#ifdef DIG_SIGCHASE
- case 'i': /* sigchase */
- FULLCHECK("sigchase");
- lookup->sigchase = state;
- if (lookup->sigchase)
- lookup->dnssec = ISC_TRUE;
- break;
+ case 'g': /* sigchase */
+ FULLCHECK("sigchase");
+ lookup->sigchase = state;
+ if (lookup->sigchase)
+ lookup->dnssec = ISC_TRUE;
+ break;
#endif
+#ifdef ISC_PLATFORM_USESIT
+ case 't': /* sit */
+ FULLCHECK("sit");
+ if (state && lookup->edns == -1)
+ lookup->edns = 0;
+ lookup->sit = state;
+ if (value != NULL) {
+ strncpy(sitvalue, value,
+ sizeof(sitvalue));
+ lookup->sitvalue = sitvalue;
+ } else
+ lookup->sitvalue = NULL;
+ break;
+#endif
+ default:
+ goto invalid_option;
+ }
+ break;
case 'p': /* split */
FULLCHECK("split");
if (value != NULL && !state)
diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook
index d2c04394a5..2db8a5b9f2 100644
--- a/bin/dig/dig.docbook
+++ b/bin/dig/dig.docbook
@@ -924,6 +924,18 @@
+
+
+
+
+ Send a Source Identity Token EDNS option, with optional value.
+ Replaying a SIT from a previous response will allow the
+ server to identify a previous client. The default is
+ .
+
+
+
+
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 94ab297166..baef5f7d18 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -74,6 +74,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -176,6 +177,8 @@ int fatalexit = 0;
char keynametext[MXNAME];
char keyfile[MXNAME] = "";
char keysecret[MXNAME] = "";
+unsigned char cookie_secret[33];
+unsigned char cookie[8];
dns_name_t *hmacname = NULL;
unsigned int digestbits = 0;
isc_buffer_t *namebuf = NULL;
@@ -766,6 +769,9 @@ make_empty_lookup(void) {
looknew->besteffort = ISC_TRUE;
looknew->dnssec = ISC_FALSE;
looknew->nsid = ISC_FALSE;
+#ifdef ISC_PLATFORM_USESIT
+ looknew->sit = ISC_FALSE;
+#endif
#ifdef DIG_SIGCHASE
looknew->sigchase = ISC_FALSE;
#if DIG_SIGCHASE_TD
@@ -801,6 +807,9 @@ make_empty_lookup(void) {
looknew->new_search = ISC_FALSE;
looknew->done_as_is = ISC_FALSE;
looknew->need_search = ISC_FALSE;
+#ifdef ISC_PLATFORM_USESIT
+ looknew->sitvalue = NULL;
+#endif
ISC_LINK_INIT(looknew, link);
ISC_LIST_INIT(looknew->q);
ISC_LIST_INIT(looknew->connecting);
@@ -847,6 +856,10 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->besteffort = lookold->besteffort;
looknew->dnssec = lookold->dnssec;
looknew->nsid = lookold->nsid;
+#ifdef ISC_PLATFORM_USESIT
+ looknew->sit = lookold->sit;
+ looknew->sitvalue = lookold->sitvalue;
+#endif
#ifdef DIG_SIGCHASE
looknew->sigchase = lookold->sigchase;
#if DIG_SIGCHASE_TD
@@ -1210,6 +1223,7 @@ setup_system(void) {
dig_searchlist_t *domain = NULL;
lwres_result_t lwresult;
unsigned int lwresflags;
+ isc_result_t result;
debug("setup_system()");
@@ -1288,7 +1302,10 @@ setup_system(void) {
#endif
#endif
-
+ result = isc_entropy_getdata(entp, cookie_secret,
+ sizeof(cookie_secret), NULL, 0);
+ if (result != ISC_R_SUCCESS)
+ fatal("unable to generate cookie secret");
}
/*%
@@ -1381,46 +1398,18 @@ setup_libs(void) {
*/
static void
add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
- isc_boolean_t dnssec, isc_boolean_t nsid)
+ isc_boolean_t dnssec, dns_ednsopt_t *ednsopts, size_t count)
{
dns_rdataset_t *rdataset = NULL;
- dns_rdatalist_t *rdatalist = NULL;
- dns_rdata_t *rdata = NULL;
isc_result_t result;
+ unsigned int flags = 0;
debug("add_opt()");
- result = dns_message_gettemprdataset(msg, &rdataset);
- check_result(result, "dns_message_gettemprdataset");
- dns_rdataset_init(rdataset);
- result = dns_message_gettemprdatalist(msg, &rdatalist);
- check_result(result, "dns_message_gettemprdatalist");
- result = dns_message_gettemprdata(msg, &rdata);
- check_result(result, "dns_message_gettemprdata");
-
- debug("setting udp size of %d", udpsize);
- rdatalist->type = dns_rdatatype_opt;
- rdatalist->covers = 0;
- rdatalist->rdclass = udpsize;
- rdatalist->ttl = edns << 16;
if (dnssec)
- rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
- if (nsid) {
- isc_buffer_t *b = NULL;
-
- result = isc_buffer_allocate(mctx, &b, 4);
- check_result(result, "isc_buffer_allocate");
- isc_buffer_putuint16(b, DNS_OPT_NSID);
- isc_buffer_putuint16(b, 0);
- rdata->data = isc_buffer_base(b);
- rdata->length = isc_buffer_usedlength(b);
- dns_message_takebuffer(msg, &b);
- } else {
- rdata->data = NULL;
- rdata->length = 0;
- }
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
- dns_rdatalist_tordataset(rdatalist, rdataset);
+ flags |= DNS_MESSAGEEXTFLAG_DO;
+ result = dns_message_buildopt(msg, &rdataset, edns, udpsize, flags,
+ ednsopts, count);
+ check_result(result, "dns_message_buildopt");
result = dns_message_setopt(msg, rdataset);
check_result(result, "dns_message_setopt");
}
@@ -2008,6 +1997,15 @@ insert_soa(dig_lookup_t *lookup) {
dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY);
}
+#ifdef ISC_PLATFORM_USESIT
+static void
+compute_cookie(unsigned char *cookie, size_t len) {
+ /* XXXMPA need to fix, should be per server. */
+ INSIST(len >= 8U);
+ memcpy(cookie, cookie_secret, 8);
+}
+#endif
+
/*%
* Setup the supplied lookup structure, making it ready to start sending
* queries to servers. Create and initialize the message to be sent as
@@ -2276,12 +2274,44 @@ setup_lookup(dig_lookup_t *lookup) {
&lookup->renderbuf);
check_result(result, "dns_message_renderbegin");
if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1) {
+#define EDNSOPTS 2
+ dns_ednsopt_t opts[EDNSOPTS];
+ int i = 0;
if (lookup->udpsize == 0)
lookup->udpsize = 4096;
if (lookup->edns < 0)
lookup->edns = 0;
+ if (lookup->nsid) {
+ INSIST(i < EDNSOPTS);
+ opts[i].code = DNS_OPT_NSID;
+ opts[i].length = 0;
+ opts[i].value = NULL;
+ i++;
+ }
+#ifdef ISC_PLATFORM_USESIT
+ if (lookup->sit) {
+ INSIST(i < EDNSOPTS);
+ opts[i].code = DNS_OPT_SIT;
+ if (lookup->sitvalue != NULL) {
+ char bb[256];
+ isc_buffer_t b;
+
+ isc_buffer_init(&b, bb, sizeof(bb));
+ result = isc_hex_decodestring(lookup->sitvalue,
+ &b);
+ check_result(result, "isc_hex_decodestring");
+ opts[i].value = isc_buffer_base(&b);
+ opts[i].length = isc_buffer_usedlength(&b);
+ } else {
+ compute_cookie(cookie, sizeof(cookie));
+ opts[i].length = 8;
+ opts[i].value = cookie;
+ }
+ i++;
+ }
+#endif
add_opt(lookup->sendmsg, lookup->udpsize,
- lookup->edns, lookup->dnssec, lookup->nsid);
+ lookup->edns, lookup->dnssec, opts, i);
}
result = dns_message_rendersection(lookup->sendmsg,
@@ -3109,6 +3139,67 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg,
return (ISC_TRUE);
}
+#ifdef ISC_PLATFORM_USESIT
+static void
+process_sit(dig_lookup_t *l, isc_buffer_t *optbuf, size_t optlen) {
+ char bb[256];
+ isc_buffer_t hexbuf;
+ size_t len;
+ const unsigned char *sit;
+ isc_result_t result;
+
+ if (l->sitvalue != NULL) {
+ isc_buffer_init(&hexbuf, bb, sizeof(bb));
+ result = isc_hex_decodestring(l->sitvalue, &hexbuf);
+ check_result(result, "isc_hex_decodestring");
+ sit = isc_buffer_base(&hexbuf);
+ len = isc_buffer_usedlength(&hexbuf);
+ } else {
+ sit = cookie;
+ len = sizeof(cookie);
+ }
+
+ if (optlen >= len && optlen >= 8U) {
+ if (memcmp(isc_buffer_current(optbuf), sit, 8) == 0) {
+ if (l->comments)
+ printf(";; SIT client cookie part match\n");
+ } else
+ printf(";; Warning: SIT client cookie part mis-match\n");
+ } else
+ printf(";; Warning: SIT bad token (too short)\n");
+ isc_buffer_forward(optbuf, optlen);
+}
+
+static void
+process_opt(dig_lookup_t *l, dns_rdataset_t *opt) {
+ dns_rdata_t rdata;
+ isc_result_t result;
+ isc_buffer_t optbuf;
+ isc_uint16_t optcode, optlen;
+
+ result = dns_rdataset_first(opt);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(opt, &rdata);
+ isc_buffer_init(&optbuf, rdata.data, rdata.length);
+ isc_buffer_add(&optbuf, rdata.length);
+ while (isc_buffer_remaininglength(&optbuf) >= 4) {
+ optcode = isc_buffer_getuint16(&optbuf);
+ optlen = isc_buffer_getuint16(&optbuf);
+ switch (optcode) {
+ case DNS_OPT_SIT:
+ process_sit(l, &optbuf, optlen);
+ break;
+ default:
+ isc_buffer_forward(&optbuf, optlen);
+ break;
+ }
+ }
+ }
+}
+#endif
+
+
/*%
* Event handler for recv complete. Perform whatever actions are necessary,
* based on the specifics of the user's request.
@@ -3369,7 +3460,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0 &&
!l->ignore && !l->tcp_mode) {
- printf(";; Truncated, retrying in TCP mode.\n");
+ if (l->comments)
+ printf(";; Truncated, retrying in TCP mode.\n");
n = requeue_lookup(l, ISC_TRUE);
n->tcp_mode = ISC_TRUE;
n->origin = query->lookup->origin;
@@ -3401,7 +3493,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
*/
if ((ISC_LIST_HEAD(l->q) != query) ||
(ISC_LIST_NEXT(query, link) != NULL)) {
- if( l->comments == ISC_TRUE )
+ if (l->comments)
printf(";; Got %s from %s, "
"trying next server\n",
msg->rcode == dns_rcode_servfail ?
@@ -3469,6 +3561,16 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
}
+#ifdef ISC_PLATFORM_USESIT
+ if (l->sitvalue != NULL) {
+ if (msg->opt == NULL)
+ printf(";; expected opt record in response\n");
+ else
+ process_opt(l, msg->opt);
+ } else if (l->sit && msg->opt != NULL)
+ process_opt(l, msg->opt);
+#endif
+
if (!l->doing_xfr || l->xfr_q == query) {
if (msg->rcode == dns_rcode_nxdomain &&
(l->origin != NULL || l->need_search)) {
diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h
index 0150d11dfb..83cd24d2ec 100644
--- a/bin/dig/include/dig/dig.h
+++ b/bin/dig/include/dig/dig.h
@@ -130,6 +130,9 @@ struct dig_lookup {
done_as_is,
besteffort,
dnssec,
+#ifdef ISC_PLATFORM_USESIT
+ sit,
+#endif
nsid; /*% Name Server ID (RFC 5001) */
#ifdef DIG_SIGCHASE
isc_boolean_t sigchase;
@@ -184,6 +187,9 @@ isc_boolean_t sigchase;
isc_buffer_t *querysig;
isc_uint32_t msgcounter;
dns_fixedname_t fdomain;
+#ifdef ISC_PLATFORM_USESIT
+ char *sitvalue;
+#endif
};
/*% The dig_query structure */
diff --git a/bin/named/client.c b/bin/named/client.c
index 1597ebdb4e..f16f4045d4 100644
--- a/bin/named/client.c
+++ b/bin/named/client.c
@@ -25,6 +25,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -32,6 +34,12 @@
#include
#include
+#ifdef AES_SIT
+#include
+#else
+#include
+#endif
+
#include
#include
#include
@@ -113,6 +121,9 @@
*/
#endif
+#define SIT_SIZE 24 /* 8 + 4 + 4 + 8 */
+#define EDNSOPTS 2
+
/*% nameserver client manager structure */
struct ns_clientmgr {
/* Unlocked. */
@@ -235,6 +246,10 @@ static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
dns_dispatch_t *disp, isc_boolean_t tcp);
static inline isc_boolean_t
allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl);
+#ifdef ISC_PLATFORM_USESIT
+static void compute_sit(ns_client_t *client, isc_uint32_t when,
+ isc_uint32_t nonce, isc_buffer_t *buf);
+#endif
void
ns_client_recursing(ns_client_t *client) {
@@ -802,10 +817,24 @@ client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
}
} else {
data = sendbuf;
+#ifdef ISC_PLATFORM_USESIT
+ if ((client->attributes & NS_CLIENTATTR_HAVESIT) == 0) {
+ if (client->view != NULL)
+ bufsize = client->view->situdp;
+ else
+ bufsize = 512;
+ } else
+ bufsize = client->udpsize;
+ if (bufsize > client->udpsize)
+ bufsize = client->udpsize;
+ if (bufsize > SEND_BUFFER_SIZE)
+ bufsize = SEND_BUFFER_SIZE;
+#else
if (client->udpsize < SEND_BUFFER_SIZE)
bufsize = client->udpsize;
else
bufsize = SEND_BUFFER_SIZE;
+#endif
if (length > bufsize) {
result = ISC_R_NOSPACE;
goto done;
@@ -1342,11 +1371,14 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
static inline isc_result_t
client_addopt(ns_client_t *client) {
char nsid[BUFSIZ], *nsidp;
+#ifdef ISC_PLATFORM_USESIT
+ unsigned char sit[SIT_SIZE];
+#endif
isc_result_t result;
dns_view_t *view;
dns_resolver_t *resolver;
isc_uint16_t udpsize;
- dns_ednsopt_t ednsopts[2];
+ dns_ednsopt_t ednsopts[EDNSOPTS];
int count = 0;
unsigned int flags;
@@ -1375,12 +1407,33 @@ client_addopt(ns_client_t *client) {
} else
nsidp = ns_g_server->server_id;
+ INSIST(count < EDNSOPTS);
ednsopts[count].code = DNS_OPT_NSID;
ednsopts[count].length = strlen(nsidp);
ednsopts[count].value = (unsigned char *)nsidp;
count++;
}
no_nsid:
+#ifdef ISC_PLATFORM_USESIT
+ if ((client->attributes & NS_CLIENTATTR_WANTSIT) != 0) {
+ isc_buffer_t buf;
+ isc_stdtime_t now;
+ isc_uint32_t nonce;
+
+ isc_buffer_init(&buf, sit, sizeof(sit));
+ isc_stdtime_get(&now);
+ isc_random_get(&nonce);
+
+ compute_sit(client, now, nonce, &buf);
+
+ INSIST(count < EDNSOPTS);
+ ednsopts[count].code = DNS_OPT_SIT;
+ ednsopts[count].length = SIT_SIZE;
+ ednsopts[count].value = sit;
+ count++;
+ }
+#endif
+
result = dns_message_buildopt(client->message, &client->opt, 0,
udpsize, flags, ednsopts, count);
return (result);
@@ -1464,6 +1517,179 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
return (ISC_TF(view == myview));
}
+#ifdef ISC_PLATFORM_USESIT
+static void
+compute_sit(ns_client_t *client, isc_uint32_t when, isc_uint32_t nonce,
+ isc_buffer_t *buf)
+{
+#ifdef AES_SIT
+ unsigned char digest[ISC_AES_BLOCK_LENGTH];
+ unsigned char input[4 + 4 + 16];
+ isc_netaddr_t netaddr;
+ unsigned char *cp;
+ unsigned int i;
+
+ cp = isc_buffer_used(buf);
+ isc_buffer_putmem(buf, client->cookie, 8);
+ isc_buffer_putuint32(buf, nonce);
+ isc_buffer_putuint32(buf, when);
+ memcpy(input, cp, 8);
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ switch (netaddr.family) {
+ case AF_INET:
+ memcpy(input + 8, (unsigned char *)&netaddr.type.in, 4);
+ memset(input + 12, 0, 4);
+ isc_aes128_crypt(ns_g_server->secret, input, digest);
+ break;
+ case AF_INET6:
+ memcpy(input + 8, (unsigned char *)&netaddr.type.in6, 16);
+ isc_aes128_crypt(ns_g_server->secret, input, digest);
+ for (i = 0; i < 8; i++)
+ input[i + 8] = digest[i] ^ digest[i + 8];
+ isc_aes128_crypt(ns_g_server->secret, input + 8, digest);
+ break;
+ }
+ memcpy(input, client->cookie, 8);
+ for (i = 0; i < 8; i++)
+ input[i + 8] = digest[i] ^ digest[i + 8];
+ isc_aes128_crypt(ns_g_server->secret, input, digest);
+ for (i = 0; i < 8; i++)
+ digest[i] ^= digest[i + 8];
+ isc_buffer_putmem(buf, digest, 8);
+#endif
+#ifdef HMAC_SHA1_SIT
+ unsigned char digest[ISC_SHA1_DIGESTLENGTH];
+ isc_netaddr_t netaddr;
+ unsigned char *cp;
+ isc_hmacsha1_t hmacsha1;
+
+ cp = isc_buffer_used(buf);
+ isc_buffer_putuint32(buf, nonce);
+ isc_buffer_putuint32(buf, when);
+
+ isc_hmacsha1_init(&hmacsha1,
+ ns_g_server->secret,
+ ISC_SHA1_DIGESTLENGTH);
+ isc_hmacsha1_update(&hmacsha1, cp, 8);
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ switch (netaddr.family) {
+ case AF_INET:
+ isc_hmacsha1_update(&hmacsha1,
+ (unsigned char *)&netaddr.type.in, 4);
+ break;
+ case AF_INET6:
+ isc_hmacsha1_update(&hmacsha1,
+ (unsigned char *)&netaddr.type.in6, 16);
+ break;
+ }
+ isc_hmacsha1_update(&hmacsha1, client->cookie, sizeof(client->cookie));
+ isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest));
+ isc_buffer_putmem(buf, digest, 8);
+ isc_hmacsha1_invalidate(&hmacsha1);
+#endif
+#ifdef HMAC_SHA256_SIT
+ unsigned char digest[ISC_SHA256_DIGESTLENGTH];
+ isc_netaddr_t netaddr;
+ unsigned char *cp;
+ isc_hmacsha256_t hmacsha256;
+
+ cp = isc_buffer_used(buf);
+ isc_buffer_putuint32(buf, nonce);
+ isc_buffer_putuint32(buf, when);
+
+ isc_hmacsha256_init(&hmacsha256,
+ ns_g_server->secret,
+ ISC_SHA256_DIGESTLENGTH);
+ isc_hmacsha256_update(&hmacsha256, cp, 8);
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ switch (netaddr.family) {
+ case AF_INET:
+ isc_hmacsha256_update(&hmacsha256,
+ (unsigned char *)&netaddr.type.in, 4);
+ break;
+ case AF_INET6:
+ isc_hmacsha256_update(&hmacsha256,
+ (unsigned char *)&netaddr.type.in6, 16);
+ break;
+ }
+ isc_hmacsha256_update(&hmacsha256, client->cookie,
+ sizeof(client->cookie));
+ isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest));
+ isc_buffer_putmem(buf, digest, 8);
+ isc_hmacsha256_invalidate(&hmacsha256);
+#endif
+}
+
+static void
+process_sit(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
+ unsigned char dbuf[SIT_SIZE];
+ unsigned char *old;
+ isc_stdtime_t now;
+ isc_uint32_t when;
+ isc_uint32_t nonce;
+ isc_buffer_t db;
+
+ client->attributes |= NS_CLIENTATTR_WANTSIT;
+
+ isc_stats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sitopt);
+
+ if (optlen != SIT_SIZE) {
+ /*
+ * Not our token.
+ */
+ if (optlen >= 8U)
+ memcpy(client->cookie, isc_buffer_current(buf), 8);
+ else
+ memset(client->cookie, 0, 8);
+ isc_buffer_forward(buf, optlen);
+
+ if (optlen == 8)
+ isc_stats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sitnew);
+ else
+ isc_stats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sitbadsize);
+ return;
+ }
+
+ /*
+ * Process all of the incoming buffer.
+ */
+ old = isc_buffer_current(buf);
+ memcpy(client->cookie, old, 8);
+ isc_buffer_forward(buf, 8);
+ nonce = isc_buffer_getuint32(buf);
+ when = isc_buffer_getuint32(buf);
+ isc_buffer_forward(buf, 8);
+
+ /*
+ * Allow for a 5 minute clock skew between servers sharing a secret.
+ * Only accept SIT if we have talked to the client in the last hour.
+ */
+ isc_stdtime_get(&now);
+ if (isc_serial_gt(when, (now + 300)) || /* In the future. */
+ isc_serial_lt(when, (now - 3600))) { /* In the past. */
+ isc_stats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sitbadtime);
+ return;
+ }
+
+ isc_buffer_init(&db, dbuf, sizeof(dbuf));
+ compute_sit(client, when, nonce, &db);
+
+ if (memcmp(old, dbuf, SIT_SIZE) != 0) {
+ isc_stats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sitnomatch);
+ return;
+ }
+ isc_stats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sitmatch);
+
+ client->attributes |= NS_CLIENTATTR_HAVESIT;
+}
+#endif
+
static isc_result_t
process_opt(ns_client_t *client, dns_rdataset_t *opt) {
dns_rdata_t rdata;
@@ -1520,6 +1746,11 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
client->attributes |= NS_CLIENTATTR_WANTNSID;
isc_buffer_forward(&optbuf, optlen);
break;
+#ifdef ISC_PLATFORM_USESIT
+ case DNS_OPT_SIT:
+ process_sit(client, &optbuf, optlen);
+ break;
+#endif
default:
isc_buffer_forward(&optbuf, optlen);
break;
diff --git a/bin/named/config.c b/bin/named/config.c
index 22d31bed69..55155726a3 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -112,6 +112,14 @@ options {\n\
use-ixfr true;\n\
edns-udp-size 4096;\n\
max-udp-size 4096;\n\
+"
+#ifdef ISC_PLATFORM_USESIT
+"\
+ nosit-udp-size 4096;\n\
+ request-sit true;\n\
+"
+#endif
+"\
request-nsid false;\n\
reserved-sockets 512;\n\
\n\
diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h
index a1387c6557..870877fa2f 100644
--- a/bin/named/include/named/client.h
+++ b/bin/named/include/named/client.h
@@ -161,6 +161,7 @@ struct ns_client {
ISC_LINK(ns_client_t) link;
ISC_LINK(ns_client_t) rlink;
ISC_QLINK(ns_client_t) ilink;
+ unsigned char cookie[8];
};
typedef ISC_QUEUE(ns_client_t) client_queue_t;
@@ -180,6 +181,8 @@ typedef ISC_LIST(ns_client_t) client_list_t;
#define NS_CLIENTATTR_FILTER_AAAA_RC 0x080 /*%< recursing for A against AAAA */
#endif
#define NS_CLIENTATTR_WANTAD 0x100 /*%< want AD in response if possible */
+#define NS_CLIENTATTR_WANTSIT 0x200 /*%< include SIT */
+#define NS_CLIENTATTR_HAVESIT 0x400 /*%< has a valid SIT */
extern unsigned int ns_client_requests;
diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h
index 6c968fcdc2..246f516c75 100644
--- a/bin/named/include/named/server.h
+++ b/bin/named/include/named/server.h
@@ -116,6 +116,7 @@ struct ns_server {
unsigned int session_keyalg;
isc_uint16_t session_keybits;
isc_boolean_t interface_auto;
+ unsigned char secret[33]; /*%< Source Identity Token */
};
#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R')
@@ -179,7 +180,18 @@ enum {
dns_nsstatscounter_udp = 41,
dns_nsstatscounter_tcp = 42,
+#ifdef ISC_PLATFORM_USESIT
+ dns_nsstatscounter_sitopt = 43,
+ dns_nsstatscounter_sitbadsize = 44,
+ dns_nsstatscounter_sitbadtime = 45,
+ dns_nsstatscounter_sitnomatch = 46,
+ dns_nsstatscounter_sitmatch = 47,
+ dns_nsstatscounter_sitnew = 48,
+
+ dns_nsstatscounter_max = 49
+#else
dns_nsstatscounter_max = 43
+#endif
};
void
diff --git a/bin/named/query.c b/bin/named/query.c
index ce4bce34fd..2ffd7dec98 100644
--- a/bin/named/query.c
+++ b/bin/named/query.c
@@ -98,6 +98,13 @@
/*% Want WANTAD? */
#define WANTAD(c) (((c)->attributes & \
NS_CLIENTATTR_WANTAD) != 0)
+#ifdef ISC_PLATFORM_USESIT
+/*% Client presented a valid Source Identity Token. */
+#define HAVESIT(c) (((c)->attributes & \
+ NS_CLIENTATTR_HAVESIT) != 0)
+#else
+#define HAVESIT(c) (0)
+#endif
/*% No authority? */
#define NOAUTHORITY(c) (((c)->query.attributes & \
@@ -6371,7 +6378,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* Don't mess with responses rewritten by RPZ
* Count each response at most once.
*/
- if (client->view->rrl != NULL &&
+ if (client->view->rrl != NULL && !HAVESIT(client) &&
((fname != NULL && dns_name_isabsolute(fname)) ||
(result == ISC_R_NOTFOUND && !RECURSIONOK(client))) &&
!(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) &&
diff --git a/bin/named/server.c b/bin/named/server.c
index ad5449c821..675e200f2c 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -53,6 +54,12 @@
#include
#include
+#ifdef AES_SIT
+#include
+#else
+#include
+#endif
+
#include
#include
@@ -1157,6 +1164,13 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
if (obj != NULL)
CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj)));
+#ifdef ISC_PLATFORM_USESIT
+ obj = NULL;
+ (void)cfg_map_get(cpeer, "request-sit", &obj);
+ if (obj != NULL)
+ CHECK(dns_peer_setrequestsit(peer, cfg_obj_asboolean(obj)));
+#endif
+
obj = NULL;
(void)cfg_map_get(cpeer, "edns", &obj);
if (obj != NULL)
@@ -2999,6 +3013,21 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
udpsize = 4096;
view->maxudp = udpsize;
+#ifdef ISC_PLATFORM_USESIT
+ /*
+ * Set the maximum UDP when a SIT is not provided.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "nosit-udp-size", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ udpsize = cfg_obj_asuint32(obj);
+ if (udpsize < 128)
+ udpsize = 128;
+ if (udpsize > view->maxudp)
+ udpsize = view->maxudp;
+ view->situdp = udpsize;
+#endif
+
/*
* Set the maximum rsa exponent bits.
*/
@@ -3371,6 +3400,13 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
INSIST(result == ISC_R_SUCCESS);
view->requestnsid = cfg_obj_asboolean(obj);
+#ifdef ENABLE_LTR
+ obj = NULL;
+ result = ns_config_get(maps, "request-sit", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ view->requestsit = cfg_obj_asboolean(obj);
+#endif
+
obj = NULL;
result = ns_config_get(maps, "max-clients-per-query", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -4043,6 +4079,13 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
if (result != ISC_R_SUCCESS)
return (result);
+ result = isc_entropy_getdata(ns_g_entropy, view->secret,
+ sizeof(view->secret), NULL, 0);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+
#ifdef HAVE_GEOIP
view->aclenv.geoip = ns_g_geoip;
#endif
@@ -6153,6 +6196,43 @@ load_configuration(const char *filename, ns_server_t *server,
server->flushonshutdown = ISC_FALSE;
}
+#ifdef ENABLE_LTR
+ obj = NULL;
+ result = ns_config_get(maps, "sit-secret", &obj);
+ if (result == ISC_R_SUCCESS) {
+ isc_buffer_t b;
+
+ memset(server->secret, 0, sizeof(server->secret));
+ isc_buffer_init(&b, server->secret, sizeof(server->secret));
+ result = isc_hex_decodestring(cfg_obj_asstring(obj), &b);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
+ goto cleanup;
+#ifdef AES_SIT
+ if (isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH)
+ CHECKM(ISC_R_RANGE,
+ "AES sit-secret must be on 128 bits");
+#endif
+#ifdef HMAC_SHA1_SIT
+ if (isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH)
+ CHECKM(ISC_R_RANGE,
+ "SHA1 sit-secret must be on 160 bits");
+#endif
+#ifdef HMAC_SHA256_SIT
+ if (isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH)
+ CHECKM(ISC_R_RANGE,
+ "SHA256 sit-secret must be on 160 bits");
+#endif
+ } else {
+ result = isc_entropy_getdata(ns_g_entropy,
+ server->secret,
+ sizeof(server->secret),
+ NULL,
+ 0);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+#endif
+
result = ISC_R_SUCCESS;
cleanup:
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index 04c7282d14..056391768e 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -220,6 +220,19 @@ init_desc(void) {
"RPZRewrites");
SET_NSSTATDESC(udp, "UDP queries received", "QryUDP");
SET_NSSTATDESC(tcp, "TCP queries received", "QryTCP");
+#ifdef ISC_PLATFORM_USESIT
+ SET_NSSTATDESC(sitopt, "source identity token option received",
+ "SitOpt");
+ SET_NSSTATDESC(sitnew, "new source identity token requested",
+ "SitNew");
+ SET_NSSTATDESC(sitbadsize, "source identity token - bad size",
+ "SitBadSize");
+ SET_NSSTATDESC(sitbadtime, "source identity token - bad time",
+ "SitBadTime");
+ SET_NSSTATDESC(sitnomatch, "source identity token - no match",
+ "SitNoMatch");
+ SET_NSSTATDESC(sitmatch, "source identity token - match", "SitMatch");
+#endif
INSIST(i == dns_nsstatscounter_max);
/* Initialize resolver statistics */
@@ -295,6 +308,15 @@ init_desc(void) {
SET_RESSTATDESC(nfetch, "active fetches", "NumFetch");
SET_RESSTATDESC(buckets, "bucket size", "BucketSize");
SET_RESSTATDESC(refused, "REFUSED received", "REFUSED");
+#ifdef ISC_PLATFORM_USESIT
+ SET_RESSTATDESC(sitcc, "SIT sent client cookie only",
+ "SitClientOut");
+ SET_RESSTATDESC(sitout, "SIT sent with client and server cookie",
+ "SitOut");
+ SET_RESSTATDESC(sitin, "SIT replies received", "SitIn");
+ SET_RESSTATDESC(sitok, "SIT client cookie ok", "SitClientOk");
+#endif
+
INSIST(i == dns_resstatscounter_max);
/* Initialize adb statistics */
diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
index 80141341d5..559fcbb13a 100644
--- a/bin/tests/system/conf.sh.in
+++ b/bin/tests/system/conf.sh.in
@@ -70,7 +70,7 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
forward glue gost ixfr inline limits logfileconfig lwresd
masterfile masterformat metadata notify nsupdate pending
@PKCS11_TEST@ redirect resolver rndc rpz rrl rrchecker
- rrsetorder rsabigexponent smartsign sortlist spf staticstub
+ rrsetorder rsabigexponent sit smartsign sortlist spf staticstub
statistics stub tkey tsig tsiggss unknown upforwd verify
views wildcard xfer xferquota zero zonechecks"
diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh
index 81d2b2b88c..b68dcb40b1 100644
--- a/bin/tests/system/dnssec/tests.sh
+++ b/bin/tests/system/dnssec/tests.sh
@@ -2081,7 +2081,7 @@ echo server 10.53.0.3 5300
echo update add fail.nosign.example 300 in txt "reject me"
echo send
) | $NSUPDATE > /dev/null 2>&1 && ret=1
-$DIG +noall +answer +dnssec -p 5300 fail.nosign.example txt @10.53.0.3 \
+$DIG +tcp +noall +answer +dnssec -p 5300 fail.nosign.example txt @10.53.0.3 \
> dig.out.ns3.test$n 2>&1
[ -s dig.out.ns3.test$n ] && ret=1
n=`expr $n + 1`
diff --git a/bin/tests/system/sit/.gitignore b/bin/tests/system/sit/.gitignore
new file mode 100644
index 0000000000..eee491d3c6
--- /dev/null
+++ b/bin/tests/system/sit/.gitignore
@@ -0,0 +1 @@
+prereq.sh
diff --git a/bin/tests/system/sit/clean.sh b/bin/tests/system/sit/clean.sh
new file mode 100644
index 0000000000..8f80f3d934
--- /dev/null
+++ b/bin/tests/system/sit/clean.sh
@@ -0,0 +1,2 @@
+rm -f dig.out.*
+rm -f ns1/named_dump.db
diff --git a/bin/tests/system/sit/ns1/example.db b/bin/tests/system/sit/ns1/example.db
new file mode 100644
index 0000000000..4619d8c4da
--- /dev/null
+++ b/bin/tests/system/sit/ns1/example.db
@@ -0,0 +1,13 @@
+@ SOA ns1 hostmaster.isc.org. 1 600 600 1200 600
+@ NS ns1
+ns1 A 10.53.0.1
+large TXT ( large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large )
diff --git a/bin/tests/system/sit/ns1/named.conf b/bin/tests/system/sit/ns1/named.conf
new file mode 100644
index 0000000000..e43e24fdb0
--- /dev/null
+++ b/bin/tests/system/sit/ns1/named.conf
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm hmac-sha256;
+};
+
+controls {
+ inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
+};
+
+options {
+ query-source address 10.53.0.1 dscp 1;
+ notify-source 10.53.0.1 dscp 2;
+ transfer-source 10.53.0.1 dscp 3;
+ port 5300;
+ pid-file "named.pid";
+ listen-on { 10.53.0.1; };
+ listen-on-v6 { none; };
+ recursion yes;
+ acache-enable yes;
+ deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; }
+ except-from { "example.org"; };
+ deny-answer-aliases { "example.org"; }
+ except-from { "goodcname.example.net";
+ "gooddname.example.net"; };
+ allow-query {!10.53.0.8; any; };
+ sit-secret "9be998f9e2f1550e549fbec072727dc6";
+ request-sit yes;
+ nosit-udp-size 512;
+};
+
+zone "." {
+ type hint;
+ file "root.hint";
+};
+
+zone "example" {
+ type master;
+ file "example.db";
+};
diff --git a/bin/tests/system/sit/ns1/root.hint b/bin/tests/system/sit/ns1/root.hint
new file mode 100644
index 0000000000..2fd180e3ba
--- /dev/null
+++ b/bin/tests/system/sit/ns1/root.hint
@@ -0,0 +1,20 @@
+; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+; Copyright (C) 2000, 2001 Internet Software Consortium.
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: root.hint,v 1.7 2007/06/19 23:47:05 tbox Exp $
+
+$TTL 999999
+. IN NS a.root-servers.nil.
+a.root-servers.nil. IN A 10.53.0.2
diff --git a/bin/tests/system/sit/ns2/named.conf b/bin/tests/system/sit/ns2/named.conf
new file mode 100644
index 0000000000..04da91b277
--- /dev/null
+++ b/bin/tests/system/sit/ns2/named.conf
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+controls { /* empty */ };
+
+options {
+ query-source address 10.53.0.2 dscp 1;
+ notify-source 10.53.0.2 dscp 2;
+ transfer-source 10.53.0.2 dscp 3;
+ port 5300;
+ pid-file "named.pid";
+ listen-on { 10.53.0.2; };
+ listen-on-v6 { none; };
+ recursion no;
+ acache-enable yes;
+ request-sit yes;
+ nosit-udp-size 512;
+};
+
+zone "." {
+ type master;
+ file "root.db";
+};
diff --git a/bin/tests/system/sit/ns2/root.db b/bin/tests/system/sit/ns2/root.db
new file mode 100644
index 0000000000..49f3718a76
--- /dev/null
+++ b/bin/tests/system/sit/ns2/root.db
@@ -0,0 +1,13 @@
+@ SOA a.root-servers.nil. hostmaster.isc.org. 1 600 600 1200 600
+@ NS a.root-servers.nil.
+a.root-servers.nil. A 10.53.0.2
+large.xxx TXT ( large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large
+ large large large large large large large large )
diff --git a/bin/tests/system/sit/prereq.sh.in b/bin/tests/system/sit/prereq.sh.in
new file mode 100644
index 0000000000..da92848bf2
--- /dev/null
+++ b/bin/tests/system/sit/prereq.sh.in
@@ -0,0 +1,2 @@
+test "@HAVE_SIT@" = "" && exit 255
+exit 0
diff --git a/bin/tests/system/sit/tests.sh b/bin/tests/system/sit/tests.sh
new file mode 100755
index 0000000000..8173d704cf
--- /dev/null
+++ b/bin/tests/system/sit/tests.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Copyright (C) 2004, 2007, 2009-2014 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2000, 2001 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: tests.sh,v 1.22 2012/02/09 23:47:18 tbox Exp $
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+status=0
+n=0
+
+getsit() {
+ awk '$2 == "SIT:" {
+ print $3;
+ }' < $1
+}
+
+havetc() {
+ grep 'flags:.* tc[^;]*;' $1 > /dev/null
+}
+
+n=`expr $n + 1`
+echo "I:checking SIT token returned to empty SIT option ($n)"
+ret=0
+$DIG +qr +sit version.bind txt ch @10.53.0.1 -p 5300 > dig.out.test$n
+grep SIT: dig.out.test$n > /dev/null || ret=1
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking response size without SIT ($n)"
+ret=0
+$DIG large.example txt @10.53.0.1 -p 5300 +ignore > dig.out.test$n
+havetc dig.out.test$n || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking response size without valid SIT ($n)"
+ret=0
+$DIG +sit large.example txt @10.53.0.1 -p 5300 +ignore > dig.out.test$n
+havetc dig.out.test$n || ret=1
+grep ";; SIT client cookie part match" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking response size with SIT ($n)"
+ret=0
+$DIG +sit large.example txt @10.53.0.1 -p 5300 > dig.out.test$n.l
+sit=`getsit dig.out.test$n.l`
+$DIG +qr +sit=$sit large.example txt @10.53.0.1 -p 5300 +ignore > dig.out.test$n
+havetc dig.out.test$n && ret=1
+grep ";; SIT client cookie part match" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking response size with SIT recursive ($n)"
+ret=0
+$DIG +qr +sit=$sit large.xxx txt @10.53.0.1 -p 5300 +ignore > dig.out.test$n
+havetc dig.out.test$n && ret=1
+grep ";; SIT client cookie part match" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking for SIT value in adb ($n)"
+ret=0
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 dumpdb
+sleep 1
+grep "10.53.0.2.*\[sit=" ns1/named_dump.db > /dev/null|| ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:exit status: $status"
+exit $status
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
index bd0a5fee41..aefe0de1e9 100644
--- a/bin/tests/system/tkey/keycreate.c
+++ b/bin/tests/system/tkey/keycreate.c
@@ -189,8 +189,9 @@ sendquery(isc_task_t *task, isc_event_t *event) {
request = NULL;
result = dns_request_create(requestmgr, query, &address,
- 0, initialkey, TIMEOUT, task,
- recvquery, query, &request);
+ DNS_REQUESTOPT_TCP, initialkey,
+ TIMEOUT, task, recvquery, query,
+ &request);
CHECK("dns_request_create", result);
}
diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c
index 4c5f2c5027..c956b18399 100644
--- a/bin/tests/system/tkey/keydelete.c
+++ b/bin/tests/system/tkey/keydelete.c
@@ -132,8 +132,8 @@ sendquery(isc_task_t *task, isc_event_t *event) {
request = NULL;
result = dns_request_create(requestmgr, query, &address,
- 0, tsigkey, TIMEOUT, task,
- recvquery, query, &request);
+ DNS_REQUESTOPT_TCP, tsigkey, TIMEOUT,
+ task, recvquery, query, &request);
CHECK("dns_request_create", result);
}
diff --git a/config.h.in b/config.h.in
index 285d9299ae..c6dd731812 100644
--- a/config.h.in
+++ b/config.h.in
@@ -147,6 +147,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
+/* Use AES for Source Identity Token generation */
+#undef AES_SIT
+
/* Define to enable the "filter-aaaa-on-v4" and "filter-aaaa-on-v6" options.
*/
#undef ALLOW_FILTER_AAAA
@@ -170,6 +173,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to enable rpz-nsip rules. */
#undef ENABLE_RPZ_NSIP
+/* Define to enable 'sit' support. */
+#undef ENABLE_SIT
+
/* Solaris hack to get select_large_fdset. */
#undef FD_SETSIZE
@@ -422,6 +428,12 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
+/* Use HMAC-SHA1 for Source Identity Token generation */
+#undef HMAC_SHA1_SIT
+
+/* Use HMAC-SHA256 for Source Identity Token generation */
+#undef HMAC_SHA256_SIT
+
/* return type of gai_strerror */
#undef IRS_GAISTRERROR_RETURN_T
diff --git a/configure b/configure
index 598d044875..dce84f9f53 100755
--- a/configure
+++ b/configure
@@ -700,6 +700,8 @@ XSLTPROC
W3M
PDFLATEX
LATEX
+HAVE_SIT
+ISC_PLATFORM_USESIT
ISC_ARCH_DIR
ISC_PLATFORM_USEMACASM
ISC_PLATFORM_USESTDASM
@@ -816,6 +818,7 @@ PKCS11_TOOLS
USE_PKCS11
ISC_OPENSSL_LIBS
ISC_OPENSSL_INC
+ISC_PLATFORM_OPENSSLAES
ISC_PLATFORM_OPENSSLHASH
OPENSSL_GOST
OPENSSL_ECDSA
@@ -983,6 +986,8 @@ with_ecdsa
with_gost
enable_openssl_version_check
enable_openssl_hash
+enable_openssl_aes
+with_sit_alg
with_libxml2
with_libjson
enable_largefile
@@ -1002,6 +1007,7 @@ enable_fixed_rrset
enable_rpz_nsip
enable_rpz_nsdname
enable_filter_aaaa
+enable_sit
with_docbook_xsl
with_idn
with_libiconv
@@ -1652,25 +1658,25 @@ Optional Features:
--enable-threads enable multithreading
--enable-native-pkcs11 use native PKCS11 for all crypto [default=no]
--enable-openssl-version-check
- Check OpenSSL Version [default=yes]
+ check OpenSSL version [default=yes]
--enable-openssl-hash use OpenSSL for hash functions [default=no]
+ --enable-openssl-aes use OpenSSL for aes [default=no]
--enable-largefile 64-bit file support
--enable-backtrace log stack backtrace on abort [default=yes]
--enable-symtable use internal symbol table for backtrace
[all|minimal(default)|none]
--enable-ipv6 use IPv6 default=autodetect
- --enable-getifaddrs Enable the use of getifaddrs() [yes|no].
+ --enable-getifaddrs enable the use of getifaddrs() [yes|no].
--disable-isc-spnego use SPNEGO from GSSAPI library
--disable-chroot disable chroot
--disable-linux-caps disable linux capabilities
--enable-atomic enable machine specific atomic operations
[default=autodetect]
- --enable-fixed-rrset enable fixed rrset ordering
- [default=no]
+ --enable-fixed-rrset enable fixed rrset ordering [default=no]
--disable-rpz-nsip disable rpz-nsip rules [default=enabled]
--disable-rpz-nsdname disable rpz-nsdname rules [default=enabled]
- --enable-filter-aaaa enable filtering of AAAA records
- [default=no]
+ --enable-filter-aaaa enable filtering of AAAA records [default=no]
+ --enable-sit enable source identity token [default=no]
--enable-full-report report values of all configure options
Optional Packages:
@@ -1681,7 +1687,7 @@ Optional Packages:
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-sysroot=DIR Search for dependent libraries within DIR
(or the compiler's sysroot if not specified).
- --with-python=PATH Specify path to python interpreter
+ --with-python=PATH specify path to python interpreter
--with-geoip=PATH Build with GeoIP support (yes|no|path)
--with-gssapi=PATH Specify path for system-supplied GSSAPI [default=yes]
--with-randomdev=PATH Specify path for random device
@@ -1692,19 +1698,20 @@ Optional Packages:
(PATH is for the PKCS11 provider)
--with-ecdsa Crypto ECDSA
--with-gost Crypto GOST yes|no|raw|asn1.
- --with-libxml2=PATH Build with libxml2 library yes|no|path
- --with-libjson=PATH Build with libjson0 library yes|no|path
+ --with-sit-alg=ALG choose the algorithm for SIT [aes|sha1|sha256]
+ --with-libxml2=PATH build with libxml2 library yes|no|path
+ --with-libjson=PATH build with libjson0 library yes|no|path
--with-purify=PATH use Rational purify
--with-kame=PATH use Kame IPv6 default path /usr/local/v6
--with-readline=LIBSPEC specify readline library default -lreadline
- --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets
+ --with-docbook-xsl=PATH specify path for Docbook-XSL stylesheets
--with-idn=MPREFIX enable IDN support using idnkit default PREFIX
--with-libiconv=IPREFIX GNU libiconv are in IPREFIX default PREFIX
--with-iconv=LIBSPEC specify iconv library default -liconv
--with-idnlib=ARG specify libidnkit
- --with-atf=ARG Automated Test Framework support
- --with-dlopen=ARG Support dynamically loadable DLZ drivers
+ --with-atf=ARG support Automated Test Framework
+ --with-dlopen=ARG support dynamically loadable DLZ drivers
--with-dlz-postgres=PATH Build with Postgres DLZ driver yes|no|path.
(Required to use Postgres with DLZ)
--with-dlz-mysql=PATH Build with MySQL DLZ driver yes|no|path.
@@ -1719,7 +1726,7 @@ Optional Packages:
(Required to use ODBC with DLZ)
--with-dlz-stub=PATH Build with stub DLZ driver yes|no.
(Required to use stub driver with DLZ)
- --with-make-clean Run "make clean" at end of configure [yes|no].
+ --with-make-clean run "make clean" at end of configure [yes|no]
Some influential environment variables:
CC C compiler command
@@ -11381,6 +11388,7 @@ yes)
test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes
test "${with_dlz_filesystem+set}" = set || with_dlz_filesystem=yes
test "${enable_symtable+set}" = set || enable_symtable=all
+ test "${enable_sit+set}" = set || enable_sit=yes
;;
esac
#
@@ -15607,7 +15615,7 @@ esac
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DST_OPENSSL_LIBS"
#
-# Use OpenSSL for hash functions
+# Use OpenSSL for hash functions and/or aes
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for using OpenSSL for hash functions" >&5
@@ -15619,6 +15627,51 @@ else
want_openssl_hash="no"
fi
+
+# Check whether --enable-openssl-aes was given.
+if test "${enable_openssl_aes+set}" = set; then :
+ enableval=$enable_openssl_aes; want_openssl_aes="$enableval"
+else
+ want_openssl_aes="no"
+fi
+
+
+#
+# Source Identity Token algorithm choice
+#
+
+# Check whether --with-sit-alg was given.
+if test "${with_sit_alg+set}" = set; then :
+ withval=$with_sit_alg; with_sit_alg="$withval"
+else
+ with_sit_alg="aes"
+fi
+
+
+case $with_sit_alg in
+ *1)
+ with_sit_alg="sha1"
+ want_openssl_hash="yes"
+
+$as_echo "#define HMAC_SHA1_SIT 1" >>confdefs.h
+
+ ;;
+ *2*)
+ with_sit_alg="sha256"
+ want_openssl_hash="yes"
+
+$as_echo "#define HMAC_SHA256_SIT 1" >>confdefs.h
+
+ ;;
+ *)
+ with_sit_alg="aes"
+ want_openssl_aes="yes"
+
+$as_echo "#define AES_SIT 1" >>confdefs.h
+
+ ;;
+esac
+
case $want_openssl_hash in
yes)
if test "$CRYPTO" = ""
@@ -15639,6 +15692,20 @@ $as_echo "no" >&6; }
ISC_OPENSSL_LIBS=""
;;
esac
+case $want_openssl_aes in
+ yes)
+ if test "$CRYPTO" = ""
+ then
+ as_fn_error $? "No OpenSSL for AES" "$LINENO" 5
+ fi
+ ISC_PLATFORM_OPENSSLAES="#define ISC_PLATFORM_OPENSSLAES 1"
+ ISC_OPENSSL_INC="$DST_OPENSSL_INC"
+ ;;
+ no)
+ ISC_PLATFORM_OPENSSLAES="#undef ISC_PLATFORM_OPENSSLAES"
+ ;;
+esac
+
@@ -18941,6 +19008,37 @@ $as_echo "#define ALLOW_FILTER_AAAA 1" >>confdefs.h
;;
esac
+#
+# Enable Source Identity Token support
+#
+# Check whether --enable-sit was given.
+if test "${enable_sit+set}" = set; then :
+ enableval=$enable_sit; enable_sit="$enableval"
+else
+ enable_sit="no"
+fi
+
+
+ISC_PLATFORM_USESIT="#undef ISC_PLATFORM_USESIT"
+HAVE_SIT=
+
+case "$enable_sit" in
+yes)
+
+$as_echo "#define ENABLE_SIT 1" >>confdefs.h
+
+ ISC_PLATFORM_USESIT="#define ISC_PLATFORM_USESIT 1"
+ HAVE_SIT=1
+ ;;
+no)
+ ;;
+*)
+ as_fn_error $? "\"enable-sit requires yes or no\"" "$LINENO" 5
+ ;;
+esac
+
+
+
#
# The following sets up how non-blocking i/o is established.
# Sunos, cygwin and solaris 2.x (x<5) require special handling.
@@ -19709,9 +19807,6 @@ $as_echo "#define ATF_TEST 1" >>confdefs.h
STD_CINCLUDES="$STD_CINCLUDES -I$atf/include"
ATFBIN="$atf/bin"
ATFLIBS="-L$atf/lib -latf-c"
- if test "$want_openssl_hash" = yes; then
- ATFLIBS="-L$atf/lib -latf-c $DNS_CRYPTO_LIBS"
- fi
UNITTESTS=tests
fi
@@ -20996,7 +21091,7 @@ ac_config_commands="$ac_config_commands chmod"
# elsewhere if there's a good reason for doing so.
#
-ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delve/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/dlzredir/prereq.sh bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh"
+ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delve/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/dlzredir/prereq.sh bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh"
#
@@ -22047,6 +22142,7 @@ do
"bin/tests/system/geoip/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/geoip/Makefile" ;;
"bin/tests/system/inline/checkdsa.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/inline/checkdsa.sh" ;;
"bin/tests/system/lwresd/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/lwresd/Makefile" ;;
+ "bin/tests/system/sit/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/sit/prereq.sh" ;;
"bin/tests/system/rpz/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rpz/Makefile" ;;
"bin/tests/system/rsabigexponent/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rsabigexponent/Makefile" ;;
"bin/tests/system/tkey/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/tkey/Makefile" ;;
@@ -23427,6 +23523,12 @@ echo "Optional features enabled:"
$use_threads && echo " Multiprocessing support (--enable-threads)"
test "$use_geoip" = "no" || echo " GeoIP access control (--with-geoip)"
test "$use_gssapi" = "no" || echo " GSS-API (--with-gssapi)"
+if test "$enable_sit" != "no"; then
+ echo " Source Identity Token support (--enable-sit)"
+ if test "$enable_full_report" = "yes" -o "$with_sit_alg" != "aes"; then
+ echo " Algorithm: $with_sit_alg"
+ fi
+fi
# these lines are only printed if run with --enable-full-report
if test "$enable_full_report" = "yes"; then
@@ -23490,6 +23592,8 @@ test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" && \
test "$use_geoip" = "no" && echo " GeoIP access control (--with-geoip)"
test "$use_gssapi" = "no" && echo " GSS-API (--with-gssapi)"
+test "$enable_sit" = "no" && echo " Source Identity Token support (--enable-sit)"
+
test "$enable_fixed" = "yes" || \
echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)"
diff --git a/configure.in b/configure.in
index 6f31037b9c..e7dd058782 100644
--- a/configure.in
+++ b/configure.in
@@ -74,6 +74,7 @@ yes)
test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes
test "${with_dlz_filesystem+set}" = set || with_dlz_filesystem=yes
test "${enable_symtable+set}" = set || enable_symtable=all
+ test "${enable_sit+set}" = set || enable_sit=yes
;;
esac
#
@@ -136,7 +137,7 @@ AC_SUBST(PERL)
# If python is unavailable, we simply don't build those.
#
AC_ARG_WITH(python,
-[ --with-python=PATH Specify path to python interpreter],
+[ --with-python=PATH specify path to python interpreter],
use_python="$withval", use_python="unspec")
case "$use_python" in
@@ -1335,7 +1336,7 @@ shared library configuration (e.g., LD_LIBRARY_PATH).)],
AC_ARG_ENABLE(openssl-version-check,
[AC_HELP_STRING([--enable-openssl-version-check],
- [Check OpenSSL Version @<:@default=yes@:>@])])
+ [check OpenSSL version @<:@default=yes@:>@])])
case "$enable_openssl_version_check" in
yes|'')
AC_MSG_CHECKING(OpenSSL library version)
@@ -1516,13 +1517,46 @@ AC_SUBST(OPENSSL_GOST)
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DST_OPENSSL_LIBS"
#
-# Use OpenSSL for hash functions
+# Use OpenSSL for hash functions and/or aes
#
AC_MSG_CHECKING(for using OpenSSL for hash functions)
AC_ARG_ENABLE(openssl-hash,
[ --enable-openssl-hash use OpenSSL for hash functions [[default=no]]],
want_openssl_hash="$enableval", want_openssl_hash="no")
+
+AC_ARG_ENABLE(openssl-aes,
+ [ --enable-openssl-aes use OpenSSL for aes [[default=no]]],
+ want_openssl_aes="$enableval", want_openssl_aes="no")
+
+#
+# Source Identity Token algorithm choice
+#
+AC_ARG_WITH(sit-alg,
+ [ --with-sit-alg=ALG choose the algorithm for SIT [[aes|sha1|sha256]]],
+ with_sit_alg="$withval", with_sit_alg="aes")
+
+case $with_sit_alg in
+ *1)
+ with_sit_alg="sha1"
+ want_openssl_hash="yes"
+ AC_DEFINE(HMAC_SHA1_SIT, 1,
+ [Use HMAC-SHA1 for Source Identity Token generation])
+ ;;
+ *2*)
+ with_sit_alg="sha256"
+ want_openssl_hash="yes"
+ AC_DEFINE(HMAC_SHA256_SIT, 1,
+ [Use HMAC-SHA256 for Source Identity Token generation])
+ ;;
+ *)
+ with_sit_alg="aes"
+ want_openssl_aes="yes"
+ AC_DEFINE(AES_SIT, 1,
+ [Use AES for Source Identity Token generation])
+ ;;
+esac
+
case $want_openssl_hash in
yes)
if test "$CRYPTO" = ""
@@ -1541,7 +1575,21 @@ case $want_openssl_hash in
ISC_OPENSSL_LIBS=""
;;
esac
+case $want_openssl_aes in
+ yes)
+ if test "$CRYPTO" = ""
+ then
+ AC_MSG_ERROR([No OpenSSL for AES])
+ fi
+ ISC_PLATFORM_OPENSSLAES="#define ISC_PLATFORM_OPENSSLAES 1"
+ ISC_OPENSSL_INC="$DST_OPENSSL_INC"
+ ;;
+ no)
+ ISC_PLATFORM_OPENSSLAES="#undef ISC_PLATFORM_OPENSSLAES"
+ ;;
+esac
AC_SUBST(ISC_PLATFORM_OPENSSLHASH)
+AC_SUBST(ISC_PLATFORM_OPENSSLAES)
AC_SUBST(ISC_OPENSSL_INC)
AC_SUBST(ISC_OPENSSL_LIBS)
@@ -1720,7 +1768,7 @@ fi
#
AC_MSG_CHECKING(for libxml2 library)
AC_ARG_WITH(libxml2,
-[ --with-libxml2[=PATH] Build with libxml2 library [yes|no|path]],
+[ --with-libxml2[=PATH] build with libxml2 library [yes|no|path]],
use_libxml2="$withval", use_libxml2="auto")
case "$use_libxml2" in
@@ -1762,7 +1810,7 @@ fi
#
AC_MSG_CHECKING(for json library)
AC_ARG_WITH(libjson,
-[ --with-libjson[=PATH] Build with libjson0 library [yes|no|path]],
+[ --with-libjson[=PATH] build with libjson0 library [yes|no|path]],
use_libjson="$withval", use_libjson="auto")
have_libjson=""
@@ -2626,7 +2674,7 @@ AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO)
AC_SUBST(ISC_IRS_GETNAMEINFOSOCKLEN)
AC_ARG_ENABLE(getifaddrs,
-[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
+[ --enable-getifaddrs enable the use of getifaddrs() [[yes|no]].],
want_getifaddrs="$enableval", want_getifaddrs="yes")
#
@@ -3294,8 +3342,7 @@ AC_SUBST(ISC_ARCH_DIR)
# Activate "rrset-order fixed" or not?
#
AC_ARG_ENABLE(fixed-rrset,
- [ --enable-fixed-rrset enable fixed rrset ordering
- [[default=no]]],
+ [ --enable-fixed-rrset enable fixed rrset ordering [[default=no]]],
enable_fixed="$enableval",
enable_fixed="no")
case "$enable_fixed" in
@@ -3349,8 +3396,7 @@ esac
# Activate "filter-aaaa-on-v4/v6" or not?
#
AC_ARG_ENABLE(filter-aaaa,
- [ --enable-filter-aaaa enable filtering of AAAA records
- [[default=no]]],
+ [ --enable-filter-aaaa enable filtering of AAAA records [[default=no]]],
enable_filter="$enableval",
enable_filter="no")
case "$enable_filter" in
@@ -3364,6 +3410,31 @@ case "$enable_filter" in
;;
esac
+#
+# Enable Source Identity Token support
+#
+AC_ARG_ENABLE(sit,
+ [ --enable-sit enable source identity token [[default=no]]],
+ enable_sit="$enableval", enable_sit="no")
+
+ISC_PLATFORM_USESIT="#undef ISC_PLATFORM_USESIT"
+HAVE_SIT=
+
+case "$enable_sit" in
+yes)
+ AC_DEFINE(ENABLE_SIT, 1, [Define to enable 'sit' support.])
+ ISC_PLATFORM_USESIT="#define ISC_PLATFORM_USESIT 1"
+ HAVE_SIT=1
+ ;;
+no)
+ ;;
+*)
+ AC_MSG_ERROR("enable-sit requires yes or no")
+ ;;
+esac
+AC_SUBST(ISC_PLATFORM_USESIT)
+AC_SUBST(HAVE_SIT)
+
#
# The following sets up how non-blocking i/o is established.
# Sunos, cygwin and solaris 2.x (x<5) require special handling.
@@ -3476,7 +3547,7 @@ AC_SUBST($1)
#
AC_MSG_CHECKING(for Docbook-XSL path)
AC_ARG_WITH(docbook-xsl,
-[ --with-docbook-xsl=PATH Specify path for Docbook-XSL stylesheets],
+[ --with-docbook-xsl=PATH specify path for Docbook-XSL stylesheets],
docbook_path="$withval", docbook_path="auto")
case "$docbook_path" in
auto)
@@ -3614,7 +3685,7 @@ AC_SUBST(IDNLIBS)
# Check whether to build Automated Test Framework unit tests
#
AC_ARG_WITH(atf,
- [ --with-atf=ARG Automated Test Framework support],
+ [ --with-atf=ARG support Automated Test Framework],
atf="$withval", atf="no")
if test "$atf" = yes; then
atf=`pwd`/unit/atf
@@ -3640,9 +3711,6 @@ if test "$atf" != no; then
STD_CINCLUDES="$STD_CINCLUDES -I$atf/include"
ATFBIN="$atf/bin"
ATFLIBS="-L$atf/lib -latf-c"
- if test "$want_openssl_hash" = yes; then
- ATFLIBS="-L$atf/lib -latf-c $DNS_CRYPTO_LIBS"
- fi
UNITTESTS=tests
fi
AC_SUBST(ATFBIN)
@@ -3778,7 +3846,7 @@ SO_LD=""
SO_TARGETS=""
AC_ARG_WITH(dlopen,
- [ --with-dlopen=ARG Support dynamically loadable DLZ drivers],
+ [ --with-dlopen=ARG support dynamically loadable DLZ drivers],
dlopen="$withval", dlopen="yes")
case $host in
@@ -4096,6 +4164,7 @@ AC_CONFIG_FILES([
bin/tests/system/geoip/Makefile
bin/tests/system/inline/checkdsa.sh
bin/tests/system/lwresd/Makefile
+ bin/tests/system/sit/prereq.sh
bin/tests/system/rpz/Makefile
bin/tests/system/rsabigexponent/Makefile
bin/tests/system/tkey/Makefile
@@ -4185,7 +4254,7 @@ AC_OUTPUT
# Now that the Makefiles exist we can ensure that everything is rebuilt.
#
AC_ARG_WITH(make-clean,
-[ --with-make-clean Run "make clean" at end of configure [[yes|no]].],
+[ --with-make-clean run "make clean" at end of configure [[yes|no]]],
make_clean="$withval", make_clean="yes")
case "$make_clean" in
yes)
@@ -4203,6 +4272,12 @@ echo "Optional features enabled:"
$use_threads && echo " Multiprocessing support (--enable-threads)"
test "$use_geoip" = "no" || echo " GeoIP access control (--with-geoip)"
test "$use_gssapi" = "no" || echo " GSS-API (--with-gssapi)"
+if test "$enable_sit" != "no"; then
+ echo " Source Identity Token support (--enable-sit)"
+ if test "$enable_full_report" = "yes" -o "$with_sit_alg" != "aes"; then
+ echo " Algorithm: $with_sit_alg"
+ fi
+fi
# these lines are only printed if run with --enable-full-report
if test "$enable_full_report" = "yes"; then
@@ -4266,6 +4341,8 @@ test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" && \
test "$use_geoip" = "no" && echo " GeoIP access control (--with-geoip)"
test "$use_gssapi" = "no" && echo " GSS-API (--with-gssapi)"
+test "$enable_sit" = "no" && echo " Source Identity Token support (--enable-sit)"
+
test "$enable_fixed" = "yes" || \
echo " Allow 'fixed' rrset-order (--enable-fixed-rrset)"
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index 84ad97f747..b99e75a725 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -4766,6 +4766,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
multiple-cnames yes_or_no;
notify yes_or_no | explicit | master-only;
recursion yes_or_no;
+ request-sit yes_or_no;
request-nsid yes_or_no;
rfc2308-type1 yes_or_no;
use-id-pool yes_or_no;
@@ -6228,6 +6229,35 @@ options {
+
+ request-sit
+
+ If yes, then a SIT (Source Identity
+ Token) EDNS option is sent along with the query. If the
+ resolver has previously talked to the server, the SIT
+ returned in the previous transaction is sent. This
+ is used by the server to determine whether the resolver
+ has talked to it before. A resolver sending the corret
+ SIT is assumed not to be an off-path attacker sending a
+ spoofed-source query; the query is therefore unlikely to
+ be part of a reflection/amplification attack: resolvers
+ sending a correct SIT option are not subject to response
+ rate limiting (RRL). Resolvers which do not send a correct
+ SIT option may be limited to receiving smaller responses
+ via the nosit-udp-size option.
+
+
+
+
+ sit-secret
+
+ If set, this is a shared secret used for generating and
+ verifying Source Identity Token EDNS options within a
+ anycast cluster. If not set the system will generation
+ a random secret at startup.
+
+
+
rfc2308-type1
@@ -10199,6 +10229,7 @@ rate-limit {
request-ixfr yes_or_no ;
edns yes_or_no ;
edns-udp-size number ;
+ nosit-udp-size number ;
max-udp-size number ;
transfers number ;
transfer-format ( one-answer | many-answers ) ; ]
@@ -10324,6 +10355,14 @@ rate-limit {
replies from named.
+
+ The nosit-udp-size option sets the
+ maximum size of udp responses that will be sent to
+ queries without a valid source identity token. The command
+ max-udp-size option may further limit
+ the response size.
+
+
The server supports two zone transfer methods. The first, one-answer,
uses one DNS message per resource record transferred. many-answers packs
diff --git a/doc/misc/options b/doc/misc/options
index 33718f74b8..39d09f1090 100644
--- a/doc/misc/options
+++ b/doc/misc/options
@@ -140,9 +140,9 @@ options {
fake-iquery ; // obsolete
fetch-glue ; // obsolete
files ;
- filter-aaaa { ; ... }; // not configured
- filter-aaaa-on-v4 ; // not configured
- filter-aaaa-on-v6 ; // not configured
+ filter-aaaa { ; ... };
+ filter-aaaa-on-v4 ;
+ filter-aaaa-on-v6 ;
flush-zones-on-shutdown ;
forward ( first | only );
forwarders [ port ] [ dscp ] { (
@@ -161,6 +161,8 @@ options {
; ... };
listen-on-v6 [ port ] [ dscp ] {
; ... };
+ sit-secret ;
+ nosit-udp-size ;
maintain-ixfr-base ; // obsolete
managed-keys-directory ;
masterfile-format ( text | raw | map );
@@ -230,6 +232,7 @@ options {
recursion ;
recursive-clients ;
request-ixfr ;
+ request-sit ;
request-nsid ;
reserved-sockets ;
resolver-query-timeout ;
@@ -304,6 +307,8 @@ server {
query-source ;
query-source-v6 ;
request-ixfr ;
+ request-sit ;
+ request-nsid ;
support-ixfr ; // obsolete
transfer-format ( many-answers | one-answer );
transfer-source ( | * ) [ port ( | * ) ] [
@@ -400,9 +405,9 @@ view {
empty-server ;
empty-zones-enable ;
fetch-glue ; // obsolete
- filter-aaaa { ; ... }; // not configured
- filter-aaaa-on-v4 ; // not configured
- filter-aaaa-on-v6 ; // not configured
+ filter-aaaa { ; ... };
+ filter-aaaa-on-v4 ;
+ filter-aaaa-on-v6 ;
forward ( first | only );
forwarders [ port ] [ dscp ] { (
| ) [ port ] [ dscp ]; ... };
@@ -414,6 +419,7 @@ view {
};
key-directory ;
lame-ttl ;
+ nosit-udp-size ;
maintain-ixfr-base ; // obsolete
managed-keys {
; ... };
@@ -475,6 +481,7 @@ view {
};
recursion ;
request-ixfr ;
+ request-sit ;
request-nsid ;
resolver-query-timeout ;
response-policy { zone [ policy ( given | disabled
@@ -503,6 +510,8 @@ view {
query-source ;
query-source-v6 ;
request-ixfr ;
+ request-sit ;
+ request-nsid ;
support-ixfr ; // obsolete
transfer-format ( many-answers | one-answer );
transfer-source ( | * ) [ port ( |
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index e411e274ab..f6d239137e 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -255,6 +255,8 @@ struct dns_adbentry {
unsigned char to1232; /* IPv6 nofrag */
unsigned char to512; /* plain DNS */
isc_sockaddr_t sockaddr;
+ unsigned char * sit;
+ isc_uint16_t sitlen;
isc_stdtime_t expires;
/*%<
@@ -1802,6 +1804,8 @@ new_adbentry(dns_adb_t *adb) {
e->to1432 = 0;
e->to1232 = 0;
e->to512 = 0;
+ e->sit = NULL;
+ e->sitlen = 0;
isc_random_get(&r);
e->srtt = (r & 0x1f) + 1;
e->expires = 0;
@@ -1838,6 +1842,9 @@ free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
e->magic = 0;
+ if (e->sit != NULL)
+ isc_mem_put(adb->mctx, e->sit, e->sitlen);
+
li = ISC_LIST_HEAD(e->lameinfo);
while (li != NULL) {
ISC_LIST_UNLINK(e->lameinfo, li, plink);
@@ -3425,6 +3432,16 @@ dump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug,
entry->to512, entry->plain, entry->plainto);
if (entry->udpsize != 0U)
fprintf(f, " [udpsize %u]", entry->udpsize);
+#ifdef ISC_PLATFORM_USESIT
+ if (entry->sit != NULL) {
+ unsigned int i;
+ fprintf(f, " [sit=");
+ for (i = 0; i < entry->sitlen; i++)
+ fprintf(f, "%02x", entry->sit[i]);
+ fprintf(f, "]");
+ }
+#endif
+
if (entry->expires != 0)
fprintf(f, " [ttl %d]", entry->expires - now);
fprintf(f, "\n");
@@ -4086,6 +4103,7 @@ dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
+
addr->entry->plain++;
if (addr->entry->plain == 0xff) {
addr->entry->edns >>= 1;
@@ -4242,6 +4260,59 @@ dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
return (size);
}
+void
+dns_adb_setsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
+ const unsigned char *sit, size_t len)
+{
+ int bucket;
+
+ REQUIRE(DNS_ADB_VALID(adb));
+ REQUIRE(DNS_ADBADDRINFO_VALID(addr));
+
+ bucket = addr->entry->lock_bucket;
+ LOCK(&adb->entrylocks[bucket]);
+
+ if (addr->entry->sit != NULL &&
+ (sit == NULL || len != addr->entry->sitlen)) {
+ isc_mem_put(adb->mctx, addr->entry->sit, addr->entry->sitlen);
+ addr->entry->sit = NULL;
+ addr->entry->sitlen = 0;
+ }
+
+ if (addr->entry->sit == NULL && sit != NULL && len != 0U) {
+ addr->entry->sit = isc_mem_get(adb->mctx, len);
+ if (addr->entry->sit != NULL)
+ addr->entry->sitlen = len;
+ }
+
+ if (addr->entry->sit != NULL)
+ memcpy(addr->entry->sit, sit, len);
+ UNLOCK(&adb->entrylocks[bucket]);
+}
+
+size_t
+dns_adb_getsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
+ unsigned char *sit, size_t len)
+{
+ int bucket;
+
+ REQUIRE(DNS_ADB_VALID(adb));
+ REQUIRE(DNS_ADBADDRINFO_VALID(addr));
+
+ bucket = addr->entry->lock_bucket;
+ LOCK(&adb->entrylocks[bucket]);
+ if (sit != NULL && addr->entry->sit != NULL &&
+ len >= addr->entry->sitlen)
+ {
+ memcpy(sit, addr->entry->sit, addr->entry->sitlen);
+ len = addr->entry->sitlen;
+ } else
+ len = 0;
+ UNLOCK(&adb->entrylocks[bucket]);
+
+ return (len);
+}
+
isc_result_t
dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
dns_adbaddrinfo_t **addrp, isc_stdtime_t now)
diff --git a/lib/dns/include/dns/adb.h b/lib/dns/include/dns/adb.h
index 0d4891a043..4cc8c9edc8 100644
--- a/lib/dns/include/dns/adb.h
+++ b/lib/dns/include/dns/adb.h
@@ -728,6 +728,32 @@ dns_adb_flushnames(dns_adb_t *adb, dns_name_t *name);
*\li 'name' is valid.
*/
+void
+dns_adb_setsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
+ const unsigned char *sit, size_t len);
+/*%<
+ * Record the Source Identity Token (SIT) associated with this addresss. If
+ * sit is NULL or len is zero. The recorded SIT is cleared.
+ *
+ * Requires:
+ *\li 'adb' is valid.
+ *\li 'addr' is valid.
+ */
+
+size_t
+dns_adb_getsit(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
+ unsigned char *sit, size_t len);
+/*
+ * Retieve the saved SIT value and store it in 'sit' which has size 'len'.
+ *
+ * Requires:
+ *\li 'adb' is valid.
+ *\li 'addr' is valid.
+ *
+ * Returns:
+ * The size of the sit token or zero if it doesn't fit in the buffer
+ * or it doesn't exist.
+ */
ISC_LANG_ENDDECLS
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index 889a7c31c4..6461b52ffb 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -106,6 +106,8 @@
/*%< EDNS0 extended OPT codes */
#define DNS_OPT_NSID 0x0003 /*%< NSID opt code */
#define DNS_OPT_CLIENT_SUBNET 0x0008 /*%< client subnet opt code */
+/*%< Experimental options [65001...65534] as per RFC6891 */
+#define DNS_OPT_SIT 65001 /*%< SIT opt code */
#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
@@ -1391,7 +1393,6 @@ dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
* \li other.
*/
-
ISC_LANG_ENDDECLS
#endif /* DNS_MESSAGE_H */
diff --git a/lib/dns/include/dns/peer.h b/lib/dns/include/dns/peer.h
index 49c79c15b7..619697ceb0 100644
--- a/lib/dns/include/dns/peer.h
+++ b/lib/dns/include/dns/peer.h
@@ -74,6 +74,7 @@ struct dns_peer {
isc_boolean_t request_ixfr;
isc_boolean_t support_edns;
isc_boolean_t request_nsid;
+ isc_boolean_t request_sit;
dns_name_t *key;
isc_sockaddr_t *transfer_source;
isc_dscp_t transfer_dscp;
@@ -159,6 +160,12 @@ dns_peer_setrequestnsid(dns_peer_t *peer, isc_boolean_t newval);
isc_result_t
dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval);
+isc_result_t
+dns_peer_setrequestsit(dns_peer_t *peer, isc_boolean_t newval);
+
+isc_result_t
+dns_peer_getrequestsit(dns_peer_t *peer, isc_boolean_t *retval);
+
isc_result_t
dns_peer_setsupportedns(dns_peer_t *peer, isc_boolean_t newval);
diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h
index a6b938e9cc..eeff364e41 100644
--- a/lib/dns/include/dns/stats.h
+++ b/lib/dns/include/dns/stats.h
@@ -66,8 +66,16 @@ enum {
dns_resstatscounter_dispreqtcp = 32,
dns_resstatscounter_buckets = 33,
dns_resstatscounter_refused = 34,
+#ifdef ISC_PLATFORM_USESIT
+ dns_resstatscounter_sitcc = 35,
+ dns_resstatscounter_sitout = 36,
+ dns_resstatscounter_sitin = 37,
+ dns_resstatscounter_sitok = 38,
+ dns_resstatscounter_max = 39,
+#else
dns_resstatscounter_max = 35,
+#endif
/*
* DNSSEC stats.
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index 676eef336d..bba7e1aeb6 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -148,6 +148,7 @@ struct dns_view {
dns_rrl_t * rrl;
isc_boolean_t provideixfr;
isc_boolean_t requestnsid;
+ isc_boolean_t requestsit;
dns_ttl_t maxcachettl;
dns_ttl_t maxncachettl;
dns_ttl_t prefetch_trigger;
@@ -163,6 +164,7 @@ struct dns_view {
dns_name_t * dlv;
dns_fixedname_t dlv_fixed;
isc_uint16_t maxudp;
+ isc_uint16_t situdp;
unsigned int maxbits;
dns_aaaa_t v4_aaaa;
dns_aaaa_t v6_aaaa;
@@ -204,6 +206,8 @@ struct dns_view {
char * new_zone_file;
void * new_zone_config;
void (*cfg_destroy)(void **);
+
+ unsigned char secret[33]; /* Client secret */
};
#define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w')
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 781ec2bc34..20358195ca 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -3255,6 +3255,8 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
if (optcode == DNS_OPT_NSID) {
ADD_STRING(target, "; NSID");
+ } else if (optcode == DNS_OPT_SIT) {
+ ADD_STRING(target, "; SIT");
} else {
ADD_STRING(target, "; OPT=");
sprintf(buf, "%u", optcode);
@@ -3267,10 +3269,30 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
optdata = isc_buffer_current(&optbuf);
for (i = 0; i < optlen; i++) {
- sprintf(buf, "%02x ", optdata[i]);
+ const char *sep;
+ switch (optcode) {
+ case DNS_OPT_SIT:
+ sep = "";
+ break;
+ default:
+ sep = " ";
+ break;
+ }
+ sprintf(buf, "%02x%s", optdata[i], sep);
ADD_STRING(target, buf);
}
+ isc_buffer_forward(&optbuf, optlen);
+
+ if (optcode == DNS_OPT_SIT) {
+ ADD_STRING(target, "\n");
+ break;
+ }
+
+ /*
+ * For non-SIT options, add a printable
+ * version
+ */
ADD_STRING(target, "(\"");
for (i = 0; i < optlen; i++) {
if (isprint(optdata[i]))
@@ -3281,7 +3303,6 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
isc_buffer_putstr(target, ".");
}
ADD_STRING(target, "\")");
- isc_buffer_forward(&optbuf, optlen);
}
ADD_STRING(target, "\n");
}
diff --git a/lib/dns/peer.c b/lib/dns/peer.c
index 3e4184e37c..5108145686 100644
--- a/lib/dns/peer.c
+++ b/lib/dns/peer.c
@@ -43,6 +43,7 @@
#define SERVER_UDPSIZE_BIT 6
#define SERVER_MAXUDP_BIT 7
#define REQUEST_NSID_BIT 8
+#define REQUEST_SIT_BIT 9
static void
peerlist_delete(dns_peerlist_t **list);
@@ -447,6 +448,32 @@ dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval) {
return (ISC_R_NOTFOUND);
}
+isc_result_t
+dns_peer_setrequestsit(dns_peer_t *peer, isc_boolean_t newval) {
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_PEER_VALID(peer));
+
+ existed = DNS_BIT_CHECK(REQUEST_SIT_BIT, &peer->bitflags);
+
+ peer->request_sit = newval;
+ DNS_BIT_SET(REQUEST_SIT_BIT, &peer->bitflags);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_peer_getrequestsit(dns_peer_t *peer, isc_boolean_t *retval) {
+ REQUIRE(DNS_PEER_VALID(peer));
+ REQUIRE(retval != NULL);
+
+ if (DNS_BIT_CHECK(REQUEST_SIT_BIT, &peer->bitflags)) {
+ *retval = peer->request_nsid;
+ return (ISC_R_SUCCESS);
+ } else
+ return (ISC_R_NOTFOUND);
+}
+
isc_result_t
dns_peer_settransfers(dns_peer_t *peer, isc_uint32_t newval) {
isc_boolean_t existed;
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 4cb4515839..e0c765d51e 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -32,6 +32,12 @@
#include
#include
+#ifdef AES_SIT
+#include
+#else
+#include
+#endif
+
#include
#include
#include
@@ -1733,6 +1739,83 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link);
}
+#ifdef ISC_PLATFORM_USESIT
+static void
+compute_cc(resquery_t *query, unsigned char *sit, size_t len) {
+#ifdef AES_SIT
+ unsigned char digest[ISC_AES_BLOCK_LENGTH];
+ unsigned char input[16];
+ isc_netaddr_t netaddr;
+ unsigned int i;
+
+ INSIST(len >= 8U);
+
+ isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
+ switch (netaddr.family) {
+ case AF_INET:
+ memcpy(input, (unsigned char *)&netaddr.type.in, 4);
+ memset(input + 4, 0, 12);
+ break;
+ case AF_INET6:
+ memcpy(input, (unsigned char *)&netaddr.type.in6, 16);
+ break;
+ }
+ isc_aes128_crypt(query->fctx->res->view->secret, input, digest);
+ for (i = 0; i < 8; i++)
+ digest[i] ^= digest[i + 8];
+ memcpy(sit, digest, 8);
+#endif
+#ifdef HMAC_SHA1_SIT
+ unsigned char digest[ISC_SHA1_DIGESTLENGTH];
+ isc_netaddr_t netaddr;
+ isc_hmacsha1_t hmacsha1;
+
+ INSIST(len >= 8U);
+
+ isc_hmacsha1_init(&hmacsha1, query->fctx->res->view->secret,
+ ISC_SHA1_DIGESTLENGTH);
+ isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
+ switch (netaddr.family) {
+ case AF_INET:
+ isc_hmacsha1_update(&hmacsha1,
+ (unsigned char *)&netaddr.type.in, 4);
+ break;
+ case AF_INET6:
+ isc_hmacsha1_update(&hmacsha1,
+ (unsigned char *)&netaddr.type.in6, 16);
+ break;
+ }
+ isc_hmacsha1_sign(&hmacsha1, digest, sizeof(digest));
+ memcpy(sit, digest, 8);
+ isc_hmacsha1_invalidate(&hmacsha1);
+#endif
+#ifdef HMAC_SHA256_SIT
+ unsigned char digest[ISC_SHA256_DIGESTLENGTH];
+ isc_netaddr_t netaddr;
+ isc_hmacsha256_t hmacsha256;
+
+ INSIST(len >= 8U);
+
+ isc_hmacsha256_init(&hmacsha256, query->fctx->res->view->secret,
+ ISC_SHA256_DIGESTLENGTH);
+ isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr);
+ switch (netaddr.family) {
+ case AF_INET:
+ isc_hmacsha256_update(&hmacsha256,
+ (unsigned char *)&netaddr.type.in, 4);
+ break;
+ case AF_INET6:
+ isc_hmacsha256_update(&hmacsha256,
+ (unsigned char *)&netaddr.type.in6, 16);
+ break;
+ }
+ isc_hmacsha256_sign(&hmacsha256, digest, sizeof(digest));
+ memcpy(sit, digest, 8);
+ isc_hmacsha256_invalidate(&hmacsha256);
+#endif
+}
+#endif
+
static isc_result_t
resquery_send(resquery_t *query) {
fetchctx_t *fctx;
@@ -1758,10 +1841,6 @@ resquery_send(resquery_t *query) {
unsigned ednsopt = 0;
isc_uint16_t hint = 0, udpsize = 0; /* No EDNS */
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_format(&query->addrinfo->sockaddr,
- addrbuf, sizeof(addrbuf));
-
fctx = query->fctx;
QTRACE("send");
@@ -1935,6 +2014,10 @@ resquery_send(resquery_t *query) {
unsigned int version = 0; /* Default version. */
unsigned int flags = query->addrinfo->flags;
isc_boolean_t reqnsid = res->view->requestnsid;
+#ifdef ISC_PLATFORM_USESIT
+ isc_boolean_t reqsit = res->view->requestsit;
+ unsigned char sit[64];
+#endif
if ((flags & FCTX_ADDRINFO_EDNSOK) != 0 &&
(query->options & DNS_FETCHOPT_EDNS512) == 0) {
@@ -1974,9 +2057,13 @@ resquery_send(resquery_t *query) {
version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
}
- /* request NSID for current view or peer? */
- if (peer != NULL)
+ /* Request NSID/SIT for current view or peer? */
+ if (peer != NULL) {
(void) dns_peer_getrequestnsid(peer, &reqnsid);
+#ifdef ISC_PLATFORM_USESIT
+ (void) dns_peer_getrequestsit(peer, &reqsit);
+#endif
+ }
if (reqnsid) {
INSIST(ednsopt < EDNSOPTS);
ednsopts[ednsopt].code = DNS_OPT_NSID;
@@ -1984,6 +2071,28 @@ resquery_send(resquery_t *query) {
ednsopts[ednsopt].value = NULL;
ednsopt++;
}
+#ifdef ISC_PLATFORM_USESIT
+ if (reqsit) {
+ INSIST(ednsopt < EDNSOPTS);
+ ednsopts[ednsopt].code = DNS_OPT_SIT;
+ ednsopts[ednsopt].length =
+ dns_adb_getsit(fctx->adb,
+ query->addrinfo,
+ sit, sizeof(sit));
+ if (ednsopts[ednsopt].length != 0) {
+ ednsopts[ednsopt].value = sit;
+ inc_stats(fctx->res,
+ dns_resstatscounter_sitout);
+ } else {
+ compute_cc(query, sit, sizeof(sit));
+ ednsopts[ednsopt].value = sit;
+ ednsopts[ednsopt].length = 8;
+ inc_stats(fctx->res,
+ dns_resstatscounter_sitcc);
+ }
+ ednsopt++;
+ }
+#endif
result = fctx_addopt(fctx->qmessage, version,
udpsize, ednsopts, ednsopt);
if (reqnsid && result == ISC_R_SUCCESS) {
@@ -6896,6 +7005,11 @@ process_opt(resquery_t *query, dns_rdataset_t *opt) {
isc_result_t result;
isc_uint16_t optcode;
isc_uint16_t optlen;
+#ifdef ISC_PLATFORM_USESIT
+ unsigned char *sit;
+ dns_adbaddrinfo_t *addrinfo;
+ unsigned char cookie[8];
+#endif
result = dns_rdataset_first(opt);
if (result == ISC_R_SUCCESS) {
@@ -6915,6 +7029,23 @@ process_opt(resquery_t *query, dns_rdataset_t *opt) {
query->fctx->res->mctx);
isc_buffer_forward(&optbuf, optlen);
break;
+#ifdef ISC_PLATFORM_USESIT
+ case DNS_OPT_SIT:
+ sit = isc_buffer_current(&optbuf);
+ compute_cc(query, cookie, sizeof(cookie));
+ if (optlen >= 8U &&
+ memcmp(cookie, sit, 8) == 0) {
+ inc_stats(query->fctx->res,
+ dns_resstatscounter_sitok);
+ addrinfo = query->addrinfo;
+ dns_adb_setsit(query->fctx->adb,
+ addrinfo, sit, optlen);
+ }
+ isc_buffer_forward(&optbuf, optlen);
+ inc_stats(query->fctx->res,
+ dns_resstatscounter_sitin);
+ break;
+#endif
default:
isc_buffer_forward(&optbuf, optlen);
break;
diff --git a/lib/dns/view.c b/lib/dns/view.c
index b6349e2201..f0b323c651 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -195,6 +195,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->flush = ISC_FALSE;
view->dlv = NULL;
view->maxudp = 0;
+ view->situdp = 0;
view->maxbits = 0;
view->v4_aaaa = dns_aaaa_ok;
view->v6_aaaa = dns_aaaa_ok;
@@ -203,6 +204,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
dns_fixedname_init(&view->dlv_fixed);
view->managed_keys = NULL;
view->redirect = NULL;
+ view->requestnsid = ISC_FALSE;
+ view->requestsit = ISC_TRUE;
view->new_zone_file = NULL;
view->new_zone_config = NULL;
view->cfg_destroy = NULL;
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in
index 7614e7dd68..6dce1169e0 100644
--- a/lib/isc/Makefile.in
+++ b/lib/isc/Makefile.in
@@ -55,7 +55,7 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
# Alphabetically
OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ \
- assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
+ aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
bind9.@O@ buffer.@O@ bufferlist.@O@ \
commandline.@O@ crc64.@O@ error.@O@ event.@O@ \
hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
@@ -74,7 +74,7 @@ SYMTBLOBJS = backtrace-emptytbl.@O@
# Alphabetically
SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ \
- assertions.c backtrace.c base32.c base64.c bind9.c \
+ aes.c assertions.c backtrace.c base32.c base64.c bind9.c \
buffer.c bufferlist.c commandline.c crc64.c \
error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \
httpd.c inet_aton.c iterated_hash.c \
diff --git a/lib/isc/aes.c b/lib/isc/aes.c
new file mode 100644
index 0000000000..e0bbf80e52
--- /dev/null
+++ b/lib/isc/aes.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file isc/aes.c */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef ISC_PLATFORM_OPENSSLAES
+
+#ifndef EVP_AES
+
+#include
+
+void
+isc_aes128_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out)
+{
+ AES_KEY k;
+
+ RUNTIME_CHECK(AES_set_encrypt_key(key, 128, &k) == 0);
+ AES_encrypt(in, out, &k);
+}
+
+void
+isc_aes192_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out)
+{
+ AES_KEY k;
+
+ RUNTIME_CHECK(AES_set_encrypt_key(key, 192, &k) == 0);
+ AES_encrypt(in, out, &k);
+}
+
+void
+isc_aes256_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out)
+{
+ AES_KEY k;
+
+ RUNTIME_CHECK(AES_set_encrypt_key(key, 256, &k) == 0);
+ AES_encrypt(in, out, &k);
+}
+#else
+
+#include
+
+void
+isc_aes128_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out)
+{
+ EVP_CIPHER_CTX c;
+ int len;
+
+ EVP_CIPHER_CTX_init(&c);
+ RUNTIME_CHECK(EVP_EncryptInit(&c, EVP_aes_128_ecb(), key, NULL) == 1);
+ EVP_CIPHER_CTX_set_padding(&c, 0);
+ RUNTIME_CHECK(EVP_EncryptUpdate(&c, out, &len, in,
+ ISC_AES_BLOCK_LENGTH) == 1);
+ RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH);
+ RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(&c) == 1);
+}
+
+void
+isc_aes192_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out)
+{
+ EVP_CIPHER_CTX c;
+ int len;
+
+ EVP_CIPHER_CTX_init(&c);
+ RUNTIME_CHECK(EVP_EncryptInit(&c, EVP_aes_192_ecb(), key, NULL) == 1);
+ EVP_CIPHER_CTX_set_padding(&c, 0);
+ RUNTIME_CHECK(EVP_EncryptUpdate(&c, out, &len, in,
+ ISC_AES_BLOCK_LENGTH) == 1);
+ RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH);
+ RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(&c) == 1);
+}
+
+void
+isc_aes256_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out)
+{
+ EVP_CIPHER_CTX c;
+ int len;
+
+ EVP_CIPHER_CTX_init(&c);
+ RUNTIME_CHECK(EVP_EncryptInit(&c, EVP_aes_256_ecb(), key, NULL) == 1);
+ EVP_CIPHER_CTX_set_padding(&c, 0);
+ RUNTIME_CHECK(EVP_EncryptUpdate(&c, out, &len, in,
+ ISC_AES_BLOCK_LENGTH) == 1);
+ RUNTIME_CHECK(len == ISC_AES_BLOCK_LENGTH);
+ RUNTIME_CHECK(EVP_CIPHER_CTX_cleanup(&c) == 1);
+}
+#endif
+
+#endif
diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in
index bc99bd1ac4..15ff1e6291 100644
--- a/lib/isc/include/isc/Makefile.in
+++ b/lib/isc/include/isc/Makefile.in
@@ -26,7 +26,7 @@ top_srcdir = @top_srcdir@
# machine generated. The latter are handled specially in the
# install target below.
#
-HEADERS = app.h assertions.h base64.h bind9.h boolean.h buffer.h \
+HEADERS = aes.h app.h assertions.h base64.h bind9.h boolean.h buffer.h \
bufferlist.h commandline.h entropy.h error.h event.h \
eventclass.h file.h formatcheck.h fsaccess.h \
hash.h heap.h hex.h hmacmd5.h hmacsha.h \
diff --git a/lib/isc/include/isc/aes.h b/lib/isc/include/isc/aes.h
new file mode 100644
index 0000000000..1e3a9f4835
--- /dev/null
+++ b/lib/isc/include/isc/aes.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file isc/aes.h */
+
+#ifndef ISC_AES_H
+#define ISC_AES_H 1
+
+#include
+#include
+#include
+
+#ifdef ISC_PLATFORM_OPENSSLAES
+
+#define ISC_AES128_KEYLENGTH 16U
+#define ISC_AES192_KEYLENGTH 24U
+#define ISC_AES256_KEYLENGTH 32U
+#define ISC_AES_BLOCK_LENGTH 16U
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_aes128_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out);
+
+void
+isc_aes192_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out);
+
+void
+isc_aes256_crypt(const unsigned char *key, const unsigned char *in,
+ unsigned char *out);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_PLATFORM_OPENSSLAES */
+
+#endif /* ISC_AES_H */
diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in
index 07553e36b8..a26f12b47a 100644
--- a/lib/isc/include/isc/platform.h.in
+++ b/lib/isc/include/isc/platform.h.in
@@ -311,12 +311,22 @@
*/
@ISC_PLATFORM_OPENSSLHASH@
+/*
+ * Define if AES must be provided by OpenSSL.
+ */
+@ISC_PLATFORM_OPENSSLAES@
+
/*
* Defines for the noreturn attribute.
*/
@ISC_PLATFORM_NORETURN_PRE@
@ISC_PLATFORM_NORETURN_POST@
+/*
+ * Defined if we are enabling SIT (Source Identity Token).
+ */
+@ISC_PLATFORM_USESIT@
+
/***
*** Windows dll support.
***/
diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in
index 7a0da96b5f..997397d30d 100644
--- a/lib/isc/tests/Makefile.in
+++ b/lib/isc/tests/Makefile.in
@@ -29,7 +29,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I. -Iinclude ${ISC_INCLUDES}
CDEFINES = -DTESTS="\"${top_builddir}/lib/isc/tests/\""
-ISCLIBS = ../libisc.@A@
+ISCLIBS = ../libisc.@A@ @DNS_CRYPTO_LIBS@
ISCDEPLIBS = ../libisc.@A@
LIBS = @LIBS@ @ATFLIBS@
@@ -39,8 +39,7 @@ SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \
lex_test.c \
sockaddr_test.c symtab_test.c task_test.c queue_test.c \
parse_test.c pool_test.c regex_test.c socket_test.c \
- safe_test.c \
- time_test.c
+ safe_test.c time_test.c aes_test.c
SUBDIRS =
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
@@ -48,7 +47,7 @@ TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
sockaddr_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \
queue_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \
regex_test@EXEEXT@ socket_test@EXEEXT@ safe_test@EXEEXT@ \
- time_test@EXEEXT@
+ time_test@EXEEXT@ aes_test@EXEEXT@
@BIND9_MAKE_RULES@
@@ -104,6 +103,10 @@ time_test@EXEEXT@: time_test.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
time_test.@O@ ${ISCLIBS} ${LIBS}
+aes_test@EXEEXT@: aes_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ aes_test.@O@ ${ISCLIBS} ${LIBS}
+
unit::
sh ${top_srcdir}/unit/unittest.sh
diff --git a/lib/isc/tests/aes_test.c b/lib/isc/tests/aes_test.c
new file mode 100644
index 0000000000..c9497b88f8
--- /dev/null
+++ b/lib/isc/tests/aes_test.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* ! \file */
+
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef ISC_PLATFORM_OPENSSLAES
+
+/*
+ * Test data from NIST KAT
+ */
+
+isc_result_t
+tohexstr(unsigned char *d, char *out);
+
+size_t
+fromhexstr(const char *in, unsigned char *d);
+
+unsigned char plaintext[3 * ISC_AES_BLOCK_LENGTH];
+unsigned char ciphertext[ISC_AES_BLOCK_LENGTH];
+char str[2 * ISC_AES_BLOCK_LENGTH + 1];
+unsigned char key[ISC_AES256_KEYLENGTH + 1];
+size_t len;
+
+isc_result_t
+tohexstr(unsigned char *d, char *out) {
+ isc_buffer_t b;
+ isc_region_t r;
+
+ isc_buffer_init(&b, out, 2 * ISC_AES_BLOCK_LENGTH + 1);
+ r.base = d;
+ r.length = ISC_AES_BLOCK_LENGTH;
+ return (isc_hex_totext(&r, 0, "", &b));
+}
+
+size_t
+fromhexstr(const char *in, unsigned char *d)
+{
+ isc_buffer_t b;
+ isc_result_t ret;
+
+ isc_buffer_init(&b, d, ISC_AES256_KEYLENGTH + 1);
+ ret = isc_hex_decodestring(in, &b);
+ if (ret != ISC_R_SUCCESS)
+ return 0;
+ return isc_buffer_usedlength(&b);
+}
+
+typedef struct aes_testcase {
+ const char *key;
+ const char *input;
+ const char *result;
+} aes_testcase_t;
+
+
+ATF_TC(isc_aes128);
+ATF_TC_HEAD(isc_aes128, tc) {
+ atf_tc_set_md_var(tc, "descr", "AES 128 test vectors");
+}
+ATF_TC_BODY(isc_aes128, tc) {
+ UNUSED(tc);
+
+ aes_testcase_t testcases[] = {
+ /* Test 1 (KAT ECBVarTxt128 #3) */
+ {
+ "00000000000000000000000000000000",
+ "F0000000000000000000000000000000",
+ "96D9FD5CC4F07441727DF0F33E401A36"
+ },
+ /* Test 2 (KAT ECBVarTxt128 #123) */
+ {
+ "00000000000000000000000000000000",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "F9B0FDA0C4A898F5B9E6F661C4CE4D07"
+ },
+ /* Test 3 (KAT ECBVarKey128 #3) */
+ {
+ "F0000000000000000000000000000000",
+ "00000000000000000000000000000000",
+ "970014D634E2B7650777E8E84D03CCD8"
+ },
+ /* Test 4 (KAT ECBVarKey128 #123) */
+ {
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "00000000000000000000000000000000",
+ "41C78C135ED9E98C096640647265DA1E"
+ },
+ /* Test 5 (KAT ECBGFSbox128 #3) */
+ {
+ "00000000000000000000000000000000",
+ "6A118A874519E64E9963798A503F1D35",
+ "DC43BE40BE0E53712F7E2BF5CA707209"
+ },
+ /* Test 6 (KAT ECBKeySbox128 #3) */
+ {
+ "B6364AC4E1DE1E285EAF144A2415F7A0",
+ "00000000000000000000000000000000",
+ "5D9B05578FC944B3CF1CCF0E746CD581"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ aes_testcase_t *testcase = testcases;
+
+ while (testcase->key != NULL) {
+ len = fromhexstr(testcase->key, key);
+ ATF_CHECK_EQ(len, ISC_AES128_KEYLENGTH);
+ len = fromhexstr(testcase->input, plaintext);
+ ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH);
+ isc_aes128_crypt(key, plaintext, ciphertext);
+ ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_aes192);
+ATF_TC_HEAD(isc_aes192, tc) {
+ atf_tc_set_md_var(tc, "descr", "AES 192 test vectors");
+}
+ATF_TC_BODY(isc_aes192, tc) {
+ UNUSED(tc);
+
+ aes_testcase_t testcases[] = {
+ /* Test 1 (KAT ECBVarTxt192 #3) */
+ {
+ "000000000000000000000000000000000000000000000000",
+ "F0000000000000000000000000000000",
+ "2A560364CE529EFC21788779568D5555"
+ },
+ /* Test 2 (KAT ECBVarTxt192 #123) */
+ {
+ "000000000000000000000000000000000000000000000000",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "2AABB999F43693175AF65C6C612C46FB"
+ },
+ /* Test 3 (KAT ECBVarKey192 #3) */
+ {
+ "F00000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000",
+ "180B09F267C45145DB2F826C2582D35C"
+ },
+ /* Test 4 (KAT ECBVarKey192 #187) */
+ {
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "00000000000000000000000000000000",
+ "EACF1E6C4224EFB38900B185AB1DFD42"
+ },
+ /* Test 5 (KAT ECBGFSbox192 #3) */
+ {
+ "000000000000000000000000000000000000000000000000",
+ "51719783D3185A535BD75ADC65071CE1",
+ "4F354592FF7C8847D2D0870CA9481B7C"
+ },
+ /* Test 6 (KAT ECBKeySbox192 #3) */
+ {
+ "CD62376D5EBB414917F0C78F05266433DC9192A1EC943300",
+ "00000000000000000000000000000000",
+ "7F6C25FF41858561BB62F36492E93C29"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ aes_testcase_t *testcase = testcases;
+
+ while (testcase->key != NULL) {
+ len = fromhexstr(testcase->key, key);
+ ATF_CHECK_EQ(len, ISC_AES192_KEYLENGTH);
+ len = fromhexstr(testcase->input, plaintext);
+ ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH);
+ isc_aes192_crypt(key, plaintext, ciphertext);
+ ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+
+ATF_TC(isc_aes256);
+ATF_TC_HEAD(isc_aes256, tc) {
+ atf_tc_set_md_var(tc, "descr", "AES 256 test vectors");
+}
+ATF_TC_BODY(isc_aes256, tc) {
+ UNUSED(tc);
+
+ aes_testcase_t testcases[] = {
+ /* Test 1 (KAT ECBVarTxt256 #3) */
+ {
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "F0000000000000000000000000000000",
+ "7F2C5ECE07A98D8BEE13C51177395FF7"
+ },
+ /* Test 2 (KAT ECBVarTxt256 #123) */
+ {
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "7240E524BC51D8C4D440B1BE55D1062C"
+ },
+ /* Test 3 (KAT ECBVarKey256 #3) */
+ {
+ "F0000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "00000000000000000000000000000000",
+ "1C777679D50037C79491A94DA76A9A35"
+ },
+ /* Test 4 (KAT ECBVarKey256 #251) */
+ {
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0",
+ "00000000000000000000000000000000",
+ "03720371A04962EAEA0A852E69972858"
+ },
+ /* Test 5 (KAT ECBGFSbox256 #3) */
+ {
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000",
+ "8A560769D605868AD80D819BDBA03771",
+ "38F2C7AE10612415D27CA190D27DA8B4"
+ },
+ /* Test 6 (KAT ECBKeySbox256 #3) */
+ {
+ "984CA75F4EE8D706F46C2D98C0BF4A45"
+ "F5B00D791C2DFEB191B5ED8E420FD627",
+ "00000000000000000000000000000000",
+ "4307456A9E67813B452E15FA8FFFE398"
+ },
+ { NULL, NULL, NULL }
+ };
+
+ aes_testcase_t *testcase = testcases;
+
+ while (testcase->key != NULL) {
+ len = fromhexstr(testcase->key, key);
+ ATF_CHECK_EQ(len, ISC_AES256_KEYLENGTH);
+ len = fromhexstr(testcase->input, plaintext);
+ ATF_CHECK_EQ(len, ISC_AES_BLOCK_LENGTH);
+ isc_aes256_crypt(key, plaintext, ciphertext);
+ ATF_CHECK(tohexstr(ciphertext, str) == ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, testcase->result);
+
+ testcase++;
+ }
+}
+#else
+ATF_TC(untested);
+ATF_TC_HEAD(untested, tc) {
+ atf_tc_set_md_var(tc, "descr", "skipping aes test");
+}
+ATF_TC_BODY(untested, tc) {
+ UNUSED(tc);
+ atf_tc_skip("AES not available");
+}
+#endif
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+#ifdef ISC_PLATFORM_OPENSSLAES
+ ATF_TP_ADD_TC(tp, isc_aes128);
+ ATF_TP_ADD_TC(tp, isc_aes192);
+ ATF_TP_ADD_TC(tp, isc_aes256);
+#else
+ ATF_TP_ADD_TC(tp, untested);
+#endif
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/win32/include/isc/platform.h.in b/lib/isc/win32/include/isc/platform.h.in
index 9357baf87a..05ef7040c4 100644
--- a/lib/isc/win32/include/isc/platform.h.in
+++ b/lib/isc/win32/include/isc/platform.h.in
@@ -109,6 +109,11 @@
*/
@ISC_PLATFORM_NEEDSTRCASESTR@
+/*
+ * Define to enable Source Identity Token support.
+ */
+#define ISC_PLATFORM_USESIT 1
+
/*
* Set up a macro for importing and exporting from the DLL
*/
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index e18b9fd33c..65b26e5b81 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -980,6 +980,9 @@ options_clauses[] = {
{ "interface-interval", &cfg_type_uint32, 0 },
{ "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
{ "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
+#ifdef ISC_PLATFORM_USESIT
+ { "sit-secret", &cfg_type_qstring, 0 },
+#endif
{ "managed-keys-directory", &cfg_type_qstring, 0 },
{ "match-mapped-addresses", &cfg_type_boolean, 0 },
{ "max-rsa-exponent-size", &cfg_type_uint32, 0 },
@@ -1513,6 +1516,9 @@ view_clauses[] = {
{ "fetch-glue", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
{ "lame-ttl", &cfg_type_uint32, 0 },
+#ifdef ISC_PLATFORM_USESIT
+ { "nosit-udp-size", &cfg_type_uint32, 0 },
+#endif
{ "max-acache-size", &cfg_type_sizenodefault, 0 },
{ "max-cache-size", &cfg_type_sizenodefault, 0 },
{ "max-cache-ttl", &cfg_type_uint32, 0 },
@@ -1535,6 +1541,10 @@ view_clauses[] = {
{ "queryport-pool-updateinterval", &cfg_type_uint32,
CFG_CLAUSEFLAG_OBSOLETE },
{ "recursion", &cfg_type_boolean, 0 },
+ { "request-ixfr", &cfg_type_boolean, 0 },
+#ifdef ISC_PLATFORM_USESIT
+ { "request-sit", &cfg_type_boolean, 0 },
+#endif
{ "request-nsid", &cfg_type_boolean, 0 },
{ "resolver-query-timeout", &cfg_type_uint32, 0 },
{ "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI },
@@ -1811,6 +1821,10 @@ server_clauses[] = {
{ "provide-ixfr", &cfg_type_boolean, 0 },
{ "request-ixfr", &cfg_type_boolean, 0 },
{ "support-ixfr", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
+#ifdef ISC_PLATFORM_USESIT
+ { "request-sit", &cfg_type_boolean, 0 },
+#endif
+ { "request-nsid", &cfg_type_boolean, 0 },
{ "transfers", &cfg_type_uint32, 0 },
{ "transfer-format", &cfg_type_transferformat, 0 },
{ "keys", &cfg_type_server_key_kludge, 0 },