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 },