
=pod

=head1 NAME

I<val_create_context()>
I<val_free_context()> - manage validator context

I<val_context_setqflags()> - manage validator context flags

I<val_resolve_and_check()>, I<val_free_result_chain()> - query and validate
answers from a DNS name server

I<val_istrusted()> - check if status value corresponds to that of a
trustworthy answer

I<val_isvalidated()> - check if status value represents an
answer that cryptographically chains down from a configured
trust anchor

I<val_does_not_exist()> - check if status value represents
one of the non-existence types

I<p_val_status()>, I<p_ac_status()>, I<p_val_error()> - display validation status,
authentication chain status and error information

I<val_log_add_optarg> - control log message verbosity and output location

=head1 SYNOPSIS

  #include <validator.h>

  int val_create_context(const char *label, val_context_t **newcontext);

  int val_context_setqflags(val_context_t *context, 
                            unsigned char action, 
                            unsigned int flags);

  int val_resolve_and_check(val_context_t *context,
                         const char *domain_name,
                         int class,
                         int type,
                         unsigned int  flags,
                         struct val_result_chain  **results);

  char *p_val_status(val_status_t valerrno);

  char *p_ac_status(val_astatus_t auth_chain_status);

  char *p_val_error(int err);

  int val_istrusted(val_status_t val_status);

  int val_isvalidated(val_status_t val_status);

  int val_does_not_exist(val_status_t status);

  val_log_t *val_log_add_optarg(const char *args, int use_stderr);

  void val_free_result_chain(struct val_result_chain *results);

  void val_free_context(val_context_t *context);


=head1 DESCRIPTION

The I<val_resolve_and_check()> function queries a set of name servers for
the I<<domain_name, type, class>> tuple and to verifies and validates the
response.  Verification involves checking the RRSIGs, and validation is
verification of an authentication chain from a configured trust anchor.

The I<flags> parameter can be used to control the results of validation.
The following values, which may be ORed together, are currently defined 
for this field: 

=over 4

=item B<VAL_QUERY_DONT_VALIDATE> 

causes the validator to disable validation for this query.  

=item B<VAL_QUERY_IGNORE_SKEW> 

causes the validator to disable checking signature inception and
expiration times on RRSIGs.  

=item B<VAL_QUERY_AC_DETAIL> 

causes the validator to copy the authentication chain details into the 
val_rc_answer member within the returned val_result_chain structure. 

=item B<VAL_QUERY_ASYNC> 

enables asynchronous query resolution for that lookup. 

=item B<VAL_QUERY_NO_DLV> 

causes the validator to disable DLV processing for this query.  
This is only available if the I<libval(3)> library has
been compiled with DLV support.

=item B<VAL_QUERY_NO_EDNS0_FALLBACK>

In querying various name servers, libsres will also attempt multiple EDNS0
sizes, ending with a query that has EDNS0 disabled (i.e. no CD bit set).
This option causes libval to disable EDNS0 fallback for the query.

=item B<VAL_QUERY_RECURSE>

forces libval to recursively answer the query by iteratively querying
various name servers in the delegation hierarchy, instead of
requesting this information from
any caching name server that may be configured in B<dnsval.conf>

=item B<VAL_QUERY_SKIP_RESOLVER>

forces libval to only look at its cache while trying to resolve a name. 

=item B<VAL_QUERY_SKIP_CACHE>

forces libval to ignore cached data while trying to resolve a name. 

=back

The first parameter to I<val_resolve_and_check()> is the validator context.
Applications can create a new validator context using the
I<val_create_context()> function.  This function parses the resolver and
validator configuration files and creates the handle I<newcontext> to this
parsed information.  Information stored as part of validator context includes
the validation policy and resolver policy.

Validator and resolver policies are read from the B</etc/dnsval.conf> and
B</etc/resolv.conf> files by default.  B</etc/root.hints> provides
bootstrapping information for the validator when it functions as a full
resolver (see I<dnsval.conf(3)>). These defaults may be different if 
any other value was specified at library configure time. If the default 
resolver configuration file is not found at the specified location, libval
will also try to fallback to /etc/resolv.conf as a last resort.

Default query flags can be set and unset for a given context using 
I<val_context_setqflags()>. This allows an application to alter the 
DNSSEC validator processing, while still having most of the more 
granular default configuration specified in its configuration file.  
The I<action> parameter can be set to one of the following.

=over 4

=item B<VAL_CTX_FLAG_SET> 

causes the validator to set the given flag as one of the default 
query flags. 

=item B<VAL_CTX_FLAG_RESET> 

causes the validator to reset the given flag if it was set as one 
of the default query flags for the context.

=back

