DNS Extensions S. Krishnaswamy Internet-Draft A. Hayatnagarkar Expires: January 7, 2008 SPARTA, Inc. July 6, 2007 DNSSEC Validator API draft-hayatnagarkar-dnsext-validator-api-04 Status of this Memo By submitting this Internet-Draft, each author represents that any applicable patent or other IPR claims of which he or she is aware have been or will be disclosed, and any of which he or she becomes aware will be disclosed, in accordance with Section 6 of BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet- Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt. The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. This Internet-Draft will expire on January 7, 2008. Copyright Notice Copyright (C) The IETF Trust (2007). Abstract The DNS Security Extensions (DNSSEC) provide origin authentication and integrity of DNS data. However, the current resolver Application Programming Interface (API) does not allow a security-aware resolver to communicate detailed results of DNSSEC processing back to the application. This document describes an API between applications and a validating security-aware stub resolver that allows applications to control the validation process and obtain results of DNSSEC processing. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 1] Internet-Draft DNSSEC Validator API July 2007 Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 3. High-level Validator API . . . . . . . . . . . . . . . . . . . 4 3.1. val_gethostbyname, val_gethostbyname_r, val_gethostbyaddr, val_gethostbyaddr_r . . . . . . . . . . 5 3.2. val_getaddrinfo, val_getnameinfo, val_freeaddrinfo . . . . 7 3.3. val_query, val_res_query, val_res_search . . . . . . . . . 9 4. Low-level Validator API . . . . . . . . . . . . . . . . . . . 11 4.1. val_resolve_and_check, val_free_result_chain, p_ac_status . . . . . . . . . . . . . . . . . . . . . . . 11 4.2. Authentication Chain Status Codes . . . . . . . . . . . . 14 5. Evaluating Trustworthiness . . . . . . . . . . . . . . . . . . 17 5.1. List of Validation Status Codes . . . . . . . . . . . . . 17 5.2. Helper Routines for Evaluating Trustworthiness . . . . . . 19 6. Context Management and Validator Policy API . . . . . . . . . 20 6.1. Configuring Validator Policy . . . . . . . . . . . . . . . 21 6.2. val_create_context, val_free_context . . . . . . . . . . . 23 6.3. val_add_valpolicy, val_remove_valpolicy . . . . . . . . . 24 7. Function Return Values . . . . . . . . . . . . . . . . . . . . 24 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 25 9. Security Considerations . . . . . . . . . . . . . . . . . . . 25 10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 26 11. Normative References . . . . . . . . . . . . . . . . . . . . . 26 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 27 Intellectual Property and Copyright Statements . . . . . . . . . . 28 Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 2] Internet-Draft DNSSEC Validator API July 2007 1. Introduction The DNS Security Extensions (RFC 4033 [2], RFC 4034 [3], RFC 4035 [4]) allow resolvers to test the origin authenticity and integrity of data returned by the DNS. A validator, or more formally, a validating security-aware stub resolver, is a piece of software that performs these tests by checking the cryptographic signatures that cover DNS records and by verifying a sequence of such records from a trust anchor [2] to these signed records. This document presents an API between an application and a validator, which provides a convenient way for applications to control the DNSSEC validation process and obtain detailed validation results on which to base program behavior. The API can be broadly divided into three groups: the high-Level validator API, the low-Level validator API and the context-management API. The high-level validator API is designed for ease of use and mirrors existing DNS-related functions. This API is best suited for existing applications that use legacy DNS-related functions such as gethostbyname(), getaddrinfo() and res_query() and have no requirement for detailed validation status information. The low-level validator API allows detailed inspection of validation status values for each element of the authentication chain [2]. Validator operation can be guided by local policy. The context- management API provides functions that allow applications to control the types of policies that are used during DNSSEC validation. Section 3, Section 4, and Section 6 describe these interfaces in greater detail. The range of functions provided in this API allows for the creation of applications that are either only interested in basic DNSSEC results such as "validated" or "not-validated", or more sophisticated applications that can look for specific errors in the authentication chain as a sign of a network abnormality or attack. 2. Terminology Some of the terms used in this specification are defined below: Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 3] Internet-Draft DNSSEC Validator API July 2007 legacy functions: Functions such as gethostbyname() and getaddrinfo() that are not capable of returning validation status values for DNS responses and are typically used by DNSSEC-unaware applications. validator policy: a set of configuration parameters for the validator, which can influence the eventual outcome of the validation process. policy attribute: a configurable component of the validator policy; for instance a trust anchor setting or the acceptable clock skew value while validating inception and expiration times on signatures. validator context: an opaque structure encapsulating the validator policy. The validator context is the application's handle to the validator policy. active policy: the policy associated with a validator context. default policy: the policy definition that is used by the validator if the application does not specify its own preference while creating a validator context. 3. High-level Validator API The high-level validator API provides DNSSEC-aware substitutes for commonly used DNS functions such as gethostbyname(), getaddrinfo(), res_query() and res_search(). The high-level API provides an easy path for applications already using legacy functions to transition towards becoming DNSSEC-aware. The ctx parameter in the following functions points to the validator context. An application may either pass a context created using the val_create_context() function (Section 6) or may use an internally created default context by supplying a NULL value. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 4] Internet-Draft DNSSEC Validator API July 2007 3.1. val_gethostbyname, val_gethostbyname_r, val_gethostbyaddr, val_gethostbyaddr_r #include struct hostent *val_gethostbyname( const val_context_t *ctx, const char *name, val_status_t *val_status ); int val_gethostbyname_r( const val_context_t *ctx, const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop, val_status_t *val_status ); struct hostent *val_gethostbyaddr( const val_context_t *ctx, const char *addr, int len, int type, val_status_t *val_status ); int val_gethostbyaddr_r( const val_context_t *ctx, const char *addr, int len, int type, struct hostent *ret, char *buf, int buflen, struct hostent **result, int *h_errnop, val_status_t *val_status ); The val_gethostbyname(), val_gethostbyname_r(), val_gethostbyaddr() and val_gethostbyaddr_r() functions are DNSSEC-aware versions of the gethostbyname(), gethostbyname_r(), gethostbyaddr() and gethostbyaddr_r() legacy functions that also return the validation status of DNS responses. These functions must be only used when retrofitting DNSSEC in applications that use the above legacy functions to perform address-to-name and name-to-address translations. It is recommended that new applications that need to perform address-to-name and name-to-address translations use the functions from Section 3.2. The val_gethostbyname() function returns a pointer to a structure of type hostent for the host name provided in name. If name is an IPv4 Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 5] Internet-Draft DNSSEC Validator API July 2007 address (in standard dot notation) or an IPv6 address (in colon and possibly dot notation), no lookup is performed and val_gethostbyname() simply copies name into h_name and its struct in- addr equivalent into the h_addr_list[0] field of the returned hostnet structure. The val_gethostbyaddr() function returns a pointer to a structure of type hostent for the given host address, addr, whose length is given by the len parameter and address type is given by the type parameter. Valid address types are AF_INET and AF_INET6. As with gethostbyname() and gethostbyaddr(), the val_gethostbyname() and val_gethostbyaddr() functions set the value of the global h_errno variable and return NULL on errors and return a pointer to a static hostent structure on success. The return values from val_gethostbyname() and val_gethostbyaddr() point to static data, which may be overwritten by subsequent calls. The val_gethostbyname_r() and val_gethostbyaddr_r() functions are reentrant and thread-safe versions of the val_gethostbyname() and val_gethostbyaddr() functions. These functions return 0 on success, and a non-zero value on error. These functions do not modify the global h_errno variable, but return the error numbers in the h_errnop parameter. When these functions return, the value of result will be NULL on error or point to the ret paramter on success. Auxiliary data, which supplies the memory allocated for the returned hostent structure, is stored in the buffer buf of length buflen. If the buffer is too small, these functions will return the error ERANGE. The val_status parameter contains the status of DNSSEC validation. Possible values for this type are VAL_LOCAL_ANSWER, VAL_TRUSTED_ANSWER, VAL_VALIDATED_ANSWER and VAL_UNTRUSTED_ANSWER. A validation status of VAL_LOCAL_ANSWER is returned if the answer was returned from a local configuration store without any validation being performed. A validation status of VAL_TRUSTED_ANSWER or VAL_VALIDATED_ANSWER is returned only if the validation status values for the address and canonical name(s) within the hostent structure, if present, are themselves of the type VAL_TRUSTED_ANSWER or VAL_VALIDATED_ANSWER respectively. The trustworthiness of val_status can be easily determined using the functions described in Section 5.2. The validation status value can be converted into an ASCII string using the p_val_status() function as described in Section 5.2. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 6] Internet-Draft DNSSEC Validator API July 2007 3.2. val_getaddrinfo, val_getnameinfo, val_freeaddrinfo #include int val_getaddrinfo( const val_context_t *ctx, const char *nodename, const char *servname, const struct addrinfo *hints, struct val_addrinfo **res , val_status_t *val_status); int val_getnameinfo( const val_context_t *ctx, const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags, val_status_t *val_status ); void val_freeaddrinfo( struct val_addrinfo *ainfo ); struct val_addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct val_addrinfo *ai_next; val_status_t ai_val_status; } The val_getaddrinfo() function returns the address and service information for the specified domain name and service. It is a DNSSEC-aware version of the getaddrinfo() legacy function (RFC 3493 [1]). The val_getaddrinfo() function returns its results in the res parameter. The value of res either points to a valid val_addrinfo structure on success or is NULL in case of on error. The val_addrinfo structure is a linked list and is an augmented form of the addrinfo structure. It contains an additional ai_val_status field that represents the DNSSEC validation status for the answer represented by that particular element in the linked list. The combined DNSSEC validation status value for all answers returned by Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 7] Internet-Draft DNSSEC Validator API July 2007 val_getaddrinfo() is returned in the val_status paramter. The memory for the value of res is dynamically allocated and the caller should release it after use with the val_freeaddrinfo() function. The syntax and semantics of other parameters in val_getaddrinfo() are identical to those specified in [1]. The val_getnameinfo() function performs an address-to-name translation in a protocol independent manner. It is a DNSSEC-aware version of the getnameinfo() legacy function (RFC 3493 [1]). This function returns the DNSSEC validation status in the val_status parameter. The syntax and semantics of other parameters in val_getnameinfo() are identical to that specified for getnameinfo() in [1]. The val_getaddrinfo() and val_getnameinfo() functions return 0 on success and a non-zero value on error. Possible values for val_status and ai_val_status are VAL_LOCAL_ANSWER, VAL_TRUSTED_ANSWER, VAL_VALIDATED_ANSWER and VAL_UNTRUSTED_ANSWER. A validation status of VAL_LOCAL_ANSWER is returned if the answer was returned from a local configuration store without any validation being performed. A validation status of VAL_TRUSTED_ANSWER or VAL_VALIDATED_ANSWER is returned in val_status only if all the ai_val_status values in the val_addrinfo list are themselves VAL_TRUSTED_ANSWER or VAL_VALIDATED_ANSWER respectively. Similarly, a validation status of VAL_TRUSTED_ANSWER or VAL_VALIDATED_ANSWER is returned in ai_val_status only if the validation status values for the address and canonical name(s) within the given val_addrinfo structure are themselves validated or trusted respectively. The trustworthiness of valdation status values can be easily determined using the functions described in Section 5.2. The validation status values can be converted into ASCII strings using the p_val_status() function as described in Section 5.2. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 8] Internet-Draft DNSSEC Validator API July 2007 3.3. val_query, val_res_query, val_res_search #include int val_query( const val_context_t *ctx, const char *domain_name, const u_int16_t class, const u_int16_t type, const u_int8_t flags, struct val_response **resp); int val_free_response(struct val_response *resp); int val_res_query(const val_context_t *ctx, const char *domain_name, int class, int type, u_char *answer, int anslen, val_status_t *val_status); int val_res_search(const val_context_t *ctx, const char *domain_name, int class, int type, u_char *answer, int anslen, val_status_t *val_status); struct val_response { unsigned char *vr_response; int vr_length; val_status_t vr_val_status; struct val_response *vr_next; }; The val_query() and val_res_query() functions query the name server for the fully qualified domain name present in the domain_name field of the given class and type. In addition to the answers to the query, they return the status of DNSSEC validation. They are intended as DNSSEC-aware replacements for the res_query() function. val_res_search() is a DNSSEC-aware substitute for the res_search() legacy function. The flags parameter in val_query() controls the scope of validation and the output format. When the VAL_QUERY_MERGE_RRSETS flag is specified, all RRsets in the answer are merged into a single response and returned in the first (and only) element of the resp linked list. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 9] Internet-Draft DNSSEC Validator API July 2007 The vr_response field of this element will have a format similar to the answer returned by res_query(). The VAL_QUERY_DONT_VALIDATE flag forces the validator to disable validation for the given query. The val_query() function returns 0 on success and a non-zero error code on failure. On success, the memory pointed to by resp contains a linked-list of responses returned by the validator. By default, each val_response structure in the linked-list within resp holds a single RRset response. The format of the vr_response field within the val_response structure is similar to the format of the answer returned by res_query() and is of length vr_length. The vr_val_status field contains the status of DNSSEC validation for that particular RRset. Possible values for the validation status are defined in Section 5.1 and may be converted into an ASCII string using the p_val_status() function as described in Section 5.2. Elements within the resp linked-list may be accessed by traversing the list using the vr_next field. The memory for the value of resp is internally allocated and must be released by the application using the val_free_response() function when no longer needed. The val_res_query() function is semantically closer to the res_query() function. It internally invokes the val_query() function supplying it with the VAL_QUERY_MERGE_RRSETS flag. On success, the response will be copied to answer, not to exceed the length specified in anslen. val_res_search() provides the same functionality as val_res_query(); in addition, it implements the search rules controlled by DNS search paths defined in the configuration system. The val_res_query() and val_res_search() functions return the size of the response packet on success and -1 on failure. The caller must check that the returned packet size is not greater than the length of the buffer provided in anslen. If the returned size is greater, the caller should allocate a larger buffer and call these functions again. The combined validation status value is returned in the val_status field. Possible values for the val_status field are VAL_TRUSTED_ANSWER, VAL_VALIDATED_ANSWER and VAL_UNTRUSTED_ANSWER. A validation status of VAL_TRUSTED_ANSWER or VAL_VALIDATED_ANSWER is returned only if all the individual RRsets are themselves trusted or validated respectively. The trustworthiness of val_status can be easily determined using the functions described in Section 5.2. The validation status value can be converted into an ASCII string using the p_val_status() function as described in Section 5.2. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 10] Internet-Draft DNSSEC Validator API July 2007 4. Low-level Validator API The low-level validator API provides applications with greater control and visibility into the validation process. The functions and data structures defined in the low-level validator API are summarized below. 4.1. val_resolve_and_check, val_free_result_chain, p_ac_status #include int val_resolve_and_check( const val_context_t *context, u_char *domain_name_n, const u_int16_t class, const u_int16_t type, const u_int8_t flags, struct val_result_chain **results); void val_free_result_chain( struct val_result_chain *results); char *p_ac_status(val_astatus_t status); int ns_name_pton(const char *src, u_char *dst, int dstsize); int ns_name_pton(const u_char *src, char *dst, int dstsize); #define MAX_PROOFS 4 struct val_result_chain { val_status_t val_rc_status; struct val_authentication_chain *val_rc_answer; int val_rc_proof_count; struct val_authentication_chain *val_rc_proofs[MAX_PROOFS]; struct val_result_chain *val_rc_next; }; struct val_authentication_chain { val_astatus_t val_ac_status; struct val_rrset *val_ac_rrset; struct val_authentication_chain *val_ac_trust; }; struct val_rrset { u_int8_t *val_msg_header; Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 11] Internet-Draft DNSSEC Validator API July 2007 u_int16_t val_msg_headerlen; u_int8_t *val_rrset_name_n; u_int16_t val_rrset_class_h; u_int16_t val_rrset_type_h; u_int32_t val_rrset_ttl_h; u_int8_t val_rrset_section; struct sockaddr *val_rrset_server; struct rr_rec *val_rrset_data; struct rr_rec *val_rrset_sig; }; struct rr_rec { u_int16_t rr_rdata_length_h; u_int8_t *rr_rdata; val_astatus rr_status; struct rr_rec *rr_next; }; The val_resolve_and_check() function queries a set of name servers for the tuple and then verifies and validates the responses received. The verification step checks the validity of the RRSIGs while the validation step performs verification down the authentication chain from a configured trust anchor. The context parameter points to the validator context. An application may explicitly create a context using the val_create_context() function described in Section 6, or allow the validator to create one internally by specifying the value of NULL for this parameter. Only the VAL_QUERY_DONT_VALIDATE flag is currently defined. This flag forces validation to be ignored for this name -- no authentication chain is constructed for the response. The domain name specified in domain_name_n must be in the DNS wire format. Names can be converted from a normal string representation to the DNS wire format and vice-versa using the ns_name_pton() and ns_name_ntop() functions repectively. src contains the data to be converted and dst contains the converted value. dstsize must be large enough to hold the converted value. The ns_name_pton() and ns_name_ntop() functions return the number of bytes written to dst on success or -1 on failure. val_resolve_and_check() returns 0 on success and an error code from Section 7 on failure. On success, the val_resolve_and_check() function internally allocates memory for the value of the result parameter. This must be released after use using the val_free_result_chain() function. Answers to the query are returned in results, which is a linked-list Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 12] Internet-Draft DNSSEC Validator API July 2007 of val_result_chain structures. Each element in the linked-list corresponds to a distinct RRset returned in the answer section along with any associated proofs of non-existence. Multiple RRs within the RRset are all part of the same answer. Multiple answers are possible when the query type is ANY or RRSIG. The val_rc_next field can be used to iterate through the list of all results returned by the validator. The consolidated validation status value for an RRset, based on the individual status values for all components in the authentication chain, is stored in the val_rc_status field. Possible values for val_rc_status are listed in Section 5.1 and can be converted into an ASCII string using the p_val_status() function as described in Section 5.2. Members of the authentication chain sequence are encapsulated in the val_authentication_chain linked list. The val_rc_answer field in the val_result_chain structure points to the first element in the authentication chain sequence proceeding from the signed record towards the trust anchor. Any proofs of non-existence are returned in the val_rc_proofs array. val_rc_proof_count provides the number of proof elements that are available. Within the val_authentication_chain structure, the val_ac_status field returns the validation status for the specified RRset. Possible values for this field are defined in Section 4.2. These values can be converted to ASCII format using the p_ac_status() function. The val_ac_trust field points to the next element in the authentication chain proceeding from the signed record towards the trust anchor. For a element with type DNSKEY, the next element corresponds to a DS record in the parent zone and for a DS record the next element corresponds to the DNSKEY in the current zone. The value of val_ac_trust is NULL when the current element in the linked list points to a valid trust anchor or when an error condition is encountered. The value stored in the val_ac_status field can be used to differentiate between these two cases. The val_ac_rrset field in the val_authentication_chain structure contains the actual RRset data. The information stored in the val_rrset structure includes the DNS response header in the val_msg_header field with length given by val_msg_headerlen, and the DNS response "envelope" comprising of the name, class, type and time- to-live tuple in the val_rrset_name_n, val_rrset_class_h, val_rrset_type_h and val_rrset_ttl_h fields respectively. val_rrset_name_n is stored in the DNS wire format. The name servers from where these RRsets were received is stored in the val_rrset_server field. The section where the RRset appeared in the DNS response is saved in the val_rrset_section field within the val_rrset structure, and may contain one of the following values: Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 13] Internet-Draft DNSSEC Validator API July 2007 VAL_FROM_ANSWER: the RRset was present in the answer section of the DNS response. VAL_FROM_AUTHORITY: the RRset was present in the authority section of the DNS response. VAL_FROM_ADDITIONAL: the RRset was present in the additional section of the DNS response. The response RDATA is stored in val_rrset_data. Any associated RRSIGs are stored in val_rrset_sig. Both of these variables are of type rr_rec, which is a list of name-value pairs for each resource- record within the RRset. The rr_status member in rr_rec is only relevant for the signatures present in val_rrset_sig or when val_rrset_data points to DNSKEY or DS RRs. This field takes on a subset all status values possible for val_astatus_t as defined in Section 4.2. 4.2. Authentication Chain Status Codes The status value stored in the val_ac_status member of the val_authentication_chain structure can be used to determine the validity of information contained in the structure and the reason for verification failure, if any. It can contain one of the following values: VAL_AC_UNSET: returned if the status was not set due to some other error condition observed in the authentication chain. VAL_AC_IGNORE_VALIDATION: returned if validation for the given resource record was ignored. VAL_AC_TRUSTED_ZONE: returned if local policy defined a given zone as trusted, with no further validation being deemed necessary. VAL_AC_UNTRUSTED_ZONE: returned if local policy defined a given zone as untrusted, with no further validation being deemed necessary. VAL_AC_PROVABLY_UNSECURE: returned if the authentication chain from a trust anchor to a given zone could not be constructed due to the provable absence of a DS record for this zone in the parent. VAL_AC_BARE_RRSIG: returned if the response was for a query of type RRSIG. RRSIGs contain the cryptographic signatures for other DNS data and cannot themselves be validated. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 14] Internet-Draft DNSSEC Validator API July 2007 VAL_AC_NO_TRUST_ANCHOR: returned if there was no matching trust anchor for a given authentication chain. VAL_AC_TRUST_KEY: returned if a given DNSKEY or a DS record was locally defined to be a trust anchor. VAL_AC_RRSIG_MISSING: returned if RRSIG data could not be retrieved for a resource record. VAL_AC_DNSKEY_MISSING: returned if the DNSKEY for a zone could not be retrieved. VAL_AC_DS_MISSING: returned if the DS record covering a DNSKEY record was not available. VAL_AC_DATA_MISSING: returned if there was no data available for a response when there should have been. VAL_AC_NOT_VERIFIED: returned if all RRSIGs covering an RRset could not be verified. VAL_AC_VERIFIED: returned if at least one RRSIG covering a resource record verified successfully. VAL_AC_DNS_QUERY_ERROR: returned if an error was encountered while sending out the query. VAL_AC_DNS_RESPONSE_ERROR: returned if no response was returned or some error was returned as an rcode in the DNS response. VAL_AC_DNS_REFERRAL_ERROR: returned if referrals for a query could not be successfully followed. VAL_AC_DNS_MISSING_GLUE: returned if glue records were not available for a referral. VAL_AC_DNS_CONFLICTING_ANSWERS: returned if multiple answers were returned for a query, but they were inconsistent with each other. VAL_AC_DNS_WRONG_ANSWER: returned if a received message was not a valid response to a query. For each signature rr_rec member within the authentication chain val_ac_rrset, the validation status stored in the variable rr_status can return one of the following values: Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 15] Internet-Draft DNSSEC Validator API July 2007 VAL_AC_RRSIG_VERIFIED: returned if the RRSIG verified successfully. VAL_AC_WCARD_VERIFIED: returned if a given RRSIG covering a resource record showed that the record was wildcard expanded. VAL_AC_RRSIG_VERIFIED_SKEW: returned if the RRSIG was verified only after clock skew was taken into consideration. VAL_AC_WCARD_VERIFIED_SKEW: returned if a given RRSIG covering a resource record showed that the record was wildcard expanded, and if the RRSIG was verified only after clock skew was taken into consideration. VAL_AC_DNSKEY_NOMATCH: returned if an RRSIG was created by a DNSKEY that did not exist in the apex keyset. VAL_AC_WRONG_LABEL_COUNT: returned if the number of labels on the signature was greater than the the count given in the RRSIG RDATA. VAL_AC_BAD_DELEGATION: returned if an RRSIG on the DNSKEY was created with a key that did not exist in the parent DS record set. VAL_AC_INVALID_RRSIG: returned if the RRSIG could not be parsed. VAL_AC_RRSIG_NOTYETACTIVE: returned if the RRSIG's inception time was in the future. VAL_AC_RRSIG_EXPIRED: returned if the RRSIG had expired. VAL_AC_ALGORITHM_NOT_SUPPORTED: returned if the RRSIG algorithm was not supported. VAL_AC_RRSIG_VERIFY_FAILED: returned if a given RRSIG covering an RRset was bogus. VAL_AC_RRSIG_ALGORITHM_MISMATCH: returned if the keytag referenced in the RRSIG matched a DNSKEY but the algorithms were different. For each rr_rec member of type DNSKEY (or DS where relevant) within the authentication chain val_ac_rrset, the validation status stored in the variable rr_status can return one of the following values: VAL_AC_SIGNING_KEY: returned if this DNSKEY was used to create an RRSIG for the resource record set. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 16] Internet-Draft DNSSEC Validator API July 2007 VAL_AC_VERIFIED_LINK: returned if this DNSKEY provided the link in the authentication chain from the trust anchor to the signed record. VAL_AC_UNKNOWN_DNSKEY_PROTOCOL: returned if the DNSKEY protocol number was unrecognized. VAL_AC_UNKNOWN_ALGORITHM_LINK: returned if this DNSKEY formed a link in the authentication chain from the trust anchor to the signed record, but the DNSKEY algorithm was unknown. VAL_AC_INVALID_KEY: returned if the key used to verify the RRSIG was not valid DNSKEY. VAL_AC_ALGORITHM_NOT_SUPPORTED: returned if the DNSKEY or DS algorithm was not supported. 5. Evaluating Trustworthiness The result of DNSSEC validation for an RRset, based on the individual (val_ac_status) status values of each element in the authentication chain, is returned in a variable of type val_status_t. Possible values for the val_status_t type are listed in Section 5.1. The helper functions provided in Section 5.2 simplify the task of evaluating trustworthiness of an answering by wrapping around the different classes of status values possible for val_status_t. 5.1. List of Validation Status Codes VAL_SUCCESS: returned if the response was successfully verified and validated. VAL_NONEXISTENT_NAME: returned if the proof for denial of existence for a domain name was validated successfully. VAL_NONEXISTENT_TYPE: returned if the proof for denial of existence for the resource record type for the name queried was validated successfully. VAL_IGNORE_VALIDATION: returned if local policy was configured to ignore validation for the zone from which this data was received. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 17] Internet-Draft DNSSEC Validator API July 2007 VAL_TRUSTED_ZONE: returned if local policy considered the zone from which this was data received to be trusted. VAL_NONEXISTENT_NAME_NOCHAIN: returned if the proof for denial of existence for a domain name was considered trustworthy, but the authentication chain(s) for the different components of the proof were not themselves validated. VAL_NONEXISTENT_TYPE_NOCHAIN: returned if the proof for denial of existence for the resource record type for the name queried was considered trustworthy, but the authentication chain(s) for the different components of the proof were not themselves validated. VAL_PROVABLY_UNSECURE: returned if the record or some ancestor of the record in the authentication chain towards the trust anchor was known to be provably unsecure, and if local policy defines this state as trusted. VAL_LOCAL_ANSWER: returned if the response was obtained locally (for example, a file such as /etc/hosts). VAL_BARE_RRSIG: returned if the response was for a query of type RRSIG. RRSIGs contain the cryptographic signatures for other DNS data and cannot themselves be validated. VAL_NOTRUST: returned if all available components in the authentication chain were successfully verified but there was no trust anchor available. VAL_BOGUS_PROVABLE: returned if the response could not be validated due to signature verification failures or the inability to verify proofs for exactly one component in the authentication chain below the trust anchor. VAL_BOGUS: returned if the response could not be validated due to signature verification failures or the inability to verify proofs for an indeterminate number of components in the authentication chain. VAL_BAD_PROVABLY_UNSECURE: returned if the record or some ancestor of the record in the authentication chain towards the trust anchor was known to be provably unsecure, but local policy defines this state as untrusted. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 18] Internet-Draft DNSSEC Validator API July 2007 VAL_DNS_QUERY_ERROR: returned if an error was encountered while sending out the query. VAL_DNS_RESPONSE_ERROR: returned if no response was returned or some error was returned as an rcode in the DNS response. VAL_DNS_REFERRAL_ERROR: returned if referrals for a query could not be successfully followed. VAL_DNS_MISSING_GLUE: returned if glue records were not available for a referral. VAL_DNS_CONFLICTING_ANSWERS: returned if multiple answers were returned for a query, but they were inconsistent with each other. VAL_DNS_WRONG_ANSWER: returned if a received message was not a valid response to a query. VAL_UNTRUSTED_ZONE: returned if local policy considered the zone from which this was data received to be untrusted. VAL_VALIDATED_ANSWER: returned if the combined validation status for a set of validator status values represents a validated state. VAL_TRUSTED_ANSWER: returned if the combined validation status for a set of validator status values represents a trusted (but non- validated) state. VAL_UNTRUSTED_ANSWER: returned if the combined validation status for a set of validator status values represents an untrusted state. 5.2. Helper Routines for Evaluating Trustworthiness #include int val_istrusted(val_status_t status); int val_isvalidated(val_status_t status); int val_does_not_exist(val_status_t status); char *p_val_status(val_status_t err); Most applications will be interested in a single value that represents the trustworthiness of data. In some instances an application may also need to distinguish between cases where the answer was cryptographically validated and cases where the answer was locally trusted. The val_istrusted() and val_isvalidated() functions Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 19] Internet-Draft DNSSEC Validator API July 2007 allow an application to evaluate, at a high level, the trustworthiness of a response without having to inspect the exact status value returned. The val_istrusted() function returns a single boolean value representing the trustworthiness of information returned by the validator. The return value is greater than 0 if status is one of VAL_SUCCESS, VAL_NONEXISTENT_NAME, VAL_NONEXISTENT_TYPE, VAL_NONEXISTENT_NAME_NOCHAIN, VAL_NONEXISTENT_TYPE_NOCHAIN, VAL_PROVABLY_UNSECURE, VAL_IGNORE_VALIDATION, VAL_TRUSTED_ZONE, VAL_TRUSTED_ANSWER, or VAL_VALIDATED_ANSWER and is equal to 0 for other status values. The val_isvalidated() function returns a single boolean value that indicates if the answer cryptographically chains down from a configured trust anchor. The return value is greater than 0 if status is one of VAL_SUCCESS, VAL_NONEXISTENT_NAME, VAL_NONEXISTENT_TYPE, or VAL_VALIDATED_ANSWER and is equal to 0 for other status values. The val_does_not_exist() function returns a single boolean value that indicates if the given validation status represents one of the non- existence types. The return value is greater than 0 if status is one of VAL_NONEXISTENT_TYPE, VAL_NONEXISTENT_NAME, VAL_NONEXISTENT_NAME_NOCHAIN, or VAL_NONEXISTENT_TYPE_NOCHAIN. The val_does_not_exist() function allows an application to determine from the validation status value if the answer was provably non- existent. In combination with the val_istrusted() and val_isvalidated() functions, it can give an indication about the manner in which trustworthiness was determined. The p_val_status() function can be used to convert the validation status information in val_status_t into an ASCII string format. The returned values are string representations of the definitions given in Section 5.1. 6. Context Management and Validator Policy API Applications can use local policy to influence the validation outcome. Examples of local policy elements include trust anchors for different zones and acceptable clock-skew policy for inception and expiration times on signatures. Local policy may be different for different applications and operating scenarios. The following subsections describe the manner in which applications may be able to customize their policies for DNSSEC validation. Krishnaswamy & Hayatnagarkar Expires January 7, 2008 [Page 20] Internet-Draft DNSSEC Validator API July 2007 6.1. Configuring Validator Policy Local policy for the validator is stored in the local configration system (for example, the configuration file /etc/dnsval.conf). Policies are identified by simple text strings called labels, which must be unique within the configuration system. As an example, "browser" could be used as the label that defines the validator policy for all web-browsers in a system. A label value of ":" identifies the "default" policy, or the policy that is used when a NULL context is specified as the ctx parameter. The default policy is unique within the configuraion system. Furthermore, the ':' character is only allowed in the default policy label. The configuration system must flag an error if some other label contains the ':' character. If the policy identified by the ':' label does not exist in the configuration system, the first policy in the configuration system is used as the default policy. Policy definitions have the following structure.