33// Copyright (c) 2013-2021 Ingo Bauersachs
44package org .xbill .DNS .dnssec ;
55
6+ import static org .xbill .DNS .ExtendedErrorCodeOption .DNSSEC_BOGUS ;
7+ import static org .xbill .DNS .ExtendedErrorCodeOption .NSEC_MISSING ;
8+
69import java .security .NoSuchAlgorithmException ;
710import java .security .interfaces .DSAPublicKey ;
811import java .security .interfaces .ECPublicKey ;
1720import org .xbill .DNS .DNSKEYRecord ;
1821import org .xbill .DNS .DNSSEC .Algorithm ;
1922import org .xbill .DNS .DNSSEC .DNSSECException ;
23+ import org .xbill .DNS .ExtendedErrorCodeOption ;
2024import org .xbill .DNS .NSEC3Record ;
2125import org .xbill .DNS .NSEC3Record .Flags ;
2226import org .xbill .DNS .Name ;
@@ -492,38 +496,43 @@ public SecurityStatus proveNameError(List<SRRset> nsec3s, Name qname, Name zonen
492496 * @return {@link SecurityStatus#SECURE} if the NSEC3s prove the proposition, {@link
493497 * SecurityStatus#INSECURE} if qname is under opt-out, {@link SecurityStatus#BOGUS} otherwise.
494498 */
495- public SecurityStatus proveNodata (List <SRRset > nsec3s , Name qname , int qtype , Name zonename ) {
499+ public JustifiedSecStatus proveNodata (List <SRRset > nsec3s , Name qname , int qtype , Name zonename ) {
496500 if (nsec3s == null || nsec3s .isEmpty ()) {
497- return SecurityStatus .BOGUS ;
501+ return new JustifiedSecStatus (
502+ SecurityStatus .BOGUS , ExtendedErrorCodeOption .NSEC_MISSING , R .get ("failed.nsec3.none" ));
498503 }
499504
500505 NSEC3Record nsec3 = this .findMatchingNSEC3 (qname , zonename , nsec3s );
501506 // Cases 1 & 2.
502507 if (nsec3 != null ) {
503508 if (nsec3 .hasType (qtype )) {
504509 log .debug ("proveNodata: Matching NSEC3 proved that type existed!" );
505- return SecurityStatus .BOGUS ;
510+ return new JustifiedSecStatus (
511+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.type_exists" ));
506512 }
507513
508514 if (nsec3 .hasType (Type .CNAME )) {
509515 log .debug ("proveNodata: Matching NSEC3 proved that a CNAME existed!" );
510- return SecurityStatus .BOGUS ;
516+ return new JustifiedSecStatus (
517+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.cname_exists" ));
511518 }
512519
513520 if (qtype == Type .DS && nsec3 .hasType (Type .SOA ) && !Name .root .equals (qname )) {
514521 log .debug ("proveNodata: apex NSEC3 abused for no DS proof, bogus" );
515- return SecurityStatus .BOGUS ;
522+ return new JustifiedSecStatus (
523+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.apex_abuse" ));
516524 } else if (qtype != Type .DS && nsec3 .hasType (Type .NS ) && !nsec3 .hasType (Type .SOA )) {
517525 if (!nsec3 .hasType (Type .DS )) {
518526 log .debug ("proveNodata: matching NSEC3 is insecure delegation" );
519- return SecurityStatus .INSECURE ;
527+ return new JustifiedSecStatus ( SecurityStatus .INSECURE , - 1 , null ) ;
520528 }
521529
522530 log .debug ("proveNodata: matching NSEC3 is a delegation, bogus" );
523- return SecurityStatus .BOGUS ;
531+ return new JustifiedSecStatus (
532+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.delegation" ));
524533 }
525534
526- return SecurityStatus .SECURE ;
535+ return new JustifiedSecStatus ( SecurityStatus .SECURE , - 1 , null ) ;
527536 }
528537
529538 // For cases 3 - 5, we need the proven closest encloser, and it can't
@@ -534,11 +543,12 @@ public SecurityStatus proveNodata(List<SRRset> nsec3s, Name qname, int qtype, Na
534543 // At this point, not finding a match or a proven closest encloser is a
535544 // problem.
536545 if (ce .status == SecurityStatus .BOGUS ) {
537- log .debug ("proveNodata: did not match qname, nor found a proven closest encloser." );
538- return SecurityStatus .BOGUS ;
546+ log .debug ("proveNodata: did not match qname, nor found a proven closest encloser" );
547+ return new JustifiedSecStatus (
548+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.qname_ce" ));
539549 } else if (ce .status == SecurityStatus .INSECURE && qtype != Type .DS ) {
540- log .debug ("proveNodata: closest nsec3 is insecure delegation. " );
541- return SecurityStatus .INSECURE ;
550+ log .debug ("proveNodata: closest nsec3 is insecure delegation" );
551+ return new JustifiedSecStatus ( SecurityStatus .INSECURE , - 1 , null ) ;
542552 }
543553
544554 // Case 3: REMOVED
@@ -549,26 +559,30 @@ public SecurityStatus proveNodata(List<SRRset> nsec3s, Name qname, int qtype, Na
549559 if (nsec3 != null ) {
550560 if (nsec3 .hasType (qtype )) {
551561 log .debug ("proveNodata: matching wildcard had qtype!" );
552- return SecurityStatus .BOGUS ;
562+ return new JustifiedSecStatus (
563+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.type_exists_wc" ));
553564 } else if (nsec3 .hasType (Type .CNAME )) {
554565 log .debug ("nsec3 nodata proof: matching wildcard had a CNAME, bogus" );
555- return SecurityStatus .BOGUS ;
566+ return new JustifiedSecStatus (
567+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.cname_exists_wc" ));
556568 }
557569
558570 if (qtype == Type .DS && qname .labels () != 1 && nsec3 .hasType (Type .SOA )) {
559571 log .debug ("nsec3 nodata proof: matching wildcard for no DS proof has a SOA, bogus" );
560- return SecurityStatus .BOGUS ;
572+ return new JustifiedSecStatus (
573+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.wc_soa" ));
561574 } else if (qtype != Type .DS && nsec3 .hasType (Type .NS ) && !nsec3 .hasType (Type .SOA )) {
562575 log .debug ("nsec3 nodata proof: matching wilcard is a delegation, bogus" );
563- return SecurityStatus .BOGUS ;
576+ return new JustifiedSecStatus (
577+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.delegation_wc" ));
564578 }
565579
566580 if (ce .ncNsec3 != null && (ce .ncNsec3 .getFlags () & Flags .OPT_OUT ) == Flags .OPT_OUT ) {
567581 log .debug ("nsec3 nodata proof: matching wildcard is in optout range, insecure" );
568- return SecurityStatus .INSECURE ;
582+ return new JustifiedSecStatus ( SecurityStatus .INSECURE , - 1 , null ) ;
569583 }
570584
571- return SecurityStatus .SECURE ;
585+ return new JustifiedSecStatus ( SecurityStatus .SECURE , - 1 , null ) ;
572586 }
573587
574588 // Case 5.
@@ -577,24 +591,27 @@ public SecurityStatus proveNodata(List<SRRset> nsec3s, Name qname, int qtype, Na
577591 // insecure delegation under an optout here */
578592 if (ce .ncNsec3 == null ) {
579593 log .debug ("nsec3 nodata proof: no next closer nsec3" );
580- return SecurityStatus .BOGUS ;
594+ return new JustifiedSecStatus (
595+ SecurityStatus .BOGUS , NSEC_MISSING , R .get ("failed.nsec3.no_next" ));
581596 }
582597
583598 // We need to make sure that the covering NSEC3 is opt-out.
584599 if ((ce .ncNsec3 .getFlags () & Flags .OPT_OUT ) == 0 ) {
585600 if (qtype != Type .DS ) {
586601 log .debug (
587- "proveNodata: covering NSEC3 was not opt-out in an opt-out DS NOERROR/NODATA case." );
602+ "proveNodata: covering NSEC3 was not opt-out in an opt-out DS NOERROR/NODATA case" );
603+ return new JustifiedSecStatus (
604+ SecurityStatus .BOGUS , DNSSEC_BOGUS , R .get ("failed.nsec3.not_optout" ));
588605 } else {
589606 log .debug (
590- "proveNodata: could not find matching NSEC3, nor matching wildcard, and qtype is not DS -- no more options." );
607+ "proveNodata: could not find matching NSEC3, nor matching wildcard, and qtype is not DS -- no more options" );
608+ return new JustifiedSecStatus (
609+ SecurityStatus .BOGUS , NSEC_MISSING , R .get ("failed.nsec3.not_found" ));
591610 }
592-
593- return SecurityStatus .BOGUS ;
594611 }
595612
596613 // RFC5155 section 9.2: if nc has optout then no AD flag set
597- return SecurityStatus .INSECURE ;
614+ return new JustifiedSecStatus ( SecurityStatus .INSECURE , - 1 , null ) ;
598615 }
599616
600617 /**
0 commit comments