Answers returned by I<val_resolve_and_check()> are made available in the
I<*results> linked list.  Each answer corresponds to a distinct RRset; multiple
RRs within the RRset are part of the same answer.  Multiple answers are possible when
I<type> is I<ns_t_any> or I<ns_t_rrsig>.

Individual elements in I<*results> point to I<val_authentication_chain> linked
lists.  The authentication chain elements in I<val_authentication_chain> contain
the actual RRsets returned by  the name server in response to the query.

Validation result values returned in I<val_result_chain> and
authentication chain status values returned in each element of the
I<val_authentication_chain> linked list can be can be converted into ASCII
format using the I<p_val_status()> and I<p_ac_status()> functions respectively.

While some applications such as DNSSEC troubleshooting utilities and packet
inspection tools may look at individual authentication
chain elements to identify the actual reasons for validation error,
most applications will only be interested in a single error code for determining
the authenticity of data.

I<val_isvalidated()> identifies if a given
validation result status value corresponds to an answer that was
cryptographically verified and validated using a locally configured
trust anchor.

I<val_istrusted()> identifies if a given
validator status value is trusted.  An answer may be locally trusted
without being validated.

I<val_does_not_exist()> identifies if a given
validator status value corresponds to one of the non-existence types.

The I<libval> library internally allocates memory for I<*results> and this
must be freed by the invoking application using the I<free_result_chain()>
interface.


=head1 DATA STRUCTURES

=over 4

=item I<struct val_result_chain>

  struct val_result_chain
  {
      val_status_t                     val_rc_status;
      char                            *val_rc_alias;
      struct val_rrset_rec            *val_rc_rrset;
      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;
  };

=over 4


=item I<val_rc_answer>

Authentication chain for a given RRset.

=item I<val_rc_next>

Pointer to the next RRset in the set of answers returned for a query.

=item I<val_rc_proofs>

Pointer to authentication chains for any proof of non-existence that were
returned for the query.

=item I<val_rc_proof_count>

Number of proof elements stored in I<val_rc_proofs>. The number cannot exceed
B<MAX_PROOFS>.

=item I<val_rc_alias>

For an val_result_chain element that points to a name alias, this field contains the target value.

=item I<val_rc_rrset>

For an val_result_chain element that contains a valid (not NULL) val_rc_answer field, 
the val_rc_rrset field points to the top-most val_rrset_rec element in the val_rc_answer 
authentication chain. 

=item I<val_rc_status>

Validation status for a given RRset.  This can be one of the following:

=over 4

=item VAL_SUCCESS

Answer received and validated successfully.

=item VAL_NONEXISTENT_NAME

No name was present and a valid proof of non-
existence confirming the missing name (NSEC or
NSEC3 span) was returned. The components of
the proof were also individually validated.

=item VAL_NONEXISTENT_TYPE

No type exists for the name and a valid proof
of non-existence confirming the missing name
was returned.  The components of the proof
were also individually validated.

=item VAL_NONEXISTENT_NAME_NOCHAIN

No name was present and a valid proof of non-
existence confirming the missing name was
returned. The components of the proof were also
identified to be trustworthy, but they were
not individually validated.

=item VAL_NONEXISTENT_TYPE_NOCHAIN

No type exists for the name and a valid proof
of non-existence confirming the missing name
(NSEC or NSEC3 span) was returned.  The
components of the proof were also identified
to be trustworthy, but they were not
individually validated.

=item VAL_PINSECURE

The record or some ancestor of the record in
the authentication chain towards the trust
anchor was known to be provably insecure.

=item VAL_PINSECURE_UNTRUSTED

The record or some ancestor of the record in the
authentication chain towards the trust anchor was
known to be provably insecure. But the provably
insecure condition was configured as untrustworthy.

=item VAL_BARE_RRSIG

No DNSSEC validation possible, query was
for an RRSIG.

=item VAL_IGNORE_VALIDATION

Local policy was configured to ignore validation
for the zone from which this data was received.

=item VAL_UNTRUSTED_ZONE

Local policy was configured to reject
any data received from the given zone.

=item VAL_OOB_ANSWER

Answer was obtained using some Out of Band 
method, such as a local configuration file.

=item VAL_BOGUS

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.

=item VAL_DNS_ERROR     

Some error was encountered during DNS processing. 

=item VAL_NOTRUST

All available components in the authentication
chain verified properly, but there was no trust
anchor available.

=back

Status values in I<val_status_t> returned by the validator can be displayed
in ASCII format using I<p_val_status()>.

=back

=back

=over 4

=item I<struct val_authentication_chain>

  struct val_authentication_chain
  {
      val_astatus_t                    val_ac_status;
      struct val_rrset_rec                *val_ac_rrset;
      struct val_authentication_chain *val_ac_trust;
  };

=over 4

=item I<val_ac_status>

