idnits 2.17.1 draft-hayatnagarkar-dnsext-validator-api-09.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 173: '...ct (see Section 6). Applications MUST...' RFC 2119 keyword, line 177: '... Validator API MUST internally use a...' RFC 2119 keyword, line 204: '...addr() functions SHOULD only be used w...' RFC 2119 keyword, line 208: '... Section 3.4 SHOULD be used instead....' RFC 2119 keyword, line 211: '...of a DNS response, applications SHOULD...' (118 more instances...) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == Line 1451 has weird spacing: '...ple.com valid...' == Line 1529 has weird spacing: '...timeval tv;...' -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (March 12, 2012) is 4427 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) No issues found here. Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 DNS Extensions S. Krishnaswamy 3 Internet-Draft R. Story 4 Intended status: Standards Track SPARTA, Inc. 5 Expires: September 13, 2012 A. Hayatnagarkar 6 March 12, 2012 8 DNSSEC Validator API 9 draft-hayatnagarkar-dnsext-validator-api-09 11 Abstract 13 The DNS Security Extensions (DNSSEC) provide origin authentication 14 and integrity of DNS data. However, the current resolver Application 15 Programming Interface (API) does not specify how a validating stub 16 resolver should communicate results of DNSSEC processing back to the 17 application. This document describes an API between applications and 18 a validating stub resolver that allows applications to control the 19 DNSSEC validation process and obtain results of DNSSEC processing. 21 Status of this Memo 23 This Internet-Draft is submitted in full conformance with the 24 provisions of BCP 78 and BCP 79. 26 Internet-Drafts are working documents of the Internet Engineering 27 Task Force (IETF). Note that other groups may also distribute 28 working documents as Internet-Drafts. The list of current Internet- 29 Drafts is at http://datatracker.ietf.org/drafts/current/. 31 Internet-Drafts are draft documents valid for a maximum of six months 32 and may be updated, replaced, or obsoleted by other documents at any 33 time. It is inappropriate to use Internet-Drafts as reference 34 material or to cite them other than as "work in progress." 36 This Internet-Draft will expire on September 13, 2012. 38 Copyright Notice 40 Copyright (c) 2012 IETF Trust and the persons identified as the 41 document authors. All rights reserved. 43 This document is subject to BCP 78 and the IETF Trust's Legal 44 Provisions Relating to IETF Documents 45 (http://trustee.ietf.org/license-info) in effect on the date of 46 publication of this document. Please review these documents 47 carefully, as they describe your rights and restrictions with respect 48 to this document. Code Components extracted from this document must 49 include Simplified BSD License text as described in Section 4.e of 50 the Trust Legal Provisions and are provided without warranty as 51 described in the Simplified BSD License. 53 Table of Contents 55 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 56 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 57 3. High-level DNSSEC Validator API . . . . . . . . . . . . . . . 4 58 3.1. val_gethostbyname, val_gethostbyaddr . . . . . . . . . . . 5 59 3.2. val_getaddrinfo, val_freeaddrinfo, val_getnameinfo . . . . 6 60 3.3. val_res_query . . . . . . . . . . . . . . . . . . . . . . 8 61 3.4. val_get_rrset . . . . . . . . . . . . . . . . . . . . . . 9 62 4. Low-level DNSSEC Validator API . . . . . . . . . . . . . . . . 10 63 4.1. val_resolve_and_check, val_free_result_chain . . . . . . . 11 64 4.2. Authentication Chain Status Codes and p_ac_status() . . . 15 65 5. Low-level Asynchronous DNSSEC Validator API . . . . . . . . . 18 66 5.1. Asynchronous Requests . . . . . . . . . . . . . . . . . . 18 67 5.1.1. val_async_submit . . . . . . . . . . . . . . . . . . . 18 68 5.1.2. val_async_select_info . . . . . . . . . . . . . . . . 19 69 5.1.3. val_async_check_wait . . . . . . . . . . . . . . . . . 20 70 5.2. Asynchronous Callbacks . . . . . . . . . . . . . . . . . . 21 71 5.3. Asynchronous Status . . . . . . . . . . . . . . . . . . . 22 72 5.3.1. Operations on asynchronous status objects . . . . . . 22 73 6. DNSSEC Validator Context API . . . . . . . . . . . . . . . . . 23 74 6.1. val_create_context, val_free_context . . . . . . . . . . . 23 75 6.2. val_context_setqflags . . . . . . . . . . . . . . . . . . 24 76 7. Function Return Codes and p_val_err() . . . . . . . . . . . . 24 77 8. Evaluating Response Validity . . . . . . . . . . . . . . . . . 25 78 8.1. DNSSEC Validation Status Codes and p_val_status() . . . . 25 79 8.2. High-Level Routines for Evaluating Validity . . . . . . . 27 80 9. Notes On DNS Data Caching By Appplications . . . . . . . . . . 28 81 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29 82 11. Security Considerations . . . . . . . . . . . . . . . . . . . 29 83 12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 30 84 13. References . . . . . . . . . . . . . . . . . . . . . . . . . . 30 85 13.1. Normative References . . . . . . . . . . . . . . . . . . . 30 86 13.2. Informative References . . . . . . . . . . . . . . . . . . 31 87 Appendix A. Zone-Specific Validator Policy Settings . . . . . . . 31 88 Appendix B. Global Validator Policy . . . . . . . . . . . . . . . 33 89 Appendix C. Asynchronous API Example Code . . . . . . . . . . . . 33 90 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 35 92 1. Introduction 94 The DNS Security Extensions ([refs.RFC4033], [refs.RFC4034], 95 [refs.RFC4035]) enable DNS resolvers to test the origin authenticity 96 and integrity of data returned by the DNS. A DNSSEC validator, or 97 more formally, a validating stub resolver, is a piece of software 98 that performs these tests by constructing an authentication chain 99 [refs.RFC4033] from a locally configured DNSSEC trust anchor 100 [refs.RFC4033] to a cryptographic signature that covers the DNS 101 information in question. This document presents an API between an 102 application and a DNSSEC validator, which enables applications to 103 control the DNSSEC validation process and enables applications to 104 obtain DNSSEC validation results upon which to base program behavior. 106 The API can be broadly divided into three groups: the high-level 107 DNSSEC validator API, the low-level DNSSEC validator API and the 108 DNSSEC validator-context API. Section 3, Section 4, and Section 6 109 describe these groups in greater detail. 111 The high-level DNSSEC validator API is designed for ease of use and 112 mirrors existing DNS-related functions. This API is best suited for 113 existing applications that use legacy DNS functions such as 114 gethostbyname() and getaddrinfo() [refs.IEEE.1003.1-2004] and have no 115 requirement for detailed DNSSEC validation status information. 117 The low-level DNSSEC validator API enables applications to examine 118 the DNSSEC validation details for each element of the DNSSEC 119 authentication chain. 121 The DNSSEC validator-context API enables applications to control the 122 DNSSEC policies that are used for validating DNS responses. 124 The range of functions provided in this API supports different 125 classes of applications, ranging from those that are only interested 126 in basic DNSSEC results to more sophisticated applications that can 127 look for specific errors in an authentication chain as a sign of some 128 abnormality or attack. 130 2. Terminology 132 Some of the terms used in this specification are defined below: 134 Legacy DNS Functions: existing functions, such as gethostbyname() 135 and getaddrinfo(), which are not capable of returning DNSSEC 136 validation status codes for DNS responses. 138 DNSSEC Validator Policy: a set of configuration parameters for the 139 DNSSEC validator, which can influence the eventual outcome of the 140 DNSSEC validation process. 142 DNSSEC Validator Context: the application's run-time handle to the 143 DNSSEC validator policy. 145 3. High-level DNSSEC Validator API 147 The high-level DNSSEC validator API defines DNSSEC-aware substitutes 148 for commonly used legacy DNS functions. It provides an easy path for 149 applications already using legacy DNS functions to transition towards 150 becoming DNSSEC-aware. This API also defines the val_get_rrset() 151 function, which enables applications to obtain data for an arbitrary 152 DNS name, class and type, and inspect the corresponding DNSSEC 153 validation status value(s). 155 A number of legacy DNS functions exist; however, some of these 156 functions (such as gethostbyname_r and gethostbyname2) are only 157 available on a subset of Operating Systems and are not part of any 158 official standard. Also, some functions are defined as minor 159 extensions of other well-known legacy DNS functions. For example, 160 gethostbyname2 differs from gethostbyname_r only by virtue of having 161 the extra argument to explictly specify the address family. Further, 162 some functions differ from others only by virtue of being able to 163 support a re-entrant and thread-safe implementation. Instead of 164 providing an exhaustive list of DNSSEC-capable replacement functions 165 for all known resolver function calls, the high-level DNSSEC 166 validator API in this document only describes DNSSEC extensions for 167 the canonical set of function calls specified in 168 [refs.IEEE.1003.1-2004]. DNSSEC replacement functions for other 169 legacy DNS functions are expected to mirror, to a large extent, other 170 functions described in this document. 172 The ctx parameter in the functions described in this API points to a 173 DNSSEC validator context object (see Section 6). Applications MUST 174 either supply a reference to a valid DNSSEC validator context object 175 created using the functions specified in Section 6 or supply a NULL 176 value for this parameter. Libraries that implement the DNSSEC 177 Validator API MUST internally use a default DNSSEC validator context 178 when the application supplies a NULL value for ctx. 180 3.1. val_gethostbyname, val_gethostbyaddr 182 #include 184 struct hostent *val_gethostbyname( val_context_t *ctx, 185 const char *name, 186 val_status_t *val_status ); 188 struct hostent *val_gethostbyaddr( val_context_t *ctx, 189 const char *addr, 190 int len, 191 int type, 192 val_status_t *val_status ); 194 The val_gethostbyname() and val_gethostbyaddr() functions are DNSSEC- 195 aware versions of the gethostbyname() and gethostbyaddr() legacy DNS 196 functions. 198 The new functions have an additional parameter, val_status, which 199 enables applications to check the DNSSEC validation status codes for 200 the address-to-name and name-to-address translations. The other 201 arguments to these functions and their return values have identical 202 semantics to the corresponding legacy DNS functions as described in 203 [refs.IEEE.1003.1-2004]. The val_gethostbyname() and 204 val_gethostbyaddr() functions SHOULD only be used when retrofitting 205 DNSSEC in existing applications that use the gethostbyname() and 206 gethostbyaddr() functions. For new applications that need to perform 207 these translations, the functions described in Section 3.2 and 208 Section 3.4 SHOULD be used instead. 210 The DNSSEC validation status is returned in the val_status parameter. 211 When evaluating the validity of a DNS response, applications SHOULD 212 use the functions described in Section 8.2 instead of directly 213 inspecting the DNSSEC validation status code returned in val_status. 215 The status code returned in val_status is determined by the following 216 rules. 217 o A DNSSEC validation status of VAL_OOB_ANSWER MUST be returned if 218 the complete answer is returned using some out-of-band mechanism 219 (for example, from a local configuration store such as /etc/hosts 220 or its equivalent) without any DNSSEC validation being performed. 221 However, if local DNSSEC validator policy defines out-of-band 222 answers to be trustworthy, a DNSSEC validation status of 223 VAL_TRUSTED_ANSWER SHOULD be returned instead. 224 o A DNSSEC validation status of VAL_VALIDATED_ANSWER MUST be 225 returned if all addresses and canonical names within the hostent 226 structure are validated successfully. 228 o A DNSSEC validation status of VAL_TRUSTED_ANSWER MUST be returned 229 if at least one address or canonical name within the hostent 230 structure is not validated by the DNSSEC validation process, but 231 all answers are still considered trustworthy (see Section 6) by 232 way of the configured local DNSSEC validator policy. 233 o A DNSSEC validation status of VAL_UNTRUSTED_ANSWER MUST be 234 returned if at least one address or canonical name within the 235 hostent structure is neither validated through the DNSSEC 236 validation process nor considered to be trusted according to the 237 configured local DNSSEC validator policy. 238 o A DNSSEC validation status of VAL_NONEXISTENT_NAME or 239 VAL_NONEXISTENT_TYPE MUST be returned if the DNSSEC validation 240 process is able to prove non-existence for the name or type being 241 queried for. A DNSSEC validation status of 242 VAL_NONEXISTENT_NAME_NOCHAIN or VAL_NONEXISTENT_TYPE_NOCHAIN MUST 243 be returned if a DNS response with an RCODE reflecting type or 244 name non-existence is returned, and local DNSSEC validator policy 245 is configured to treat such answers as trustworthy. If the 246 previous two conditions for non-existence are not satisfied, 247 val_status MUST be set to VAL_UNTRUSTED_ANSWER. 249 3.2. val_getaddrinfo, val_freeaddrinfo, val_getnameinfo 251 #include 253 int val_getaddrinfo( val_context_t *ctx, 254 const char *nodename, 255 const char *servname, 256 const struct addrinfo *hints, 257 struct addrinfo **res , 258 val_status_t *val_status); 260 void val_freeaddrinfo( struct addrinfo *res); 262 int val_getnameinfo( val_context_t *ctx, 263 const struct sockaddr *sa, 264 socklen_t salen, 265 char *host, 266 size_t hostlen, 267 char *serv, 268 size_t servlen, 269 int flags, 270 val_status_t *val_status ); 272 These functions are DNSSEC-aware versions of the getaddrinfo(), 273 freeaddrinfo() and getnameinfo() legacy DNS functions 274 ([refs.RFC3493]) respectively. 276 The val_getaddrinfo() function returns the address and service 277 information for the specified domain name and service. The 278 val_freaddrinfo() function releases the memory used by the struct 279 addrinfo returned in the res parameter when calling val_getaddrinfo. 280 The val_getnameinfo() function performs an address-to-name 281 translation in a protocol independent manner. 283 The value of res MUST point to a valid addrinfo structure 284 ([refs.RFC3493]) on a successful return from the val_getaddrinfo() 285 function or NULL in case of error. Sufficient memory MUST be 286 internally allocated to hold the linked list pointed to by res. This 287 memory MUST be released when applications invoke the freeaddrinfo() 288 function. ([refs.RFC3493]). 290 The DNSSEC validation status is returned in the val_status parameter. 291 When evaluating the validity of a DNS response, applications SHOULD 292 use the functions described in Section 8.2 instead of directly 293 inspecting the DNSSEC validation status code returned in val_status. 294 The syntax and semantics of other parameters in val_getaddrinfo() and 295 val_getnameinfo() and their return values are identical to those 296 specified for getaddrinfo() and getnameinfo() in [refs.RFC3493]. 298 The status code returned in val_status is determined by the following 299 rules. 300 o A DNSSEC validation status of VAL_OOB_ANSWER MUST be returned in 301 val_status if the complete answer is returned using some out-of- 302 band mechanism (for example, from a local configuration store such 303 as /etc/hosts or its equivalent) without any DNSSEC validation 304 being performed. However, if local DNSSEC validator policy 305 defines out-of-band answers to be trustworthy, a DNSSEC validation 306 status of VAL_TRUSTED_ANSWER SHOULD be returned instead. 307 o A DNSSEC validation status of VAL_VALIDATED_ANSWER MUST be 308 returned in val_status if the hostname returned by 309 val_getnameinfo(), or all addresses and canonical names returned 310 by val_getaddrinfo(), are validated through the DNSSEC process. 311 o A DNSSEC validation status of VAL_TRUSTED_ANSWER MUST be returned 312 in val_status if the hostname returned by val_getnameinfo(), or at 313 least one address or canonical name returned by val_getaddrinfo(), 314 is not validated by the DNSSEC validation process but all answers 315 are still considered to be trustworthy through the local DNSSEC 316 validator policy (see Section 6). 317 o A DNSSEC validation status of VAL_UNTRUSTED_ANSWER MUST be 318 returned if at least one address or canonical name returned by 319 val_getaddrinfo() within the addrinfo structure, or the returned 320 hostname in val_getnameinfo(), is neither validated through the 321 DNSSEC process nor considered to be trustworthy according to the 322 local DNSSEC validator policy. 324 o A DNSSEC validation status of VAL_NONEXISTENT_NAME or 325 VAL_NONEXISTENT_TYPE MUST be returned in val_status if the DNSSEC 326 validation process is able to prove non-existence for the name or 327 type being queried for. A DNSSEC validation status of 328 VAL_NONEXISTENT_NAME_NOCHAIN or VAL_NONEXISTENT_TYPE_NOCHAIN MUST 329 be returned if a DNS response with an RCODE reflecting type or 330 name non-existence is returned, and local DNSSEC validator policy 331 is configured to treat such answers as trustworthy (Section 6). 332 If the previous two conditions for non-existence are not 333 satisfied, val_status MUST be set to VAL_UNTRUSTED_ANSWER. 335 3.3. val_res_query 337 #include 339 int val_res_query(val_context_t *ctx, 340 const char *domain_name, 341 int class, 342 int type, 343 unsigned char *answer, 344 int anslen, 345 val_status_t *val_status); 347 The val_res_query() function is a DNSSEC-aware replacement for the 348 res_query() function (currently not documented in any standard 349 reference). 351 The val_res_query() function queries the DNS for the data associated 352 with the given domain name, class and type, and returns the resulting 353 resource record sets in a DNS-style response. 355 The val_res_query() function MUST return the actual size of the 356 response packet on success and -1 on failure. On success, the 357 response from the DNS MUST be copied to the user-allocated buffer in 358 answer and MUST NOT exceed the buffer size specified in anslen. 360 The DNSSEC validation status is returned in the val_status parameter. 361 When evaluating the validity of a DNS response, applications SHOULD 362 use the functions described in Section 8.2 instead of directly 363 inspecting the DNSSEC validation status code returned in val_status. 365 The status code returned in val_status is determined by the following 366 rules. 367 o A DNSSEC validation status of VAL_VALIDATED_ANSWER MUST be 368 returned if all resource record sets returned in the answer are 369 validated by the DNSSEC validation process. 371 o A DNSSEC validation status of VAL_TRUSTED_ANSWER MUST be returned 372 if at least one resource record set returned in the answer is not 373 validated by the DNSSEC validation process, but all resource 374 record sets are still considered to be trustworthy according to 375 the configured local DNSSEC validator policy (see Section 6). 376 o A DNSSEC validation status of VAL_UNTRUSTED_ANSWER MUST be 377 returned if at least one resource record set in the answer is 378 neither validated through the DNSSEC validation process nor 379 considered to be trustworthy according to the local DNSSEC 380 validator policy. 381 o A DNSSEC validation status of VAL_NONEXISTENT_NAME or 382 VAL_NONEXISTENT_TYPE MUST be returned if the DNSSEC validation 383 process is able to prove non-existence for the name or type being 384 queried for. A DNSSEC validation status of 385 VAL_NONEXISTENT_NAME_NOCHAIN or VAL_NONEXISTENT_TYPE_NOCHAIN MUST 386 be returned if a DNS response with an RCODE reflecting type or 387 name non-existence is returned, and local DNSSEC validator policy 388 is configured to treat such answers as trustworthy. If the 389 previous two conditions for non-existence are not satisfied, 390 val_status MUST be set to VAL_UNTRUSTED_ANSWER. 392 3.4. val_get_rrset 394 #include 396 int val_get_rrset(val_context_t *ctx, 397 const char *name, 398 int class, 399 int type, 400 unsigned int flags, 401 struct val_answer_chain **answers); 403 void val_free_answer_chain(struct val_answer_chain *answers); 405 The val_get_rrset() function queries the DNS for the data associated 406 with the given domain name, class and type. The flags argument 407 specifies a list of options to the validation process, logically OR'd 408 to each other. This possible flags are defined in Section 4.1. 409 val_get_rrset() MUST return 0 on success and an error code from 410 Section 7 on failure. 412 val_get_rrset() MUST return its results in the val_answer_chain 413 structure after allocating sufficient memory for this structure. 414 Applications MUST release this memory after use by invoking the 415 val_free_answer_chain() function. 417 The val_answer_chain structure is defined below. 419 struct val_answer_chain { 420 val_status_t val_ans_status; 421 char *val_ans_name; 422 int val_ans_class; 423 int val_ans_type; 424 struct rr_rec *val_ans; 425 struct val_answer_chain *val_ans_next; 426 }; 428 struct rr_rec { 429 size_t rr_length; 430 unsigned char *rr_data; 431 struct rr_rec *rr_next; 432 }; 434 val_ans_name MUST be set to the DNS name of the actual resource 435 record set returned. This value may differ from the name argument in 436 val_get_rrset() if the resource record is returned after following a 437 CNAME ([refs.RFC1034]) or DNAME ([refs.RFC2672]) alias. val_ans_class 438 and val_ans_type MUST be set to the actual class and type for the 439 returned resource record. These values may differ from the class and 440 type arguments in val_get_rrset() if the query type or class has the 441 value 255 (ANY). The resource record sets MUST be returned in 442 val_ans as a linked list of rr_rec structures, with each element 443 containing the rr_length and rr_data tuple for a resource record in 444 the resource record set. val_ans MUST be set to NULL if no answer was 445 returned for the given query or if a proof of non-existence was 446 returned. 448 The DNSSEC validation status code is returned in the val_ans_status 449 field. Since validation status codes returned by val_get_rrset() are 450 available per resource record set, the set of possible values for 451 val_ans_status is more granular than that possible for the val_status 452 field in other high-level API functions. The list of possible codes 453 for val_ans_status are listed in Section 8.1. When evaluating the 454 validity of a DNS response, applications SHOULD use the functions 455 described in Section 8.2 instead of directly inspecting the DNSSEC 456 validation status code returned in val_ans_status. 458 4. Low-level DNSSEC Validator API 460 The low-level DNSSEC validator API provides applications with greater 461 control and visibility into the DNSSEC validation process. The 462 functions and data structures defined in the low-level DNSSEC 463 validator API are summarized below. 465 4.1. val_resolve_and_check, val_free_result_chain 467 #include 469 int val_resolve_and_check( val_context_t *ctx, 470 const char *domain_name, 471 int class, 472 int type, 473 unsigned int flags, 474 struct val_result_chain **results); 476 void val_free_result_chain(struct val_result_chain *results); 478 The val_resolve_and_check() function queries the DNS for the 479 tuple and then performs the DNSSEC 480 validation operation for the responses received. The 481 val_free_result_chain() function releases the resources allocated for 482 the returned result. 484 The flags argument specifies a list of options to the validation 485 process, logically OR'd to each other. The following flags are 486 defined; their values are implementation-specific: 488 VAL_QUERY_AC_DETAIL: If this flag is specified, the complete 489 authentication chain MUST be returned for each answer within the 490 val_result_chain structure. If this flag is not set then only the 491 rrset information corresponding to the answer or proof of non- 492 existence for the queried name, domain_name SHOULD be returned 493 within the val_result_chain structure. 494 VAL_QUERY_DONT_VALIDATE: If this flag is specified, validation 495 processing MUST be ignored for the given name. Any resulting 496 answer will have a validation status value of 497 VAL_IGNORE_VALIDATION. 498 VAL_QUERY_IGNORE_SKEW: If this flag is specified, signature 499 inception and expiration times MUST be ignored for RRSIGs in the 500 authentication chain. 501 VAL_QUERY_NO_DLV: If this flag is specified, Dynamic Look-aside 502 Validation (DLV) [refs.DLV] processing for this name MUST NOT be 503 performed. 504 VAL_QUERY_ASYNC: If this flag is specified, this name MUST be 505 resolved through the asynchronous lookup process (see Section 5). 506 VAL_QUERY_RECURSE: If this flag is specified, the name MUST be 507 looked up by directly querying the authoritative name server for 508 that name (which may involve iteratively querying various name 509 servers in the delegation hierarchy) instead of requesting this 510 information from any caching name server that may be specified as 511 configuration data. 513 VAL_QUERY_NO_EDNS0_FALLBACK: If this flag is specified, re-trying 514 the query with smaller EDNS0 advertised window sizes MUST NOT be 515 attempted as a fallback strategy. 516 VAL_QUERY_SKIP_RESOLVER: If this flag is specified, only the cache 517 should be consulted while looking up a name. New queries MUST NOT 518 be sent on the wire as part of looking up and validating the 519 cached answer. 520 VAL_QUERY_SKIP_CACHE: If this flag is specified, any locally cached 521 information for the name being looked up MUST be ignored. 523 val_resolve_and_check() MUST return 0 on success and an error code 524 from Section 7 on failure. Answers to the query MUST be returned in 525 results, which is a linked list of val_result_chain structures, as 526 defined below. val_resolve_and_check() MUST allocate sufficient 527 memory to hold the contents of results. This memory MUST be released 528 when applications invoke the val_free_result_chain() function. 530 #define MAX_PROOFS 4 531 struct val_result_chain { 532 val_status_t val_rc_status; 533 char *val_rc_alias; 534 struct val_rrset_rec *val_rc_rrset; 535 struct val_authentication_chain *val_rc_answer; 536 int val_rc_proof_count; 537 struct val_authentication_chain *val_rc_proofs[MAX_PROOFS]; 538 struct val_result_chain *val_rc_next; 539 }; 541 Each element in the val_result_chain linked list MUST point to a 542 distinct resource record set returned in the response. Multiple 543 resource record sets can be returned in a response when the query is 544 for the type code of 255 (ANY) or 46 (RRSIG). The val_rc_next field 545 enables an application to iterate through the list of all results 546 returned by the DNSSEC validator. For all val_result_chain elements 547 that represent a name alias, val_rc_alias MUST point to the target 548 name referenced by that alias. 550 val_rc_answer SHOULD point to a resource record in the answer 551 portion; all associated proofs of non-existence (either in support of 552 the answer in val_rc_answer or to prove the non-existence of a 553 record) SHOULD be returned in val_rc_proofs. val_rc_proof_count MUST 554 be set to the number of proof elements that are available. 555 val_rc_answer and val_rc_proofs SHOULD be NULL if the 556 VAL_QUERY_AC_DETAIL flag is not specified in the flags argument for 557 val_resolve_and_check(). 559 val_rc_rrset MUST point to resource record set information for the 560 current element in the val_result_chain linked list. If no answers 561 are returned (or a proof of non-existence is returned) in response to 562 the query, val_rc_rrset MUST be set to NULL. 564 The DNSSEC validation status code is returned in the val_rc_status 565 field. Since validation status codes are available per resource 566 record set, it is possible to have a highly granular set of values 567 for val_rc_status. Possible codes for val_rc_status are listed in 568 Section 8.1. When evaluating the validity of a DNS response, 569 applications SHOULD use the functions described in Section 8.2 570 instead of directly inspecting the DNSSEC validation status code 571 returned in val_rc_status. 573 The val_authentication_chain structure represents a linked list whose 574 elements comprise the DNSSEC authentication chain for an answer or 575 proof of non-existence resource record set. 577 struct val_authentication_chain { 578 val_astatus_t val_ac_status; 579 struct val_rrset_rec *val_ac_rrset; 580 struct val_authentication_chain *val_ac_trust; 581 }; 583 The DNSSEC validation status for the specified resource record set 584 MUST be set in the val_ac_status field. Possible codes for this 585 field are defined in Section 4.2. The val_ac_trust field MUST point 586 to the next element in the authentication chain proceeding from the 587 signed record towards a DNSSEC trust anchor. For an element with 588 type DNSKEY, the next element MUST correspond to a DS record in the 589 parent zone and for a DS record the next element MUST correspond to 590 the DNSKEY in the same zone as the DS record. The value of 591 val_ac_trust MUST be set to NULL if either the current element in the 592 linked list points to a valid DNSSEC trust anchor or if an error 593 condition is encountered. The validation status code stored in the 594 val_ac_status field can be used to differentiate between different 595 error conditions. 597 The val_ac_rrset field in the val_authentication_chain structure MUST 598 point to a val_rrset_rec structure holding the actual resource record 599 set fields ([refs.RFC1034]) as described below. 601 struct val_rrset_rec { 602 int val_rrset_rcode; 603 char *val_rrset_name; 604 int val_rrset_class; 605 int val_rrset_type; 606 long val_rrset_ttl; 607 int val_rrset_section; 608 struct sockaddr *val_rrset_server; 609 struct val_rr_rec *val_rrset_data; 610 struct val_rr_rec *val_rrset_sig; 611 }; 613 The information stored in the val_rrset_rec structure includes the 614 DNS response error code in the val_rrset_rcode field, and the DNS 615 response "envelope" comprising of the name, class, type and time-to- 616 live tuple in the val_rrset_name, val_rrset_class, val_rrset_type and 617 val_rrset_ttl fields respectively. Additionally, the name server 618 from where this resource record set was received MUST be stored in 619 the sockaddr data structure ([refs.IEEE.1003.1-2004]) pointed to by 620 the val_rrset_server field. The section where the resource record 621 set appeared in the DNS response MUST be saved in the 622 val_rrset_section field within the val_rrset_rec structure, and MUST 623 be set to one of the following values: 625 #define VAL_FROM_ANSWER 1 /* if the resource record set was present 626 in the answer section of the DNS response. */ 628 #define VAL_FROM_AUTHORITY 2 /* if the resource record set was 629 present in the authority section of the DNS response. */ 631 #define VAL_FROM_ADDITIONAL 3 /* if the resource record set was 632 present in the additional section of the DNS response. */ 634 The data returned for the resource record set MUST be queued to 635 val_rrset_data. Any associated RRSIGs MUST be queued to 636 val_rrset_sig. Both of these variables MUST point to lists of struct 637 val_rr_rec elements, which specify the resource record data and the 638 DNSSEC validation status for each resource-record within the resource 639 record set as defined below. 641 struct val_rr_rec { 642 size_t rr_rdata_length; 643 unsigned char *rr_rdata; 644 struct val_rr_rec *rr_next; 645 val_astatus_t rr_status; 646 }; 648 The rr_status member in val_rr_rec is only relevant for the 649 signatures present in val_rrset_sig or when val_rrset_data points to 650 DNSKEY or DS resource records. In other cases the value of this 651 field MUST be set to VAL_AC_UNSET. The rr_status field takes on a 652 subset of all status codes possible for the val_astatus_t type and is 653 further described in Section 4.2. 655 4.2. Authentication Chain Status Codes and p_ac_status() 657 For each authentication chain element in the val_authentication_chain 658 structure, the val_ac_status field MUST contain one of the following 659 codes: 661 VAL_AC_UNSET: The DNSSEC validation status for the resource record 662 set could not be determined. 664 VAL_AC_IGNORE_VALIDATION: DNSSEC validation for the given resource 665 record set was ignored on the basis of some configured DNSSEC 666 validator policy. 668 VAL_AC_UNTRUSTED_ZONE: The resource record set belonged to a zone 669 that the DNSSEC validator considered to be un-trusted, with no 670 further DNSSEC validation being deemed necessary. 672 VAL_AC_PINSECURE: The resource record set belonged to a zone for 673 which the DS record was provably absent. 675 VAL_AC_BARE_RRSIG: The resource record set contained only RRSIGs (in 676 response to a query of type RRSIG). RRSIGs contain the 677 cryptographic signatures for other DNS data and cannot themselves 678 be validated. 680 VAL_AC_NO_LINK: No DNSSEC trust anchor was configured at or above 681 the level of the authentication chain could be found above this 682 point, therefore no validation could be performed. 684 VAL_AC_TRUST: At least one of the signatures covering the given 685 resource record set was directly verified using a key that was 686 configured as a DNSSEC trust anchor. 688 VAL_AC_RRSIG_MISSING: RRSIG data for the given resource record set 689 could not be located. 691 VAL_AC_DNSKEY_MISSING: The DNSKEY data that generated signatures for 692 the given resource record set could not be located. 694 VAL_AC_DS_MISSING: The DS data for the DNSKEY resource record set in 695 question could not be located. 697 VAL_AC_DATA_MISSING: The returned resource record set was empty. 699 VAL_AC_DNS_ERROR: A DNS error was encountered during the query 700 resolution process. 702 VAL_AC_NOT_VERIFIED: None of the RRSIGs covering the given resource 703 record set could be verified. 705 VAL_AC_VERIFIED: At least one RRSIG covering the resource record set 706 verified successfully. 708 For each signature val_rr_rec member within an authentication chain 709 pointed to by val_ac_rrset, the DNSSEC validation status stored in 710 the variable rr_status MUST be set to one of the following codes: 712 VAL_AC_UNSET: No DNSSEC validation status information could be 713 obtained for the given signature. 715 VAL_AC_RRSIG_VERIFIED: The RRSIG verified successfully. 717 VAL_AC_WCARD_VERIFIED: The RRSIG covering a resource record proved 718 that the record was wildcard expanded. 720 VAL_AC_RRSIG_VERIFIED_SKEW: The RRSIG verified successfully only 721 after clock skew was taken into consideration. 723 VAL_AC_WCARD_VERIFIED_SKEW: The RRSIG covering a resource record 724 proved that the record was wildcard expanded, but only after clock 725 skew was taken into consideration. 727 VAL_AC_WRONG_LABEL_COUNT: The number of labels on the signature was 728 greater than the count given in the RRSIG resource record data. 730 VAL_AC_INVALID_RRSIG: The RRSIG could not be parsed. 732 VAL_AC_RRSIG_NOTYETACTIVE: The RRSIG's inception time was in the 733 future. 735 VAL_AC_RRSIG_EXPIRED: The RRSIG's expiration time was in the past. 737 VAL_AC_ALGORITHM_NOT_SUPPORTED: The RRSIG algorithm was not 738 supported. 740 VAL_AC_RRSIG_VERIFY_FAILED: The RRSIG could not be verified. 742 VAL_AC_RRSIG_ALGORITHM_MISMATCH: The keytag referenced in the RRSIG 743 matched a DNSKEY but the algorithms were different. 745 VAL_AC_DNSKEY_NOMATCH: The DNSKEY that created the given signature 746 could not be found in the zone DNSKEY resource record set. 748 For each val_rr_rec member of type DNSKEY (or DS where indicated) 749 within an authentication chain structure pointed to by val_ac_rrset, 750 the DNSSEC validation status stored in the variable rr_status MUST be 751 set to one of the following codes: 753 VAL_AC_UNSET: No DNSSEC validation status information could be 754 obtained for the given DNSKEY or DS record. 756 VAL_AC_TRUST_POINT: The given DNSKEY or DS record was configured as 757 a DNSSEC trust anchor. 759 VAL_AC_SIGNING_KEY: The given DNSKEY was used for generating an 760 RRSIG for a resource record in the authentication chain. 762 VAL_AC_VERIFIED_LINK: The given DNSKEY or DS resource record 763 provided the link in the authentication chain from a DNSSEC trust 764 anchor to the signed record. 766 VAL_AC_UNKNOWN_ALGORITHM_LINK: The DNSKEY chained up to a DS record 767 but the DNSKEY algorithm was unknown. 769 VAL_AC_UNKNOWN_DNSKEY_PROTOCOL: The DNSKEY protocol number was 770 unknown. 772 VAL_AC_ALGORITHM_NOT_SUPPORTED: The DNSKEY or DS algorithm was not 773 supported. 775 VAL_AC_DS_NOMATCH: The given DNSKEY did not chain up to any DS 776 record in the parent zone. 778 VAL_AC_INVALID_KEY: The given DNSKEY was invalid. 780 VAL_AC_INVALID_DS: The given DS was invalid. 782 The numerical values for the codes listed above are implementation- 783 specific. The p_ac_status() function is used to convert the DNSSEC 784 validation status code stored in struct val_authentication_chain to a 785 string representation. 787 #include 789 const char *p_ac_status(val_astatus_t status); 791 The value returned MAY be the string conversion for the corresponding 792 val_astatus_t identifier. For example, the return value from 793 p_ac_status(VAL_AC_VERIFIED) MAY be "VAL_AC_VERIFIED". 795 5. Low-level Asynchronous DNSSEC Validator API 797 The low-level Asynchronous DNSSEC validator API allows an application 798 to submit multiple requests which can be processed in parallel. In 799 most cases, this will result in validation completing much sooner 800 than a series of synchronous requests. 802 When submitting an asynchronous request, an application may specify a 803 callback function to be called when the request completes. 805 Since DNSSEC validation of a domain name involves multiple queries, 806 applications must periodically give time to the API for processing 807 responses and sending additional queries. (See 808 val_async_check_wait() in Section 5.1.3.) 810 The functions and data structures defined in the low-level 811 Asynchronous DNSSEC validator API are summarized below. 813 5.1. Asynchronous Requests 815 5.1.1. val_async_submit 817 #include 819 int val_async_submit(val_context_t *ctx, const char *domain_name, 820 int class, int type, unsigned int flags, 821 val_async_event_cb *callback, 822 void *user_context, 823 val_async_status **async_status); 825 The val_async_submit() function submits a request for asynchronous 826 processing of DNS queries for the data associated with the given 827 domain name, class and type. 829 If specified, the given callback function will be called when results 830 become available. Some flags, defined below, can affect when and how 831 often the callback is called. 833 The specified user context will also be passed to the callback 834 function. More information on the callback function and user_context 835 can be found in Section 5.2. 837 The val_async_submit() function MUST return VAL_NO_ERROR on success 838 and return a pointer to a newly allocated async_status object via the 839 async_status parameter. More information on async_status objects can 840 be found in Section 5.3. 842 On failure, the return code will be one of VAL_RESOURCE_UNAVAILABLE, 843 VAL_BAD_ARGUMENT or VAL_INTERNAL_ERROR. The function MUST release 844 any allocated data, and MUST NOT return a value via the async_status 845 parameter. An implementation MAY set async_status to NULL. 847 The following flags may be set for the request. The numerical values 848 for the flags are implementation-specific. 850 VAL_AS_IGNORE_CACHE: Don't use any internal cache for answers to 851 this query. Answers MUST be from fresh responses to all queries. 852 These new answers MAY be stored in the internal cache for use with 853 future queries. 855 VAL_AS_NO_NEW_QUERIES: Don't send any new queries. Answers MUST 856 come from the internal cache. 858 VAL_AS_NO_ANSWERS: Caller doesn't care about the answer results. 859 This can be used for priming the cache. 861 VAL_AS_NO_CALLBACKS: Don't call any callbacks. 863 VAL_AS_NO_CANCEL_CALLBACKS: Call callbacks with results, but don't 864 call any callbacks when the reques is canceled. 866 VAL_AS_INTERIM_CALLBACKS: Call the callback function with interim 867 results. If this flag is not specified, the callback function 868 will only be called when all validation results are ready. 870 5.1.2. val_async_select_info 872 #include 874 int val_async_select_info(val_context_t *context, 875 fd_set *fds, int *max_fd, 876 struct timeval *timeout); 878 The val_async_select_info() function examines all outstanding 879 asynchronous requests for the given context and sets the appropriate 880 file descriptors, timeout value and maximum file descriptor value in 881 preparation for a call to select(). 883 The file descriptor for each socket awating a response MUST be set in 884 the fds parameter. The function MUST NOT initialize the fd_set, as 885 the application may have already set its own file descriptors. 887 The integer value pointed to by max_fd MUST be set to the highest 888 file descriptor number of any pending asynchronous request, unless 889 that value is less than the current vaule of max_fd. In that case, 890 the max_fd value MUST NOT be changed. 892 The timeout structure MUST be set to the lowest timeout value of any 893 pending asynchronous query timeout which is less than the current 894 value in timeout. 896 After the application call select, val_async_check_wait() (see 897 Section 5.1.3) should be called with the fd_set and number of ready 898 file descriptors returned by select. Example code is provided in 899 Appendix C. 901 5.1.3. val_async_check_wait 903 #include 905 int val_async_check_wait(val_context_t *ctx, fd_set *fds, 906 int *nfds, struct timeval *timeout, 907 unsigned int flags); 909 The val_async_check_wait() function handles timeouts or processes DNS 910 responses to outstanding queries. It may also call callbacks for 911 completed requests. 913 The function provides two modes of operation. The first is for use 914 with an application that has its own select() loop. The applications 915 sets its own file descriptors, calls val_async_select_info() to set 916 file descriptors for pending queries and calls select(). The fds and 917 nfds parameters from select are passed in to val_async_check_wait and 918 the timeout value is ignored. If the implementation processes 919 responses for a file descriptor, the implementation SHOULD clear the 920 appropriate file descriptor in fds and decrement nfds. 922 In the second mode of operation, the fds and nfds parameters are set 923 to NULL and a timeout value is specified. The function will call 924 val_async_select_info() and select() internally, and process any 925 responses received before the timeout value expires. 927 Example code is provided in Appendix C. 929 5.2. Asynchronous Callbacks 931 #include 933 typedef struct val_cb_params_s { 934 val_status_t val_status; 935 char *name; 936 int class_h; 937 int type_h; 938 int retval; 939 struct val_result_chain *results; 940 struct val_answer_chain *answers; 941 } val_cb_params_t; 943 typedef int (*val_async_event_cb)(val_async_status *as, int event, 944 val_context_t *ctx, void *user_ctx, 945 val_cb_params_t *callback_params); 947 When an asynchronous request is submitted, a callback function and 948 user context may be provided by the caller. This callback function 949 is called when validation results are available. The user_ctx 950 parameter MUST be the value given by the caller when the request was 951 submitted. 953 The callback params structure contains the orginal query parameters 954 (name, class and type), the 'return value' for the operation, 955 pointers to the result and answer chains, and the final validation 956 status. This structure will be released when the callback is 957 completed. The application can assume responsibility for any of the 958 pointer values by copying them and setting the pointers in the 959 callback param structure to NULL. The application then becomes 960 responsible for releasing the memory with val_free_result_chain (see 961 Section 4.1) and/or val_free_answer_chain (see Section 3.4), as 962 appropriate. 964 The following event types are defined: 966 VAL_AS_EVENT_COMPLETED: The request completed. 968 VAL_AS_EVENT_INTERIM: The request is still being processed, but some 969 interim results are available. 971 VAL_AS_EVENT_CANCELED: The request was canceled. The val_status, 972 results and answers members of the callback parameter structure 973 are undefined. 975 Possible codes for val_status are listed in Section 8.1. When 976 evaluating the validity of a DNS response, applications SHOULD use 977 the functions described in Section 8.2 instead of directly inspecting 978 the DNSSEC validation status code returned in val_status. 980 After the callback function has completed, the implementation SHOULD 981 release all resources allocated for the request. 983 5.3. Asynchronous Status 985 An application which submits asynchronous requests needs a way to 986 refer to each request for future operations. This asynchronous 987 status object is an implementation specific opaque object which an 988 uniquely identifies a particular request. 990 When an asynchronous request is submitted, the implementation MUST 991 create an asynchronous status object to return to the caller. The 992 size of the object SHOULD be at least as large as the native pointer 993 type. 995 5.3.1. Operations on asynchronous status objects 997 The API supports the following operations to manipulate asynchronous 998 requests: 1000 5.3.1.1. val_async_cancel 1002 #include 1004 int val_async_cancel( val_context_t *context, 1005 val_async_status *async_status, 1006 unsigned int flags); 1008 This function will cancel an outstanding asynchronous request. All 1009 resources used for the request SHOULD be released. 1011 The following flags may be set for the request. The numerical values 1012 for the flags are implementation-specific. 1014 VAL_AS_CANCEL_NO_CALLBACKS: Do not call completed or cancelled 1015 callbacks. 1017 6. DNSSEC Validator Context API 1019 DNSSEC validator policy can be used to influence the DNSSEC 1020 validation outcome. Examples of DNSSEC validator policy include 1021 DNSSEC trust anchors for different zones and acceptable clock-skew 1022 values for checking inception and expiration times on signatures from 1023 different zones. 1025 DNSSEC validator policy is stored in the local system configuration 1026 (for example, the configuration file /etc/dnsval.conf) and could be 1027 configured differently for different applications and operating 1028 scenarios. Policies are identified by simple text strings called 1029 labels, which MUST be unique within the system configuration. As an 1030 example, "browser" could be used as the label that defines the DNSSEC 1031 validator policy for all web-browsers in a system. The manner of 1032 supplying the validation policy label to an application is 1033 implementation-specific, but the label MAY also be supplied during 1034 application-startup through the environment variable, 1035 VAL_CONTEXT_LABEL. 1037 All DNSSEC validator policy definitions in the system configuration 1038 are implementation-specific. 1040 6.1. val_create_context, val_free_context 1042 #include 1044 int val_create_context( char *label, 1045 val_context_t **newctx ); 1047 void val_free_context( val_context_t *ctx ); 1049 These function create and release, respectively, validator context 1050 objects. 1052 An application maintains a run-time handle to its validator policy 1053 through the validator context. val_create_context() creates a new 1054 DNSSEC validator context. The label parameter identifies the DNSSEC 1055 validator policy to be used by the application for DNSSEC validation. 1056 The manner in which the label argument is used within the system 1057 configuration to identify specific validator policy settings is 1058 implementation-specific. However, all libraries that implement this 1059 API MUST internally create a DNSSEC validator context with a (system- 1060 defined) default DNSSEC validator policy if label is NULL. 1062 The val_create_context() function MUST return 0 on success, and an 1063 error code from Section 7 on failure. Memory for the newly created 1064 DNSSEC validator context MUST be returned in the newctx field. This 1065 memory MUST be released when applications invoke the 1066 val_free_context() function. newctx MUST be set to NULL if an error 1067 is encountered. 1069 6.2. val_context_setqflags 1071 #include 1073 int val_context_setqflags(val_context_t *context, 1074 unsigned char action, 1075 unsigned int flags); 1077 This function allows an application to set or reset default query 1078 flags for a given context. This enables the application to alter the 1079 DNSSEC validator processing, while still having most of the granular 1080 default configuration specified in its configuration file. 1082 The application may specify one of the following action types, where 1083 their numeric values are implementation-specific. 1085 VAL_CTX_FLAG_SET: Set the given flag as one of the default query 1086 flags for the context. 1088 VAL_CTX_FLAG_RESET: Reset the given flag if it was set as one of the 1089 default query flags for the context. 1091 7. Function Return Codes and p_val_err() 1093 The return values from functions defined in the low-level API, the 1094 DNSSEC validator-context API, and the val_get_rrset() function MUST 1095 be from the list below. Other high-level API functions mirror 1096 existing legacy DNS functions, so the return codes from these 1097 functions are identical to their predecessors. The numerical values 1098 for the return codes listed below are implementation-specific. 1100 VAL_NO_ERROR: The function call was successful. 1102 VAL_NOT_IMPLEMENTED: The implementation did not support a particular 1103 feature. 1105 VAL_RESOURCE_UNAVAILABLE: Some resource necessary for an operation 1106 (such as memory) was unavailable. 1108 VAL_BAD_ARGUMENT: An unexpected value was passed as an argument to a 1109 function. 1111 VAL_INTERNAL_ERROR: An internal error was encountered by the DNSSEC 1112 validator. 1114 VAL_CONF_PARSE_ERROR: The DNSSEC validator configuration was 1115 improperly specified in the system configuration. 1117 VAL_CONF_NOT_FOUND: The DNSSEC validator configuration could not be 1118 located in the system configuration. 1120 VAL_NO_POLICY: The DNSSEC validator policy identifier being 1121 referenced was invalid. 1123 The p_val_err() function is used to convert an error code from the 1124 list above to a string representation. 1126 #include 1128 const char *p_val_err(int err); 1130 The returned value from p_val_err() MAY be the string conversion for 1131 the corresponding error code identifier. For example, the return 1132 value from p_val_err(VAL_NO_ERROR) MAY be "VAL_NO_ERROR". 1134 8. Evaluating Response Validity 1136 The result of DNSSEC validation for a resource record set, based on 1137 the individual status code of each element in an authentication 1138 chain, is returned in a variable of type val_status_t. val_status_t 1139 can contain one of the possible codes listed in Section 8.1. The 1140 functions provided in Section 8.2 simplify the task of evaluating 1141 validity of an answer by wrapping around the different status codes 1142 possible for each type of answer. 1144 8.1. DNSSEC Validation Status Codes and p_val_status() 1146 A variable of type val_status_t MUST contain one of the following 1147 codes (the numerical values for these codes are implementation- 1148 specific): 1150 VAL_VALIDATED_ANSWER: Returned if the combined DNSSEC validation 1151 status for a set of resource record set responses represents a 1152 validated state. 1154 VAL_TRUSTED_ANSWER: Returned if the combined DNSSEC validation 1155 status for a set of resource record set responses represents a 1156 trusted (but non-validated) state. 1158 VAL_UNTRUSTED_ANSWER: Returned if the combined DNSSEC validation 1159 status for a set of resource record set responses represents an 1160 untrusted state. 1162 VAL_SUCCESS: The response for the given resource record set was 1163 successfully validated through the DNSSEC validation process. 1165 VAL_NONEXISTENT_NAME: The proof for denial of existence for a domain 1166 name validated successfully. 1168 VAL_NONEXISTENT_TYPE: The proof for denial of existence for the 1169 resource record type for the given name was validated 1170 successfully. 1172 VAL_NONEXISTENT_NAME_NOCHAIN: The proof for non-existence of a 1173 domain name was considered valid through local DNSSEC validator 1174 configuration; the authentication chain(s) for the different 1175 components of the proof were not validated. 1177 VAL_NONEXISTENT_TYPE_NOCHAIN: The proof for non-existence of the 1178 resource record type for the name queried was considered valid 1179 through local DNSSEC validator configuration; the authentication 1180 chain(s) for the different components of the proof were not 1181 validated. 1183 VAL_PINSECURE: The record or some ancestor of the record in the 1184 authentication chain towards a DNSSEC trust anchor was known to be 1185 provably insecure and DNSSEC validator policy is configured to 1186 trust provably insecure answers. 1188 VAL_PINSECURE_UNTRUSTED: The record or some ancestor of the record 1189 in the authentication chain towards a DNSSEC trust anchor was 1190 known to be provably insecure, but DNSSEC validator policy is 1191 configured to not trust provably insecure answers. 1193 VAL_BARE_RRSIG: The response was for a query of type RRSIG. RRSIGs 1194 contain the cryptographic signatures for other DNS data and cannot 1195 themselves be validated. 1197 VAL_IGNORE_VALIDATION: DNSSEC validator policy was configured to 1198 ignore DNSSEC validation for the zone from where this data was 1199 received. 1201 VAL_UNTRUSTED_ZONE: DNSSEC validator policy was configured to not 1202 trust any response from the zone that this data was received from. 1204 VAL_OOB_ANSWER: The response was obtained using some out-of-band 1205 mechanism (for example, from a local configuration store such as 1206 /etc/hosts). 1208 VAL_BOGUS: The response could not be validated due to signature 1209 verification failures or the inability to verify proofs of non- 1210 existence for one or more components in the authentication chain. 1212 VAL_DNS_ERROR: Returned if a DNS error was encountered during the 1213 query resolution process. 1215 VAL_NOTRUST: The authentication chain does not lead up to a 1216 configured DNSSEC trust anchor. 1218 The p_val_status() function is used to convert the DNSSEC validation 1219 status code stored in a variable of type val_status_t to a string 1220 representation. 1222 #include 1224 const char *p_val_status(val_status_t status); 1226 The value returned MAY be the string conversion for the corresponding 1227 val_status_t identifier. For example, the return value from 1228 p_val_status(VAL_SUCCESS) MAY be "VAL_SUCCESS". 1230 8.2. High-Level Routines for Evaluating Validity 1232 #include 1234 int val_istrusted(val_status_t status); 1236 int val_isvalidated(val_status_t status); 1238 int val_does_not_exist(val_status_t status); 1240 These functions return a boolean value indicating whether or not the 1241 given val_status_t object is trusted, validated or does not exist 1242 (respectively). 1244 Most applications will only be interested in a single value that 1245 represents the validity of DNS data. In some instances, an 1246 application may also need to distinguish between cases where the 1247 answer was cryptographically validated and cases where the answer was 1248 locally trusted. The val_istrusted() and val_isvalidated() functions 1249 allow an application to evaluate, at a high level, the validity of a 1250 response without having to inspect the exact status code returned. 1252 The val_istrusted() function returns a single integer value 1253 representing the validity of information returned by the DNSSEC 1254 validator. The return value MUST be greater than 0 if status is one 1255 of VAL_SUCCESS, VAL_NONEXISTENT_NAME, VAL_NONEXISTENT_TYPE, 1256 VAL_NONEXISTENT_NAME_NOCHAIN, VAL_NONEXISTENT_TYPE_NOCHAIN, 1257 VAL_PINSECURE, VAL_IGNORE_VALIDATION, VAL_TRUSTED_ANSWER, or 1258 VAL_VALIDATED_ANSWER and MUST be equal to 0 for other status codes. 1260 The val_isvalidated() function returns a single integer value that 1261 indicates if the answer cryptographically chains down from a 1262 configured DNSSEC trust anchor. The return value MUST be greater 1263 than 0 if status is one of VAL_SUCCESS, VAL_NONEXISTENT_NAME, 1264 VAL_NONEXISTENT_TYPE, or VAL_VALIDATED_ANSWER and MUST be equal to 0 1265 for other status codes. 1267 The val_does_not_exist() function allows an application to determine 1268 from the DNSSEC validation status value if the answer was provably 1269 non-existent. In combination with the val_istrusted() and 1270 val_isvalidated() functions, it can give an indication about the 1271 manner in which validity was determined (cryptographically verified 1272 or trusted through local DNSSEC validator policy). The return value 1273 from val_does_not_exist() MUST be greater than 0 if status is one of 1274 VAL_NONEXISTENT_TYPE, VAL_NONEXISTENT_NAME, 1275 VAL_NONEXISTENT_NAME_NOCHAIN, or VAL_NONEXISTENT_TYPE_NOCHAIN and 1276 MUST be equal to 0 for other status codes. 1278 9. Notes On DNS Data Caching By Appplications 1280 Certain applications are known to cache DNS data for an application- 1281 specific length of time, independent of the TTL limits placed on the 1282 relevant DNS resource records. Since DNS data is ephemeral by 1283 design, any caching performed independently by applications may 1284 conflict with zone publishers' needs to change such DNS records 1285 frequently. An extension to this problem is the scenario where an 1286 application caches DNS data for an application-specific length of 1287 time during which period a zone operator may revoke a DNSSEC key, 1288 thus rendering that particular cached data as untrustworthy. 1290 It is recommended that applications MUST NOT cache DNS data in a 1291 manner that would violate the TTL limits placed on DNS records. 1292 Applications must, instead delegate the function of caching DNS data 1293 to a stub resolver or a local recursive resolver library, and to only 1294 use DNS API functions to request answers whenever necessary. The 1295 stub or recursive resolver libraries should, in turn, determine from 1296 the resource record TTLs if a cached answer is available or if a 1297 fresh DNS query needs to be issued. 1299 10. IANA Considerations 1301 This document has no actions for IANA. 1303 11. Security Considerations 1305 In certain cases DNS responses may be returned from the local system 1306 configuration (for example, from the /etc/hosts file on some 1307 systems). The application cannot assume that these answers are 1308 valid, unless the application is certain that the local configuration 1309 store contains valid data. If this information is modified during a 1310 DHCP lookup, for example, the client system should ensure that the 1311 DHCP server is a trusted source, and that the communication path 1312 between the DHCP server and the client system is secured. If these 1313 conditions are not satisfied and if the application chooses to trust 1314 a locally available answer, an attacker may be able to poison the 1315 system configuration and cause an application to use invalid answers. 1316 If applications are to treat out-of-band answers as trusted, this 1317 choice SHOULD be made explicit through a validator policy 1318 configuration knob. 1320 Applications can similarly choose to trust data from provably 1321 insecure zones. Not performing DNSSEC validation for a zone that has 1322 DNSSEC intentionally turned off is no worse than the current 1323 situation of DNSSEC-unaware applications not being able to detect the 1324 integrity of DNS data for such zones. 1326 The DNS search path may affect the result of DNSSEC validation, 1327 especially in the current Internet environment where not all DNS name 1328 servers are expected to be DNSSEC-aware. If the name server pointed 1329 to by the system configuration is not DNSSEC-aware (i.e. it does not 1330 return DNSSEC records), DNSSEC validation will not work as expected, 1331 unless the validator has certain fallback mechanims in place to try 1332 and route around such broken behavior. 1334 The DNSSEC validator configuration information needs to be protected 1335 so that it cannot be overwritten by unauthorized users or processes. 1336 The system administrator must ensure that the list of DNSSEC trust 1337 anchors is kept accurate and up-to-date. If the DNSSEC trust anchors 1338 are outdated (in the event of key-rollovers), the DNSSEC validator 1339 may either falsely mark zones as bogus or may operate with the false 1340 belief of having validated a response when the response should really 1341 have been flagged as bogus. Any subversion of the DNSSEC policy 1342 configuration (including definition of new trust anchors) can 1343 similarly completely undermine the value provided by DNSSEC. 1345 12. Acknowledgements 1347 A number of individuals have provided valuable feedback and 1348 suggestions for improving this document including the following: 1349 Lindy Foster, Wayne Morrison, Russ Mundy, Bill Sommerfeld, Wes 1350 Hardaker, Giovanni Marzot and Alfred Hoenes. The list of 1351 authentication status codes in Section 4.2 was generated through 1352 multiple brainstorming sessions at various IETF meetings; this draft 1353 draws on the results from that effort. 1355 13. References 1357 13.1. Normative References 1359 [refs.DLV] 1360 Weiler, S., "DNSSEC Lookaside Validation (DLV)", RFC 5074, 1361 November 2007. 1363 [refs.IEEE.1003.1-2004] 1364 IEEE and The Open Group, http://www.opengroup.org, "IEEE 1365 Std 1003.1-2004 Standard for Information Technology -- 1366 Portable Operating System Interface (POSIX). Open Group 1367 Technical Standard: Base Specifications, Issue 6", ISO/ 1368 IEC 9945:2003, February 2004. 1370 [refs.RFC3493] 1371 Gilligan, R., Thomson, S., Bound, J., McCann, J., and W. 1372 Stevens, "Basic Socket Interface Extensions for IPv6", 1373 RFC 3493, February 2003. 1375 [refs.RFC4034] 1376 Arends, R., Austein, R., Larson, M., Massey, D., and S. 1377 Rose, "Resource Records for the DNS Security Extensions", 1378 RFC 4034, March 2005. 1380 [refs.RFC4035] 1381 Arends, R., Austein, R., Larson, M., Massey, D., and S. 1382 Rose, "Protocol Modifications for the DNS Security 1383 Extensions", RFC 4035, March 2005. 1385 13.2. Informative References 1387 [refs.RFC1034] 1388 Mockapetris, P., "Domain Names - Concepts and Facilities", 1389 RFC 1034, November 1987. 1391 [refs.RFC2672] 1392 Crawford, M., "Non-Terminal DNS Name Redirection", 1393 RFC 2672, August 1999. 1395 [refs.RFC4033] 1396 Arends, R., Austein, R., Larson, M., Massey, D., and S. 1397 Rose, "DNS Security Introduction and Requirements", 1398 RFC 4033, March 2005. 1400 Appendix A. Zone-Specific Validator Policy Settings 1402 Zone-specific validator policy settings may have the following 1403 structure. 1405