Class ValidatingResolver

java.lang.Object
org.xbill.DNS.dnssec.ValidatingResolver
All Implemented Interfaces:
Resolver

public final class ValidatingResolver extends Object implements Resolver
This resolver validates responses with DNSSEC.
Since:
3.5
  • Field Details

    • TRUST_ANCHOR_FILE_PROPERTY

      public static final String TRUST_ANCHOR_FILE_PROPERTY
      Property name from where the trust anchors are loaded.
      Since:
      3.6
      See Also:
    • VALIDATION_REASON_QCLASS

      public static final int VALIDATION_REASON_QCLASS
      The QCLASS being used for the injection of the reason why the validator came to the returned result.
      See Also:
    • DEFAULT_TA_BAD_KEY_TTL

      private static final long DEFAULT_TA_BAD_KEY_TTL
      This is the TTL to use when a trust anchor priming query failed to validate.
      See Also:
    • keyCache

      private final KeyCache keyCache
      This is a cache of validated, but expirable DNSKEY rrsets.
    • trustAnchors

      private final TrustAnchorStore trustAnchors
      A data structure holding all trust anchors. Trust anchors must be "primed" into the cache before being used to validate.
    • valUtils

      private final ValUtils valUtils
      The local validation utilities.
    • n3valUtils

      private final NSEC3ValUtils n3valUtils
      The local NSEC3 validation utilities.
    • headResolver

      private final Resolver headResolver
      The resolver that performs the actual DNS lookups.
    • clock

      private final Clock clock
      The clock used to validate messages.
    • isAddReasonToAdditional

      private boolean isAddReasonToAdditional
      If true, an additional record with the validation reason is added to the Section.ADDITIONAL section. The record is available at ./TXT/65280.
  • Constructor Details

    • ValidatingResolver

      public ValidatingResolver(Resolver headResolver)
      Creates a new instance of this class.
      Parameters:
      headResolver - The resolver to which queries for DS, DNSKEY and referring CNAME records are sent.
    • ValidatingResolver

      public ValidatingResolver(Resolver headResolver, Clock clock)
      Creates a new instance of this class.
      Parameters:
      headResolver - The resolver to which queries for DS, DNSKEY and referring CNAME records are sent.
      clock - the Clock to validate messages.
  • Method Details

    • init

      public void init(Properties config) throws IOException
      Initialize the module. Recognized configuration values:
      "dnsjava.dnssec.trust_anchor_file"
      A filename from where to load the trust anchors
      See links for other initialized classes and their configuration values (or the readme).
      Parameters:
      config - The configuration data for this module.
      Throws:
      IOException - When the file specified in the config does not exist or cannot be read.
      See Also:
    • loadTrustAnchors

      public void loadTrustAnchors(InputStream data) throws IOException
      Load the trust anchor file into the trust anchor store. The trust anchors are currently stored in a zone file format list of DNSKEY or DS records.
      Parameters:
      data - The trust anchor data.
      Throws:
      IOException - when the trust anchor data could not be read.
    • getTrustAnchors

      public TrustAnchorStore getTrustAnchors()
      Gets the store with the loaded trust anchors.
      Returns:
      The store with the loaded trust anchors.
      Since:
      3.6
    • removeSpuriousAuthority

      private void removeSpuriousAuthority(SMessage response)
      For messages that are not referrals, if the chase reply contains an unsigned NS record in the authority section it could have been inserted by a (BIND) forwarder that thinks the zone is insecure, and that has an NS record without signatures in cache. Remove the NS record since the reply does not hinge on that record (in the authority section), but do not remove it if it removes the last record from the answer+authority sections.
      Parameters:
      response - : the chased reply, we have a key for this contents, so we should have signatures for these rrsets and not having signatures means it will be bogus.
    • validatePositiveResponse

      private CompletionStage<Void> validatePositiveResponse(Message request, SMessage response, Nsec3ValidationState nsec3State, Executor executor)
      Given a "postive" response -- a response that contains an answer to the question, and no CNAME chain, validate this response. This generally consists of verifying the answer RRset and the authority RRsets.

      Given an "ANY" response -- a response that contains an answer to a qtype==ANY question, with answers. This consists of simply verifying all present answer/auth RRsets, with no checking that all types are present.

      NOTE: it may be possible to get parent-side delegation point records here, which won't all be signed. Right now, this routine relies on the upstream iterative resolver to not return these responses -- instead treating them as referrals.

      NOTE: RFC 4035 is silent on this issue, so this may change upon clarification.

      Parameters:
      request - The request that generated this response.
      response - The response to validate.
      nsec3State - State to keep track of NSEC3 hashes and calculation count.
      executor - The service to use for async operations.
    • validatePositiveResponseRecursive

      private CompletionStage<Boolean> validatePositiveResponseRecursive(SMessage response, Map<Name,Name> wcs, List<SRRset> nsec3s, List<SRRset> nsecs, int[] sections, AtomicInteger sectionIndex, AtomicInteger setIndex, Executor executor)
    • validateAnswerAndGetWildcards

      private CompletionStage<Boolean> validateAnswerAndGetWildcards(SMessage response, int qtype, Map<Name,Name> wcs, Executor executor)
    • validateAnswerAndGetWildcardsRecursive

      private CompletionStage<Boolean> validateAnswerAndGetWildcardsRecursive(SMessage response, int qtype, Map<Name,Name> wcs, AtomicInteger setIndex, Executor executor)
    • validateNodataResponse

      private CompletionStage<Void> validateNodataResponse(Message request, SMessage response, Nsec3ValidationState nsec3State, Executor executor)
      Validate a NOERROR/NODATA signed response -- a response that has a NOERROR Rcode but no ANSWER section RRsets. This consists of verifying the authority section rrsets and making certain that the authority section NSEC/NSEC3s proves that the qname does exist and the qtype doesn't.

      Note that by the time this method is called, the process of finding the trusted DNSKEY rrset that signs this response must already have been completed.

      Parameters:
      request - The request that generated this response.
      response - The response to validate.
      nsec3State - State to keep track of NSEC3 hashes and calculation count.
      executor - The service to use for async operations.
    • validateNodataResponseRecursive

      private CompletionStage<Void> validateNodataResponseRecursive(SMessage response, AtomicInteger setIndex, Nsec3ValidationState nsec3State, Executor executor)
    • failedFuture

      private <T> CompletionStage<T> failedFuture(Throwable e)
    • validateNameErrorResponse

      private CompletionStage<Void> validateNameErrorResponse(Message request, SMessage response, Nsec3ValidationState nsec3State, Executor executor)
      Validate a NAMEERROR signed response -- a response that has a NXDOMAIN Rcode. This consists of verifying the authority section rrsets and making certain that the authority section NSEC proves that the qname doesn't exist and the covering wildcard also doesn't exist..

      Note that by the time this method is called, the process of finding the trusted DNSKEY rrset that signs this response must already have been completed.

      Parameters:
      request - The request to be proved to not exist.
      response - The response to validate.
      nsec3State - State to keep track of NSEC3 hashes and calculation count.
      executor - The service to use for async operations.
    • validateNameErrorResponseRecursive

      private CompletionStage<Void> validateNameErrorResponseRecursive(SMessage response, AtomicInteger setIndex, Executor executor)
    • sendRequest

      private CompletionStage<SMessage> sendRequest(Message request, Executor executor)
    • prepareFindKey

      private CompletionStage<KeyEntry> prepareFindKey(SRRset rrset, Executor executor)
    • processFindKey

      private CompletionStage<Void> processFindKey(FindKeyState state, Executor executor)
      Process the FINDKEY state. Generally this just calculates the next name to query and either issues a DS or a DNSKEY query. It will check to see if the correct key has already been reached, in which case it will advance the event to the next state.
      Parameters:
      state - The state associated with the current key finding phase.
    • dsResponseToKE

      private KeyEntry dsResponseToKE(SMessage response, Message request, KeyEntry keyRrset)
      Given a DS response, the DS request, and the current key rrset, validate the DS response, returning a KeyEntry.
      Parameters:
      response - The DS response.
      request - The DS request.
      keyRrset - The current DNSKEY rrset from the forEvent state.
      Returns:
      A KeyEntry, bad if the DS response fails to validate, null if the DS response indicated an end to secure space, good if the DS validated. It returns null if the DS response indicated that the request wasn't a delegation point.
    • dsResponseToKeForNodata

      private KeyEntry dsResponseToKeForNodata(SMessage response, Message request, KeyEntry keyRrset)
      Given a DS response, the DS request, and the current key rrset, validate the DS response for the NODATA case, returning a KeyEntry.
      Parameters:
      response - The DS response.
      request - The DS request.
      keyRrset - The current DNSKEY rrset from the forEvent state.
      Returns:
      A KeyEntry, bad if the DS response fails to validate, null if the DS response indicated an end to secure space, good if the DS validated. It returns null if the DS response indicated that the request wasn't a delegation point.
    • processDSResponse

      private CompletionStage<Void> processDSResponse(Message request, SMessage response, FindKeyState state, Executor executor)
      This handles the responses to locally generated DS queries.
      Parameters:
      request - The request for which the response is processed.
      response - The response to process.
      state - The state associated with the current key finding phase.
    • processDNSKEYResponse

      private CompletionStage<Void> processDNSKEYResponse(Message request, SMessage response, FindKeyState state, Executor executor)
    • processValidate

      private CompletionStage<SMessage> processValidate(Message request, SMessage response, Executor executor)
    • processFinishedState

      private SMessage processFinishedState(Message request, SMessage response)
      Apply any final massaging to a response before returning up the pipeline. Primarily this means setting the AD bit or not and possibly stripping DNSSEC data.
    • setPort

      public void setPort(int port)
      Forwards the data to the head resolver passed at construction time.
      Specified by:
      setPort in interface Resolver
      Parameters:
      port - The IP destination port for the queries sent.
      See Also:
    • setTCP

      public void setTCP(boolean flag)
      Forwards the data to the head resolver passed at construction time.
      Specified by:
      setTCP in interface Resolver
      Parameters:
      flag - true to enable TCP, false to disable it.
      See Also:
    • setIgnoreTruncation

      public void setIgnoreTruncation(boolean flag)
      This is a no-op, truncation is never ignored.
      Specified by:
      setIgnoreTruncation in interface Resolver
      Parameters:
      flag - unused
    • setEDNS

      public void setEDNS(int version, int payloadSize, int flags, List<EDNSOption> options)
      The method is forwarded to the resolver, but always ensure that the level is 0 and the flags contains DO.
      Specified by:
      setEDNS in interface Resolver
      Parameters:
      version - The EDNS level to use. 0 indicates EDNS0.
      payloadSize - The maximum DNS packet size that this host is capable of receiving over UDP. If 0 is specified, the default (1280) is used.
      flags - EDNS extended flags to be set in the OPT record, ExtendedFlags.DO is always appended.
      options - EDNS options to be set in the OPT record, specified as a List of OPTRecord.Option elements.
      See Also:
    • setTSIGKey

      public void setTSIGKey(TSIG key)
      Forwards the data to the head resolver passed at construction time.
      Specified by:
      setTSIGKey in interface Resolver
      Parameters:
      key - The key.
      See Also:
    • getTimeout

      public Duration getTimeout()
      Description copied from interface: Resolver
      Gets the amount of time to wait for a response before giving up.
      Specified by:
      getTimeout in interface Resolver
      See Also:
    • setTimeout

      public void setTimeout(Duration duration)
      Description copied from interface: Resolver
      Sets the amount of time to wait for a response before giving up.
      Specified by:
      setTimeout in interface Resolver
      Parameters:
      duration - The amount of time to wait.
    • sendAsync

      public CompletionStage<Message> sendAsync(Message query, Executor executor)
      Asynchronously sends a message and validates the response with DNSSEC before returning it.
      Specified by:
      sendAsync in interface Resolver
      Parameters:
      query - The query to send.
      executor - The service to use for async operations.
      Returns:
      A future that completes when the query is finished.
    • applyEdeToOpt

      private void applyEdeToOpt(SMessage validated, Message m)
    • addValidationReasonTxtRecord

      private void addValidationReasonTxtRecord(Message m, String reason)
    • errorMessage

      private static SMessage errorMessage(Message request, int rcode)
      Creates a response message with the given return code.
      Parameters:
      request - The request for which the response belongs.
      rcode - The response code, @see Rcode
      Returns:
      The response message for request.