NXDOMAIN accepted despite NSEC not covering wildcard?

Please see:

  http://dnsviz.net/d/_25._tcp.mx1.marketconservative.com/WmzVYw/dnssec/

The NXDomain response contains NSEC records that cover

  _tcp.mx1.marketconservative.com

but NOT

  *.mx1.marketconservative.com

Here are the responses from the remote servers with RRSIGs trimmed:

    @ns1.psyclonecontacts.net.[52.1.81.184]
    ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 22871
    ;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 5
    ;_25._tcp.mx1.marketconservative.com. IN TLSA
    marketconservative.com. SOA ns1.psyclonecontacts.net. sysadmin.marketconservative.com. [...]
    dk._domainkey.mx1.marketconservative.com. NSEC mx2.marketconservative.com. [...]
    marketconservative.com. NSEC _dmarc.marketconservative.com. [...]
    
    @ns2.psyclonecontacts.net.[52.1.132.80]
    ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 39242
    ;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 5
    ;_25._tcp.mx1.marketconservative.com. IN TLSA
    marketconservative.com. SOA ns1.psyclonecontacts.net. sysadmin.marketconservative.com. [...]
    dk._domainkey.mx1.marketconservative.com. NSEC mx2.marketconservative.com. [...]
    marketconservative.com. NSEC _dmarc.marketconservative.com. [...]

Note that the second NSEC record excludes an (irrelevant) zone apex wildcard,
but not a wildcard below "mx1", so it looks to me like DNSViz may be correct,
in which case unbound should not accept this response. And yet unbound
returns NXDomain with the AD bit set:

  ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 51438
  ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1

  ;; QUESTION SECTION:
  ;_25._tcp.mx1.marketconservative.com. IN TLSA

  ;; AUTHORITY SECTION:
  marketconservative.com. SOA ns1.psyclonecontacts.net. sysadmin.marketconservative.com. 2017110101 36000 3600 1296000 3600
  dk._domainkey.mx1.marketconservative.com. NSEC mx2.marketconservative.com. TXT RRSIG NSEC
  marketconservative.com. NSEC _dmarc.marketconservative.com. A NS SOA MX TXT LOC RRSIG NSEC DNSKEY

And ditto with unbound-host:

  $ unbound-host -v -f /usr/local/etc/unbound/root.key -t tlsa _25._tcp.mx1.marketconservative.com
  Host _25._tcp.mx1.marketconservative.com not found: 3(NXDOMAIN). (secure)

I am using unbound 1.6.8 on FreeBSD.

Hi Viktor,

You are right. There is no proof that *.mx.marketconservative.com
doesn't exist, this answer should be DNSSEC bogus.

Unbound used both NSEC records. It proved the non existence of the
wildcard label by generating it using the marketconservative.com NSEC
record. The closest encloser determined using that record is
marketconservative.com, the proven wildcard is *.marketconservative.com.
The other NSEC was used to prove the absence of the qname.

I just committed a fix to always using the NSEC with the longest longest
closest encloser for the wildcard proof.

There was also an issue in the val_nsec_proves_no_wc() routine that
tried too many wildcard records by adding labels when the absence of
*.ce couldn't be proven. That is fixed in the same commit.

Thanks a lot for reporting this issue!

Regards,
-- Ralph