@Test public void testVerifyNsec3() { byte[] bytes = new byte[] {0x3f, (byte) 0xb1, (byte) 0xd0, (byte) 0xaa, 0x27, (byte) 0xe2, 0x5f, (byte) 0xda, 0x40, 0x75, (byte) 0x92, (byte) 0x95, 0x5a, 0x1c, 0x7f, (byte) 0x98, (byte) 0xdb, 0x5b, 0x79, (byte) 0x91}; Record<NSEC3> nsec3Record = record("7UO4LIHALHHLNGLJAFT7TBIQ6H1SL1CN.net", nsec3((byte) 1, (byte) 1, 0, new byte[0], bytes, TYPE.NS, TYPE.SOA, TYPE.RRSIG, TYPE.DNSKEY, TYPE.NSEC3PARAM)).as(NSEC3.class); DnsName zone = DnsName.from("net"); assertNull(Verifier.verifyNsec3(zone, nsec3Record, new Question("x.net", TYPE.A))); assertNotNull(Verifier.verifyNsec3(zone, nsec3Record, new Question("example.net", TYPE.A))); }
public static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q) { NSEC3 nsec3 = nsec3record.payloadData; DigestCalculator digestCalculator = algorithmMap.getNsecDigestCalculator(nsec3.hashAlgorithm); if (digestCalculator == null) { return new AlgorithmNotSupportedReason(nsec3.hashAlgorithmByte, nsec3.getType(), nsec3record); } byte[] bytes = nsec3hash(digestCalculator, nsec3, q.name, nsec3.iterations); String s = Base32.encodeToString(bytes); DnsName computedNsec3Record = DnsName.from(s + "." + zone); if (nsec3record.name.equals(computedNsec3Record)) { if (nsec3.types.contains(q.type)) { return new NSECDoesNotMatchReason(q, nsec3record); } return null; } if (nsecMatches(s, nsec3record.name.getHostpart(), Base32.encodeToString(nsec3.getNextHashed()))) { return null; } return new NSECDoesNotMatchReason(q, nsec3record); }
Verifier { public static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q) { NSEC3 nsec3 = nsec3record.payloadData; DigestCalculator digestCalculator = algorithmMap.getNsecDigestCalculator(nsec3.hashAlgorithm); if (digestCalculator == null) { return new AlgorithmNotSupportedReason(nsec3.hashAlgorithmByte, nsec3.getType(), nsec3record); } byte[] bytes = nsec3hash(digestCalculator, nsec3, q.name, nsec3.iterations); String s = Base32.encodeToString(bytes); DnsName computedNsec3Record = DnsName.from(s + "." + zone); if (nsec3record.name.equals(computedNsec3Record)) { if (nsec3.types.contains(q.type)) { return new NSECDoesNotMatchReason(q, nsec3record); } return null; } if (nsecMatches(s, nsec3record.name.getHostpart(), Base32.encodeToString(nsec3.getNextHashed()))) { return null; } return new NSECDoesNotMatchReason(q, nsec3record); } }
Verifier { public static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q) { NSEC3 nsec3 = nsec3record.payloadData; DigestCalculator digestCalculator = algorithmMap.getNsecDigestCalculator(nsec3.hashAlgorithm); if (digestCalculator == null) { return new AlgorithmNotSupportedReason(nsec3.hashAlgorithmByte, nsec3.getType(), nsec3record); } byte[] bytes = nsec3hash(digestCalculator, nsec3, q.name, nsec3.iterations); String s = Base32.encodeToString(bytes); DnsName computedNsec3Record = DnsName.from(s + "." + zone); if (nsec3record.name.equals(computedNsec3Record)) { if (nsec3.types.contains(q.type)) { return new NSECDoesNotMatchReason(q, nsec3record); } return null; } if (nsecMatches(s, nsec3record.name.getHostpart(), Base32.encodeToString(nsec3.getNextHashed()))) { return null; } return new NSECDoesNotMatchReason(q, nsec3record); }  }
Verifier { public static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q) { NSEC3 nsec3 = nsec3record.payloadData; DigestCalculator digestCalculator = algorithmMap.getNsecDigestCalculator(nsec3.hashAlgorithm); if (digestCalculator == null) { return new AlgorithmNotSupportedReason(nsec3.hashAlgorithmByte, nsec3.getType(), nsec3record); } byte[] bytes = nsec3hash(digestCalculator, nsec3, q.name, nsec3.iterations); String s = Base32.encodeToString(bytes); DnsName computedNsec3Record = DnsName.from(s + "." + zone); if (nsec3record.name.equals(computedNsec3Record)) { if (nsec3.types.contains(q.type)) { return new NSECDoesNotMatchReason(q, nsec3record); } return null; } if (nsecMatches(s, nsec3record.name.getHostpart(), Base32.encodeToString(nsec3.getNextHashed()))) { return null; } return new NSECDoesNotMatchReason(q, nsec3record); }  static DnssecUnverifiedReason verify(Record<DNSKEY> dnskeyRecord, DelegatingDnssecRR ds); static DnssecUnverifiedReason verify(List<Record<? extends Data>> records, RRSIG rrsig, DNSKEY key); static DnssecUnverifiedReason verifyNsec(Record<NSEC> nsecRecord, Question q); static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q); }
Verifier { public static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q) { NSEC3 nsec3 = nsec3record.payloadData; DigestCalculator digestCalculator = algorithmMap.getNsecDigestCalculator(nsec3.hashAlgorithm); if (digestCalculator == null) { return new AlgorithmNotSupportedReason(nsec3.hashAlgorithmByte, nsec3.getType(), nsec3record); } byte[] bytes = nsec3hash(digestCalculator, nsec3, q.name, nsec3.iterations); String s = Base32.encodeToString(bytes); DnsName computedNsec3Record = DnsName.from(s + "." + zone); if (nsec3record.name.equals(computedNsec3Record)) { if (nsec3.types.contains(q.type)) { return new NSECDoesNotMatchReason(q, nsec3record); } return null; } if (nsecMatches(s, nsec3record.name.getHostpart(), Base32.encodeToString(nsec3.getNextHashed()))) { return null; } return new NSECDoesNotMatchReason(q, nsec3record); }  static DnssecUnverifiedReason verify(Record<DNSKEY> dnskeyRecord, DelegatingDnssecRR ds); static DnssecUnverifiedReason verify(List<Record<? extends Data>> records, RRSIG rrsig, DNSKEY key); static DnssecUnverifiedReason verifyNsec(Record<NSEC> nsecRecord, Question q); static DnssecUnverifiedReason verifyNsec3(DnsName zone, Record<NSEC3> nsec3record, Question q);  }