Validation state of the authentication chain element.  This field will
contain the status code for the given component in the authentication chain.
This field may contain one of the following values:

=over 4

=item VAL_AC_UNSET

The status could not be determined. 

=item VAL_AC_IGNORE_VALIDATION

Validation for the given resource record was ignored,
either because of some local policy directive or
because of some protocol-specific behavior.

=item VAL_AC_UNTRUSTED_ZONE

Local policy defined a given zone as untrusted,
with no further validation being deemed necessary.

=item VAL_AC_PINSECURE

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.

=item VAL_AC_BARE_RRSIG

The response was for a query of type RRSIG.  RRSIGs
contain the cryptographic signatures for other DNS
data and cannot themselves be validated.

=item VAL_AC_NO_LINK

There was no trust anchor configured for a given
authentication chain or the chain didn't link up.

=item VAL_AC_TRUST

At least one of the signatures covering the given
DNSKEY RRset was directly verified using a key that was
configured as a DNSSEC trust anchor.

=item VAL_AC_RRSIG_MISSING

RRSIG data could not be retrieved for a
resource record.

=item VAL_AC_DNSKEY_MISSING

The DNSKEY for an RRSIG covering a resource
record could not be retrieved.

=item VAL_AC_DS_MISSING

The DS record covering a DNSKEY record was
not available.

=item VAL_AC_DATA_MISSING

No data were returned for a query and the
DNS did not indicate an error.

=item VAL_AC_DNS_ERROR

Some error was encountered during DNS processing. 

=item VAL_AC_NOT_VERIFIED

All RRSIGs covering the RRset could not
be verified.

=item VAL_AC_VERIFIED

At least one RRSIG covering a resource
record had a status of VAL_AC_RRSIG_VERIFIED.

=back

=item I<val_ac_rrset>

Pointer to an RRset of type I<struct val_rrset_rec> obtained from the DNS response.

=item I<val_ac_trust>

Pointer to an authentication chain element that either contains a DNSKEY RRset
that can be used to verify RRSIGs over the current record, or contains a DS
RRset that can be used to build the chain-of-trust towards a trust anchor.

=back

=back

=over 4

=item I<struct val_rrset_rec>

  struct val_rrset_rec
  {
      int    val_rrset_rcode;
      char   *val_rrset_name;
      int    val_rrset_class;
      int    val_rrset_type;
      long   val_rrset_ttl;
      int    val_rrset_section;
      struct sockaddr *val_rrset_server;
      struct val_rr_rec *val_rrset_data;
      struct val_rr_rec *val_rrset_sig;
  };

=over 4

=item I<val_rrset_rcode>

The rcode on the response header for this rrset.

=item I<val_rrset_name>

Owner name of the RRset. 

=item I<val_rrset_class>

Class of the RRset.

=item I<val_val_rrset_type>

Type of the RRset.

=item I<val_rrset_ttl>

TTL of the RRset.

=item I<val_rrset_section>

Section in which the RRset was received.  This value may be B<VAL_FROM_ANSWER>,
B<VAL_FROM_AUTHORITY>, or B<VAL_FROM_ADDITIONAL>.

=item I<val_rrset_server>

The name server that returned this reponse.

=item I<val_rrset_data>

Response RDATA.

=item I<val_rrset_sig>

Any associated RRSIGs for the RDATA returned in I<val_rrset_data>.

=back

=back

=over 4

=item I<struct val_rr_rec>

  struct val_rr_rec
  {
      size_t            rr_rdata_length;
      unsigned char     *rr_rdata;
      struct val_rr_rec *rr_next;
      val_astatus_t     rr_status;
  };

=over 4

=item I<rr_rdata_length_h>

Length of data stored in I<rr_rdata>.

=item I<rr_rdata>

RDATA bytes.

=item I<rr_status>

For each signature I<val_rr_rec> member within the authentication chain
I<val_ac_rrset>, the validation status stored in the variable
I<rr_status> can return one of the following values:

    VAL_AC_RRSIG_VERIFIED
	The RRSIG verified successfully.

    VAL_AC_WCARD_VERIFIED
	A given RRSIG covering a resource record shows
	that the record was wildcard expanded.

    VAL_AC_RRSIG_VERIFIED_SKEW
	The RRSIG verified successfully after clock
	skew was taken into account.

    VAL_AC_WCARD_VERIFIED_SKEW
	A given RRSIG covering a resource record shows that
	the record was wildcard expanded, but it was verified
	only after clock skew was taken into account.

    VAL_AC_WRONG_LABEL_COUNT
	The number of labels on the signature was greater
	than the count given in the RRSIG RDATA.

    VAL_AC_INVALID_RRSIG
	The RRSIG could not be parsed.

    VAL_AC_RRSIG_NOTYETACTIVE
	The RRSIG's inception time is in the future.

    VAL_AC_RRSIG_EXPIRED
	The RRSIG had expired.

    VAL_AC_ALGORITHM_NOT_SUPPORTED
	The RRSIG algorithm was not supported.

    VAL_AC_RRSIG_VERIFY_FAILED
	A given RRSIG covering an RRset was bogus.

    VAL_AC_RRSIG_ALGORITHM_MISMATCH
	The keytag referenced in the RRSIG matched a
	DNSKEY but the algorithms were different.

    VAL_AC_DNSKEY_NOMATCH
	An RRSIG was created by a DNSKEY that did not
	exist in the apex keyset.

