@@ -403,11 +403,11 @@ func validateRootDNSKEY(dnskeyRRset *RRSet, rootKeys *RRSet) error {
403
403
func denialNSEC (nsec []dns.RR , qname string , qtype uint16 ) error {
404
404
for _ , rr := range nsec {
405
405
n := rr .(* dns.NSEC )
406
- c1 := dns . CompareDomainName (qname , n .Header ().Name )
406
+ c1 , _ := canonicalNameCompare (qname , n .Header ().Name )
407
407
if c1 < 0 {
408
408
continue
409
409
}
410
- c2 := dns . CompareDomainName (qname , n .NextDomain )
410
+ c2 , _ := canonicalNameCompare (qname , n .NextDomain )
411
411
412
412
if c1 >= 0 && c2 < 0 {
413
413
Log .Debug ("NSEC record covers non-existent domain" , slog .String ("qname" , qname ), slog .String ("record" , n .String ()))
@@ -482,6 +482,43 @@ func denialNSEC3(nsec3 []dns.RR, qname string, qtype uint16, rcode string) error
482
482
return nil
483
483
}
484
484
485
+ // canonicalNameCompare optimizes DNS name comparison according to RFC 4034.
486
+ func canonicalNameCompare (name1 string , name2 string ) (int , error ) {
487
+ if _ , ok := dns .IsDomainName (dns .Fqdn (name1 )); ! ok {
488
+ return 0 , errors .New ("invalid domain name" )
489
+ }
490
+ if _ , ok := dns .IsDomainName (dns .Fqdn (name2 )); ! ok {
491
+ return 0 , errors .New ("invalid domain name" )
492
+ }
493
+
494
+ labels1 := dns .SplitDomainName (dns .Fqdn (name1 ))
495
+ labels2 := dns .SplitDomainName (dns .Fqdn (name2 ))
496
+
497
+ len1 := len (labels1 )
498
+ len2 := len (labels2 )
499
+ minLen := len1
500
+ if len2 < minLen {
501
+ minLen = len2
502
+ }
503
+
504
+ for i := 1 ; i <= minLen ; i ++ {
505
+ label1 := labels1 [len1 - i ]
506
+ label2 := labels2 [len2 - i ]
507
+ res := strings .Compare (strings .ToLower (label1 ), strings .ToLower (label2 ))
508
+ if res != 0 {
509
+ return res , nil
510
+ }
511
+ }
512
+
513
+ if len1 == len2 {
514
+ return 0 , nil
515
+ } else if len1 < len2 {
516
+ return - 1 , nil
517
+ } else {
518
+ return 1 , nil
519
+ }
520
+ }
521
+
485
522
type TrustAnchor struct {
486
523
Zone string `xml:"Zone"`
487
524
KeyDigest []KeyDigest `xml:"KeyDigest"`
0 commit comments