For each I<val_rr_rec> member of type DNSKEY (or DS, where relevant) within the
authentication chain I<val_ac_rrset>, the validation status is stored in the
variable I<rr_status> and can return one of the following values:

    VAL_AC_TRUST_POINT
    The given DNSKEY or a DS record was configured 
    as a DNSSEC trust anchor.

    VAL_AC_SIGNING_KEY
	This DNSKEY was used to create an RRSIG for
	the resource record set.

    VAL_AC_VERIFIED_LINK
	This DNSKEY provided the link in the authentication
	chain from the trust anchor to the signed record.

    VAL_AC_UNKNOWN_ALGORITHM_LINK
	This DNSKEY provided the link in the authentication
	chain from the trust anchor to the signed record,
	but the DNSKEY algorithm was unknown.

    VAL_AC_UNKNOWN_DNSKEY_PROTOCOL
	The DNSKEY protocol number was unrecognized.

    VAL_AC_ALGORITHM_NOT_SUPPORTED
	The DNSKEY or DS algorithm was not supported.
    
    VAL_AC_DS_NOMATCH
	An RRSIG was created with a key that did not
	exist in the parent DS record set.

    VAL_AC_INVALID_KEY
	The key used to verify the RRSIG was not a valid
	DNSKEY.

    VAL_AC_INVALID_DS
	The DS used to validatate the DNSKEY could not be
    parsed 
=back

=item I<rr_next>

Points to the next resource record in the RRset.

=back

=back

=head1 LOGGING 

libval provides the val_log_add_optarg() function for controlling the 
verbosity and location of log message output.

The val_log_add_optarg() function takes two arguments: the first argument
args is a character string value that specifies the location and verbosity,
the second argument, use_stderr, if set to a value greater than 0 allows 
libval to send log messages to stderr.

The character string that specifies log target location and verbosity has 
a specific format:

    <debug-level>:<dest-type>[:<dest-options>]

where 
    <debug-level> is 1-7, for increasing levels of verbosity
    <dest-type> is one of file, net, syslog, stderr, stdout
    <dest-options> depends on <dest-type>
        file:<file-name>   (opened in append mode)
        net[:<host-name>:<host-port>] (127.0.0.1:1053)
        syslog[:facility] (0-23 (default 1 USER))

The log levels can be roughly translated into different types of log messages 
as follows (the messages returned for each level in this list subsumes the 
messages returned for the level above it):

    3 : Error : errror encountered
    4 : Warning : recovering from error
    5 : Notice : gives final validation results for a query 
                 and details on policy files and labels used 
    6 : Info : gives details on authentication chains 
    7 : Debug : gives debug level information
    
=head1 RETURN VALUES

Return values for various functions are given below. These values can be
displayed in ASCII format using the I<p_val_error()> function.

=over 4

=item VAL_NO_ERROR

No error was encountered.

=item VAL_NOT_IMPLEMENTED

Functionality not yet implemented.

=item VAL_RESOURCE_UNAVAILABLE

Some resource (crypto possibly) was unavailable.  Currently not implemented.

=item VAL_BAD_ARGUMENT

Bad arguments passed as parameters.

=item VAL_INTERNAL_ERROR

Encountered some internal error.

=item VAL_NO_PERMISSION

No permission to perform operation.  Currently not implemented.

=item VAL_CONF_PARSE_ERROR

Error in parsing some configuration file.

=item VAL_CONF_NOT_FOUND

A configuration file was not available.

=item VAL_NO_POLICY

The policy identifier being referenced was invalid.

=back

=head1 FILES

The validator library reads configuration information from two files,
B<resolv.conf> and B<dnsval.conf>.

See B<dnsval.conf(5)> for a description of syntax for these files.

=head1 COPYRIGHT

Copyright 2004-2013 SPARTA, Inc.  All rights reserved.
See the COPYING file included with the dnssec-tools package for details.

=head1 AUTHORS

Suresh Krishnaswamy, Robert Story

=head1 SEE ALSO

I<libsres(3)>

B<dnsval.conf(5)>

http://www.dnssec-tools.org

=cut	
