Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18df8a8d9e | ||
|
|
a45f5d1df7 | ||
|
|
3da308c4b9 | ||
|
|
efa6dec7f7 | ||
| d3e8c4c913 | |||
| b5775a8fdf | |||
| 69d965cc0f | |||
| ca7f10bd07 | |||
| 25cc81d46a | |||
| 2a90a6ccd9 | |||
| b18a96cbfc | |||
| cc0873a336 | |||
| 4d1acb8918 |
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
build
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
jdnssec-tools*.tar.gz
|
||||||
|
docs
|
||||||
29
ChangeLog
29
ChangeLog
@@ -1,3 +1,32 @@
|
|||||||
|
2012-07-16 David Blacka <davidb@verisign.com>
|
||||||
|
|
||||||
|
* Released version 0.12.
|
||||||
|
|
||||||
|
* TypeMap: fix the fromBytes() method, which was incorrect and add
|
||||||
|
a static fromString() method.
|
||||||
|
* ProtoNSEC3: use TypeMap's toString method, rather than fetching
|
||||||
|
the array of types and rendering them directly.
|
||||||
|
|
||||||
|
2012-05-29 David Blacka <davidb@verisign.com>
|
||||||
|
|
||||||
|
* Released version 0.11.
|
||||||
|
|
||||||
|
2012-05-26 David Blacka <davidb@verisign.com>
|
||||||
|
|
||||||
|
* Update dnsjava to dnsjava-2.1.3-vrsn-1. Update the code to
|
||||||
|
adjust for API changes in dnsjava-2.1.x. Highlights:
|
||||||
|
- no longer use DNSSEC.Failed, DNSSEC.Secure as those constants
|
||||||
|
are now gone. Instead, any methods returning those constants now
|
||||||
|
return a boolean, true for DNSSEC.Secure, false for DNSSEC.Failed
|
||||||
|
or DNSSEC.Insecure.
|
||||||
|
- No longer use KEYConverter. Instead, uses the new DNSKEYRecord
|
||||||
|
constructor.
|
||||||
|
- The NSEC3 digest type is now an int (rather than a byte)
|
||||||
|
- Algorithm references are now DNSSEC.Algorithm.<alg>
|
||||||
|
|
||||||
|
* jdnssec-verifyzone: Add duplicate RR detection (on by default)
|
||||||
|
and a command line option to disable it.
|
||||||
|
|
||||||
2011-02-14 David Blacka <davidb@verisign.com>
|
2011-02-14 David Blacka <davidb@verisign.com>
|
||||||
|
|
||||||
* Released version 0.10.1.
|
* Released version 0.10.1.
|
||||||
|
|||||||
17
README
17
README
@@ -1,6 +1,7 @@
|
|||||||
jdnssec-tools
|
jdnssec-tools
|
||||||
|
|
||||||
http://www.verisignlabs.com/jdnssec-tools/
|
http://www.verisignlabs.com/jdnssec-tools/
|
||||||
|
https://github.com/dblacka/jdnssec-tools/wiki
|
||||||
|
|
||||||
Author: David Blacka (davidb@verisign.com)
|
Author: David Blacka (davidb@verisign.com)
|
||||||
|
|
||||||
@@ -12,8 +13,8 @@ These tools depend upon DNSjava (http://www.xbill.org/dnsjava), the
|
|||||||
Jakarta Commons CLI and Logging libraries (http://jakarta.apache.org),
|
Jakarta Commons CLI and Logging libraries (http://jakarta.apache.org),
|
||||||
and Sun's Java Cryptography extensions. A copy of each of these
|
and Sun's Java Cryptography extensions. A copy of each of these
|
||||||
libraries is included in the distribution. Currently, these tools use
|
libraries is included in the distribution. Currently, these tools use
|
||||||
a custom version of the DNSjava library (for NSEC3 support), which is
|
a custom version of the DNSjava library with minor modifications,
|
||||||
provided.
|
which is provided.
|
||||||
|
|
||||||
See the "licenses" directory for the licensing information of this
|
See the "licenses" directory for the licensing information of this
|
||||||
package and the other packages that are distributed with it.
|
package and the other packages that are distributed with it.
|
||||||
@@ -48,15 +49,15 @@ run the tools directly from the build area (without building the
|
|||||||
jdnssec-tools.jar file) by using the ./bin/_jdnssec_* wrappers.
|
jdnssec-tools.jar file) by using the ./bin/_jdnssec_* wrappers.
|
||||||
|
|
||||||
|
|
||||||
The source for this project is available in subversion, at
|
The source for this project is available in git on github:
|
||||||
http://svn.verisignlabs.com/jdnssec/tools/trunk. Source for
|
https://github.com/dblacka/jdnssec-tools
|
||||||
the modified DNSjava library can be found in subversion at
|
|
||||||
http://svn.verisignlabs.com/jdnssec/dnsjava/trunk.
|
|
||||||
|
|
||||||
---
|
Source for the modified DNSjava library can be found on github as well:
|
||||||
|
https://github.com/dblacka/jdnssec-dnsjava
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Questions or comments may be directed to the author
|
Questions or comments may be directed to the author
|
||||||
(mailto:davidb@verisign.com) or sent to the
|
(mailto:davidb@verisign.com) or sent to the
|
||||||
dnssec@verisignlabs.com mailing list
|
dnssec@verisignlabs.com mailing list
|
||||||
(https://lists.verisignlabs.com/mailman/listinfo/dnssec).
|
(https://lists.verisignlabs.com/mailman/listinfo/dnssec).
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -28,7 +28,6 @@ import java.util.List;
|
|||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.OptionBuilder;
|
import org.apache.commons.cli.OptionBuilder;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.xbill.DNS.DNSSEC;
|
|
||||||
import org.xbill.DNS.Name;
|
import org.xbill.DNS.Name;
|
||||||
import org.xbill.DNS.RRSIGRecord;
|
import org.xbill.DNS.RRSIGRecord;
|
||||||
import org.xbill.DNS.RRset;
|
import org.xbill.DNS.RRset;
|
||||||
@@ -186,11 +185,11 @@ public class SignKeyset extends CLBase
|
|||||||
// skip unsigned rrsets.
|
// skip unsigned rrsets.
|
||||||
if (!rrset.sigs().hasNext()) continue;
|
if (!rrset.sigs().hasNext()) continue;
|
||||||
|
|
||||||
int result = verifier.verify(rrset, null);
|
boolean result = verifier.verify(rrset);
|
||||||
|
|
||||||
if (result != DNSSEC.Secure)
|
if (!result)
|
||||||
{
|
{
|
||||||
log.fine("Signatures did not verify for RRset: (" + result + "): " + rrset);
|
log.fine("Signatures did not verify for RRset: " + rrset);
|
||||||
secure = false;
|
secure = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import org.apache.commons.cli.CommandLine;
|
|||||||
import org.apache.commons.cli.OptionBuilder;
|
import org.apache.commons.cli.OptionBuilder;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
|
|
||||||
import org.xbill.DNS.DNSSEC;
|
|
||||||
import org.xbill.DNS.Name;
|
import org.xbill.DNS.Name;
|
||||||
import org.xbill.DNS.RRSIGRecord;
|
import org.xbill.DNS.RRSIGRecord;
|
||||||
import org.xbill.DNS.RRset;
|
import org.xbill.DNS.RRset;
|
||||||
@@ -185,11 +184,11 @@ public class SignRRset extends CLBase
|
|||||||
// skip unsigned rrsets.
|
// skip unsigned rrsets.
|
||||||
if (!rrset.sigs().hasNext()) continue;
|
if (!rrset.sigs().hasNext()) continue;
|
||||||
|
|
||||||
int result = verifier.verify(rrset, null);
|
boolean result = verifier.verify(rrset);
|
||||||
|
|
||||||
if (result != DNSSEC.Secure)
|
if (!result)
|
||||||
{
|
{
|
||||||
log.fine("Signatures did not verify for RRset: (" + result + "): " + rrset);
|
log.fine("Signatures did not verify for RRset: " + rrset);
|
||||||
secure = false;
|
secure = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import org.apache.commons.cli.Options;
|
|||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
|
|
||||||
import org.xbill.DNS.DNSKEYRecord;
|
import org.xbill.DNS.DNSKEYRecord;
|
||||||
import org.xbill.DNS.DNSSEC;
|
|
||||||
import org.xbill.DNS.DSRecord;
|
import org.xbill.DNS.DSRecord;
|
||||||
import org.xbill.DNS.Name;
|
import org.xbill.DNS.Name;
|
||||||
import org.xbill.DNS.RRset;
|
import org.xbill.DNS.RRset;
|
||||||
@@ -343,11 +342,11 @@ public class SignZone extends CLBase
|
|||||||
// skip unsigned rrsets.
|
// skip unsigned rrsets.
|
||||||
if (!rrset.sigs().hasNext()) continue;
|
if (!rrset.sigs().hasNext()) continue;
|
||||||
|
|
||||||
int result = verifier.verify(rrset, null);
|
boolean result = verifier.verify(rrset);
|
||||||
|
|
||||||
if (result != DNSSEC.Secure)
|
if (!result)
|
||||||
{
|
{
|
||||||
log.fine("Signatures did not verify for RRset: (" + result + "): " + rrset);
|
log.fine("Signatures did not verify for RRset: " + rrset);
|
||||||
secure = false;
|
secure = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public class VerifyZone extends CLBase
|
|||||||
public int startfudge = 0;
|
public int startfudge = 0;
|
||||||
public int expirefudge = 0;
|
public int expirefudge = 0;
|
||||||
public boolean ignoreTime = false;
|
public boolean ignoreTime = false;
|
||||||
|
public boolean ignoreDups = false;
|
||||||
|
|
||||||
public CLIState()
|
public CLIState()
|
||||||
{
|
{
|
||||||
@@ -71,6 +72,10 @@ public class VerifyZone extends CLBase
|
|||||||
OptionBuilder.withLongOpt("ignore-time");
|
OptionBuilder.withLongOpt("ignore-time");
|
||||||
OptionBuilder.withDescription("Ignore RRSIG inception and expiration time errors.");
|
OptionBuilder.withDescription("Ignore RRSIG inception and expiration time errors.");
|
||||||
opts.addOption(OptionBuilder.create());
|
opts.addOption(OptionBuilder.create());
|
||||||
|
|
||||||
|
OptionBuilder.withLongOpt("ignore-duplicate-rrs");
|
||||||
|
OptionBuilder.withDescription("Ignore duplicate record errors.");
|
||||||
|
opts.addOption(OptionBuilder.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processOptions(CommandLine cli)
|
protected void processOptions(CommandLine cli)
|
||||||
@@ -80,6 +85,11 @@ public class VerifyZone extends CLBase
|
|||||||
ignoreTime = true;
|
ignoreTime = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cli.hasOption("ignore-duplicate-rrs"))
|
||||||
|
{
|
||||||
|
ignoreDups = true;
|
||||||
|
}
|
||||||
|
|
||||||
String optstr = null;
|
String optstr = null;
|
||||||
if ((optstr = cli.getOptionValue('S')) != null)
|
if ((optstr = cli.getOptionValue('S')) != null)
|
||||||
{
|
{
|
||||||
@@ -126,6 +136,7 @@ public class VerifyZone extends CLBase
|
|||||||
zoneverifier.getVerifier().setStartFudge(state.startfudge);
|
zoneverifier.getVerifier().setStartFudge(state.startfudge);
|
||||||
zoneverifier.getVerifier().setExpireFudge(state.expirefudge);
|
zoneverifier.getVerifier().setExpireFudge(state.expirefudge);
|
||||||
zoneverifier.getVerifier().setIgnoreTime(state.ignoreTime);
|
zoneverifier.getVerifier().setIgnoreTime(state.ignoreTime);
|
||||||
|
zoneverifier.setIgnoreDuplicateRRs(state.ignoreDups);
|
||||||
|
|
||||||
List<Record> records = ZoneUtils.readZoneFile(state.zonefile, null);
|
List<Record> records = ZoneUtils.readZoneFile(state.zonefile, null);
|
||||||
|
|
||||||
|
|||||||
@@ -105,25 +105,25 @@ public class DnsKeyAlgorithm
|
|||||||
mIdToMnemonicMap = new HashMap<Integer, String>();
|
mIdToMnemonicMap = new HashMap<Integer, String>();
|
||||||
|
|
||||||
// Load the standard DNSSEC algorithms.
|
// Load the standard DNSSEC algorithms.
|
||||||
addAlgorithm(DNSSEC.RSAMD5, new Entry("MD5withRSA", RSA));
|
addAlgorithm(DNSSEC.Algorithm.RSAMD5, new Entry("MD5withRSA", RSA));
|
||||||
addMnemonic("RSAMD5", DNSSEC.RSAMD5);
|
addMnemonic("RSAMD5", DNSSEC.Algorithm.RSAMD5);
|
||||||
|
|
||||||
addAlgorithm(DNSSEC.DH, new Entry("", DH));
|
addAlgorithm(DNSSEC.Algorithm.DH, new Entry("", DH));
|
||||||
addMnemonic("DH", DNSSEC.DH);
|
addMnemonic("DH", DNSSEC.Algorithm.DH);
|
||||||
|
|
||||||
addAlgorithm(DNSSEC.DSA, new Entry("SHA1withDSA", DSA));
|
addAlgorithm(DNSSEC.Algorithm.DSA, new Entry("SHA1withDSA", DSA));
|
||||||
addMnemonic("DSA", DNSSEC.DSA);
|
addMnemonic("DSA", DNSSEC.Algorithm.DSA);
|
||||||
|
|
||||||
addAlgorithm(DNSSEC.RSASHA1, new Entry("SHA1withRSA", RSA));
|
addAlgorithm(DNSSEC.Algorithm.RSASHA1, new Entry("SHA1withRSA", RSA));
|
||||||
addMnemonic("RSASHA1", DNSSEC.RSASHA1);
|
addMnemonic("RSASHA1", DNSSEC.Algorithm.RSASHA1);
|
||||||
addMnemonic("RSA", DNSSEC.RSASHA1);
|
addMnemonic("RSA", DNSSEC.Algorithm.RSASHA1);
|
||||||
|
|
||||||
// Load the (now) standard aliases
|
// Load the (now) standard aliases
|
||||||
addAlias(DNSSEC.DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1", DNSSEC.DSA);
|
addAlias(DNSSEC.Algorithm.DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1", DNSSEC.Algorithm.DSA);
|
||||||
addAlias(DNSSEC.RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1", DNSSEC.RSASHA1);
|
addAlias(DNSSEC.Algorithm.RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1", DNSSEC.Algorithm.RSASHA1);
|
||||||
// Also recognize the BIND 9.6 mnemonics
|
// Also recognize the BIND 9.6 mnemonics
|
||||||
addMnemonic("NSEC3DSA", DNSSEC.DSA_NSEC3_SHA1);
|
addMnemonic("NSEC3DSA", DNSSEC.Algorithm.DSA_NSEC3_SHA1);
|
||||||
addMnemonic("NSEC3RSASHA1", DNSSEC.RSA_NSEC3_SHA1);
|
addMnemonic("NSEC3RSASHA1", DNSSEC.Algorithm.RSA_NSEC3_SHA1);
|
||||||
|
|
||||||
// Algorithms added by RFC 5702.
|
// Algorithms added by RFC 5702.
|
||||||
// NOTE: these algorithms aren't available in Java 1.4's sunprovider
|
// NOTE: these algorithms aren't available in Java 1.4's sunprovider
|
||||||
@@ -221,11 +221,11 @@ public class DnsKeyAlgorithm
|
|||||||
switch (baseType(algorithm))
|
switch (baseType(algorithm))
|
||||||
{
|
{
|
||||||
case RSA:
|
case RSA:
|
||||||
return DNSSEC.RSASHA1;
|
return DNSSEC.Algorithm.RSASHA1;
|
||||||
case DSA:
|
case DSA:
|
||||||
return DNSSEC.DSA;
|
return DNSSEC.Algorithm.DSA;
|
||||||
case DH:
|
case DH:
|
||||||
return DNSSEC.DH;
|
return DNSSEC.Algorithm.DH;
|
||||||
default:
|
default:
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,8 @@ import javax.crypto.spec.DHParameterSpec;
|
|||||||
import javax.crypto.spec.DHPrivateKeySpec;
|
import javax.crypto.spec.DHPrivateKeySpec;
|
||||||
|
|
||||||
import org.xbill.DNS.DNSKEYRecord;
|
import org.xbill.DNS.DNSKEYRecord;
|
||||||
|
import org.xbill.DNS.DNSSEC.DNSSECException;
|
||||||
import org.xbill.DNS.Name;
|
import org.xbill.DNS.Name;
|
||||||
import org.xbill.DNS.Record;
|
|
||||||
import org.xbill.DNS.Type;
|
|
||||||
import org.xbill.DNS.security.KEYConverter;
|
|
||||||
import org.xbill.DNS.utils.base64;
|
import org.xbill.DNS.utils.base64;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +96,14 @@ public class DnsKeyConverter
|
|||||||
pKeyRecord.getKey());
|
pKeyRecord.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
return KEYConverter.parseRecord(pKeyRecord);
|
try
|
||||||
|
{
|
||||||
|
return pKeyRecord.getPublicKey();
|
||||||
|
}
|
||||||
|
catch (DNSSECException e)
|
||||||
|
{
|
||||||
|
throw new NoSuchAlgorithmException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,10 +112,16 @@ public class DnsKeyConverter
|
|||||||
public DNSKEYRecord generateDNSKEYRecord(Name name, int dclass, long ttl,
|
public DNSKEYRecord generateDNSKEYRecord(Name name, int dclass, long ttl,
|
||||||
int flags, int alg, PublicKey key)
|
int flags, int alg, PublicKey key)
|
||||||
{
|
{
|
||||||
Record kr = KEYConverter.buildRecord(name, Type.DNSKEY, dclass, ttl, flags,
|
try
|
||||||
DNSKEYRecord.Protocol.DNSSEC, alg, key);
|
{
|
||||||
|
return new DNSKEYRecord(name, dclass, ttl, flags, DNSKEYRecord.Protocol.DNSSEC, alg,
|
||||||
return (DNSKEYRecord) kr;
|
key);
|
||||||
|
}
|
||||||
|
catch (DNSSECException e)
|
||||||
|
{
|
||||||
|
// FIXME: this mimics the behavior of KEYConverter.buildRecord(), which would return null if the algorithm was unknown.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private Key Specific Parsing routines
|
// Private Key Specific Parsing routines
|
||||||
|
|||||||
@@ -333,15 +333,15 @@ public class DnsKeyPair
|
|||||||
if (pk != null)
|
if (pk != null)
|
||||||
{
|
{
|
||||||
// currently, alg 5 is the default over alg 1 (RSASHA1).
|
// currently, alg 5 is the default over alg 1 (RSASHA1).
|
||||||
if (pk instanceof RSAPublicKey) return DNSSEC.RSASHA1;
|
if (pk instanceof RSAPublicKey) return DNSSEC.Algorithm.RSASHA1;
|
||||||
if (pk instanceof DSAPublicKey) return DNSSEC.DSA;
|
if (pk instanceof DSAPublicKey) return DNSSEC.Algorithm.DSA;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivateKey priv = getPrivate();
|
PrivateKey priv = getPrivate();
|
||||||
if (priv != null)
|
if (priv != null)
|
||||||
{
|
{
|
||||||
if (priv instanceof RSAPrivateKey) return DNSSEC.RSASHA1;
|
if (priv instanceof RSAPrivateKey) return DNSSEC.Algorithm.RSASHA1;
|
||||||
if (priv instanceof DSAPrivateKey) return DNSSEC.DSA;
|
if (priv instanceof DSAPrivateKey) return DNSSEC.Algorithm.DSA;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import org.xbill.DNS.*;
|
|||||||
* @author $Author$
|
* @author $Author$
|
||||||
* @version $Revision$
|
* @version $Revision$
|
||||||
*/
|
*/
|
||||||
public class DnsSecVerifier implements Verifier
|
public class DnsSecVerifier
|
||||||
{
|
{
|
||||||
|
|
||||||
private class TrustedKeyStore
|
private class TrustedKeyStore
|
||||||
@@ -157,47 +157,19 @@ public class DnsSecVerifier implements Verifier
|
|||||||
mIgnoreTime = v;
|
mIgnoreTime = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private DnsKeyPair findKey(Name name, int algorithm, int footprint)
|
||||||
private DnsKeyPair findCachedKey(Cache cache, Name name, int algorithm, int footprint)
|
|
||||||
{
|
{
|
||||||
RRset[] keysets = cache.findAnyRecords(name, Type.KEY);
|
return mKeyStore.find(name, algorithm, footprint);
|
||||||
if (keysets == null) return null;
|
|
||||||
|
|
||||||
// look for the particular key
|
|
||||||
// FIXME: this assumes that name+alg+footprint is unique.
|
|
||||||
for (Iterator<Record> i = keysets[0].rrs(); i.hasNext();)
|
|
||||||
{
|
|
||||||
Record r = i.next();
|
|
||||||
if (r.getType() != Type.DNSKEY) continue;
|
|
||||||
DNSKEYRecord keyrec = (DNSKEYRecord) r;
|
|
||||||
if (keyrec.getAlgorithm() == algorithm && keyrec.getFootprint() == footprint)
|
|
||||||
{
|
|
||||||
return new DnsKeyPair(keyrec, (PrivateKey) null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DnsKeyPair findKey(Cache cache, Name name, int algorithm, int footprint)
|
private boolean validateSignature(RRset rrset, RRSIGRecord sigrec, List<String> reasons)
|
||||||
{
|
{
|
||||||
DnsKeyPair pair = mKeyStore.find(name, algorithm, footprint);
|
if (rrset == null || sigrec == null) return false;
|
||||||
if (pair == null && cache != null)
|
|
||||||
{
|
|
||||||
pair = findCachedKey(cache, name, algorithm, footprint);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte validateSignature(RRset rrset, RRSIGRecord sigrec, List<String> reasons)
|
|
||||||
{
|
|
||||||
if (rrset == null || sigrec == null) return DNSSEC.Failed;
|
|
||||||
if (!rrset.getName().equals(sigrec.getName()))
|
if (!rrset.getName().equals(sigrec.getName()))
|
||||||
{
|
{
|
||||||
log.fine("Signature name does not match RRset name");
|
log.fine("Signature name does not match RRset name");
|
||||||
if (reasons != null) reasons.add("Signature name does not match RRset name");
|
if (reasons != null) reasons.add("Signature name does not match RRset name");
|
||||||
return DNSSEC.Failed;
|
return false;
|
||||||
}
|
}
|
||||||
if (rrset.getType() != sigrec.getTypeCovered())
|
if (rrset.getType() != sigrec.getTypeCovered())
|
||||||
{
|
{
|
||||||
@@ -205,7 +177,7 @@ public class DnsSecVerifier implements Verifier
|
|||||||
if (reasons != null) reasons.add("Signature type does not match RRset type");
|
if (reasons != null) reasons.add("Signature type does not match RRset type");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIgnoreTime) return DNSSEC.Secure;
|
if (mIgnoreTime) return true;
|
||||||
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date start = sigrec.getTimeSigned();
|
Date start = sigrec.getTimeSigned();
|
||||||
@@ -221,7 +193,7 @@ public class DnsSecVerifier implements Verifier
|
|||||||
{
|
{
|
||||||
log.fine("Signature is not yet valid");
|
log.fine("Signature is not yet valid");
|
||||||
if (reasons != null) reasons.add("Signature not yet valid");
|
if (reasons != null) reasons.add("Signature not yet valid");
|
||||||
return DNSSEC.Failed;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,39 +207,37 @@ public class DnsSecVerifier implements Verifier
|
|||||||
{
|
{
|
||||||
log.fine("Signature has expired (now = " + now + ", sig expires = " + expire);
|
log.fine("Signature has expired (now = " + now + ", sig expires = " + expire);
|
||||||
if (reasons != null) reasons.add("Signature has expired.");
|
if (reasons != null) reasons.add("Signature has expired.");
|
||||||
return DNSSEC.Failed;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DNSSEC.Secure;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte verifySignature(RRset rrset, RRSIGRecord sigrec, Cache cache)
|
public boolean verifySignature(RRset rrset, RRSIGRecord sigrec)
|
||||||
{
|
{
|
||||||
return verifySignature(rrset, sigrec, cache, null);
|
return verifySignature(rrset, sigrec, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify an RRset against a particular signature.
|
* Verify an RRset against a particular signature.
|
||||||
*
|
*
|
||||||
* @return DNSSEC.Secure if the signature verified, DNSSEC.Failed if it did
|
* @return true if the signature verified, false if it did
|
||||||
* not verify (for any reason), and DNSSEC.Insecure if verification
|
* not verify (for any reason, including not finding the DNSKEY.)
|
||||||
* could not be completed (usually because the public key was not
|
|
||||||
* available).
|
|
||||||
*/
|
*/
|
||||||
public byte verifySignature(RRset rrset, RRSIGRecord sigrec, Cache cache, List<String> reasons)
|
public boolean verifySignature(RRset rrset, RRSIGRecord sigrec, List<String> reasons)
|
||||||
{
|
{
|
||||||
byte result = validateSignature(rrset, sigrec, reasons);
|
boolean result = validateSignature(rrset, sigrec, reasons);
|
||||||
if (result != DNSSEC.Secure) return result;
|
if (!result) return result;
|
||||||
|
|
||||||
DnsKeyPair keypair = findKey(cache, sigrec.getSigner(), sigrec.getAlgorithm(),
|
DnsKeyPair keypair = findKey(sigrec.getSigner(), sigrec.getAlgorithm(),
|
||||||
sigrec.getFootprint());
|
sigrec.getFootprint());
|
||||||
|
|
||||||
if (keypair == null)
|
if (keypair == null)
|
||||||
{
|
{
|
||||||
if (reasons != null) reasons.add("Could not find matching trusted key");
|
if (reasons != null) reasons.add("Could not find matching trusted key");
|
||||||
log.fine("could not find matching trusted key");
|
log.fine("could not find matching trusted key");
|
||||||
return DNSSEC.Insecure;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -290,10 +260,10 @@ public class DnsSecVerifier implements Verifier
|
|||||||
{
|
{
|
||||||
if (reasons != null) reasons.add("Signature failed to verify cryptographically");
|
if (reasons != null) reasons.add("Signature failed to verify cryptographically");
|
||||||
log.fine("Signature failed to verify cryptographically");
|
log.fine("Signature failed to verify cryptographically");
|
||||||
return DNSSEC.Failed;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DNSSEC.Secure;
|
return true;
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
@@ -305,39 +275,38 @@ public class DnsSecVerifier implements Verifier
|
|||||||
}
|
}
|
||||||
if (reasons != null) reasons.add("Signature failed to verify due to exception");
|
if (reasons != null) reasons.add("Signature failed to verify due to exception");
|
||||||
log.fine("Signature failed to verify due to exception");
|
log.fine("Signature failed to verify due to exception");
|
||||||
return DNSSEC.Insecure;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies an RRset. This routine does not modify the RRset.
|
* Verifies an RRset. This routine does not modify the RRset.
|
||||||
*
|
*
|
||||||
* @return DNSSEC.Secure if the set verified, DNSSEC.Failed if it did not, and
|
* @return true if the set verified, false if it did not.
|
||||||
* DNSSEC.Insecure if verification could not complete.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public int verify(RRset rrset, Cache cache)
|
public boolean verify(RRset rrset)
|
||||||
{
|
{
|
||||||
int result = mVerifyAllSigs ? DNSSEC.Secure : DNSSEC.Insecure;
|
boolean result = mVerifyAllSigs ? true : false;
|
||||||
|
|
||||||
Iterator i = rrset.sigs();
|
Iterator i = rrset.sigs();
|
||||||
|
|
||||||
if (!i.hasNext())
|
if (!i.hasNext())
|
||||||
{
|
{
|
||||||
log.fine("RRset failed to verify due to lack of signatures");
|
log.fine("RRset failed to verify due to lack of signatures");
|
||||||
return DNSSEC.Insecure;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i.hasNext())
|
while (i.hasNext())
|
||||||
{
|
{
|
||||||
RRSIGRecord sigrec = (RRSIGRecord) i.next();
|
RRSIGRecord sigrec = (RRSIGRecord) i.next();
|
||||||
|
|
||||||
byte res = verifySignature(rrset, sigrec, cache);
|
boolean res = verifySignature(rrset, sigrec);
|
||||||
|
|
||||||
if (!mVerifyAllSigs && res == DNSSEC.Secure) return res;
|
// If not requiring all signature to validate, then any successful validation is sufficient.
|
||||||
|
if (!mVerifyAllSigs && res) return res;
|
||||||
|
|
||||||
if (!mVerifyAllSigs && res < result) result = res;
|
// Otherwise, note if a signature failed to validate.
|
||||||
|
if (mVerifyAllSigs && !res)
|
||||||
if (mVerifyAllSigs && res != DNSSEC.Secure && res < result)
|
|
||||||
{
|
{
|
||||||
result = res;
|
result = res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ import org.xbill.DNS.utils.base32;
|
|||||||
public class ProtoNSEC3
|
public class ProtoNSEC3
|
||||||
{
|
{
|
||||||
private Name originalOwner;
|
private Name originalOwner;
|
||||||
private byte hashAlg;
|
private int hashAlg;
|
||||||
private byte flags;
|
private byte flags;
|
||||||
private int iterations;
|
private int iterations;
|
||||||
private byte[] salt;
|
private byte[] salt;
|
||||||
@@ -63,7 +63,7 @@ public class ProtoNSEC3
|
|||||||
* Creates an NSEC3 Record from the given data.
|
* Creates an NSEC3 Record from the given data.
|
||||||
*/
|
*/
|
||||||
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
|
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
|
||||||
byte hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
|
int hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
|
||||||
TypeMap typemap)
|
TypeMap typemap)
|
||||||
{
|
{
|
||||||
this.zone = zone;
|
this.zone = zone;
|
||||||
@@ -80,7 +80,7 @@ public class ProtoNSEC3
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
|
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
|
||||||
byte hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
|
int hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
|
||||||
int[] types)
|
int[] types)
|
||||||
{
|
{
|
||||||
this(owner, originalOwner, zone, dclass, ttl, hashAlg, flags, iterations, salt, next,
|
this(owner, originalOwner, zone, dclass, ttl, hashAlg, flags, iterations, salt, next,
|
||||||
@@ -168,7 +168,7 @@ public class ProtoNSEC3
|
|||||||
return dclass;
|
return dclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getHashAlgorithm()
|
public int getHashAlgorithm()
|
||||||
{
|
{
|
||||||
return hashAlg;
|
return hashAlg;
|
||||||
}
|
}
|
||||||
@@ -242,14 +242,8 @@ public class ProtoNSEC3
|
|||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
String nextstr = (next == null) ? "(null)" : b32.toString(next);
|
String nextstr = (next == null) ? "(null)" : b32.toString(next);
|
||||||
sb.append(nextstr);
|
sb.append(nextstr);
|
||||||
|
sb.append(' ');
|
||||||
int[] types = getTypes();
|
sb.append(typemap.toString());
|
||||||
for (int i = 0; i < types.length; i++)
|
|
||||||
{
|
|
||||||
sb.append(" ");
|
|
||||||
sb.append(Type.string(types[i]));
|
|
||||||
}
|
|
||||||
if (originalOwner != null) sb.append(" ; " + originalOwner);
|
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1040,7 +1040,7 @@ public class SignUtils
|
|||||||
{
|
{
|
||||||
byte[] hash = nsec3hash(name, NSEC3Record.SHA1_DIGEST_ID, iterations, salt);
|
byte[] hash = nsec3hash(name, NSEC3Record.SHA1_DIGEST_ID, iterations, salt);
|
||||||
byte flags = (byte) (optIn ? 0x01 : 0x00);
|
byte flags = (byte) (optIn ? 0x01 : 0x00);
|
||||||
|
|
||||||
ProtoNSEC3 r = new ProtoNSEC3(hash, name, zonename, DClass.IN, ttl,
|
ProtoNSEC3 r = new ProtoNSEC3(hash, name, zonename, DClass.IN, ttl,
|
||||||
NSEC3Record.SHA1_DIGEST_ID, flags, iterations, salt,
|
NSEC3Record.SHA1_DIGEST_ID, flags, iterations, salt,
|
||||||
null, types);
|
null, types);
|
||||||
@@ -1430,7 +1430,7 @@ public class SignUtils
|
|||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
* If the hash algorithm is unrecognized.
|
* If the hash algorithm is unrecognized.
|
||||||
*/
|
*/
|
||||||
public static byte[] nsec3hash(Name n, byte hash_algorithm, int iterations, byte[] salt)
|
public static byte[] nsec3hash(Name n, int hash_algorithm, int iterations, byte[] salt)
|
||||||
throws NoSuchAlgorithmException
|
throws NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
MessageDigest md;
|
MessageDigest md;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.xbill.DNS.Type;
|
|||||||
public class TypeMap
|
public class TypeMap
|
||||||
{
|
{
|
||||||
private static final Integer[] integerArray = new Integer[0];
|
private static final Integer[] integerArray = new Integer[0];
|
||||||
|
private static final byte[] emptyBitmap = new byte[0];
|
||||||
|
|
||||||
private Set<Integer> typeSet;
|
private Set<Integer> typeSet;
|
||||||
|
|
||||||
@@ -47,6 +48,9 @@ public class TypeMap
|
|||||||
return typeSet.contains(type);
|
return typeSet.contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an array of DNS type code, construct a TypeMap object.
|
||||||
|
*/
|
||||||
public static TypeMap fromTypes(int[] types)
|
public static TypeMap fromTypes(int[] types)
|
||||||
{
|
{
|
||||||
TypeMap m = new TypeMap();
|
TypeMap m = new TypeMap();
|
||||||
@@ -68,12 +72,12 @@ public class TypeMap
|
|||||||
int m = 0;
|
int m = 0;
|
||||||
TypeMap typemap = new TypeMap();
|
TypeMap typemap = new TypeMap();
|
||||||
|
|
||||||
int map_number;
|
int page;
|
||||||
int byte_length;
|
int byte_length;
|
||||||
|
|
||||||
while (m < map.length)
|
while (m < map.length)
|
||||||
{
|
{
|
||||||
map_number = map[m++];
|
page = map[m++];
|
||||||
byte_length = map[m++];
|
byte_length = map[m++];
|
||||||
|
|
||||||
for (int i = 0; i < byte_length; i++)
|
for (int i = 0; i < byte_length; i++)
|
||||||
@@ -82,7 +86,7 @@ public class TypeMap
|
|||||||
{
|
{
|
||||||
if ((map[m + i] & (1 << (7 - j))) != 0)
|
if ((map[m + i] & (1 << (7 - j))) != 0)
|
||||||
{
|
{
|
||||||
typemap.set(map_number * 8 + j);
|
typemap.set((page << 8) + (i * 8) + j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,6 +96,21 @@ public class TypeMap
|
|||||||
return typemap;
|
return typemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given list of type mnemonics, construct a TypeMap object.
|
||||||
|
*/
|
||||||
|
public static TypeMap fromString(String types)
|
||||||
|
{
|
||||||
|
TypeMap typemap = new TypeMap();
|
||||||
|
|
||||||
|
for (String type : types.split("\\s+"))
|
||||||
|
{
|
||||||
|
typemap.set(Type.value(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return typemap;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return the normal string representation of the typemap. */
|
/** @return the normal string representation of the typemap. */
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
@@ -102,7 +121,7 @@ public class TypeMap
|
|||||||
|
|
||||||
for (int i = 0; i < types.length; i++)
|
for (int i = 0; i < types.length; i++)
|
||||||
{
|
{
|
||||||
sb.append(" ");
|
if (i > 0) sb.append(" ");
|
||||||
sb.append(Type.string(types[i]));
|
sb.append(Type.string(types[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +159,8 @@ public class TypeMap
|
|||||||
{
|
{
|
||||||
int[] types = getTypes();
|
int[] types = getTypes();
|
||||||
|
|
||||||
|
if (types.length == 0) return emptyBitmap;
|
||||||
|
|
||||||
Arrays.sort(types);
|
Arrays.sort(types);
|
||||||
|
|
||||||
int mapbase = -1;
|
int mapbase = -1;
|
||||||
@@ -149,7 +170,7 @@ public class TypeMap
|
|||||||
|
|
||||||
for (int i = 0; i < types.length; i++)
|
for (int i = 0; i < types.length; i++)
|
||||||
{
|
{
|
||||||
int base = types[i] >> 8;
|
int base = (types[i] >> 8) & 0xFF;
|
||||||
if (base == mapbase) continue;
|
if (base == mapbase) continue;
|
||||||
if (mapstart >= 0)
|
if (mapstart >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import java.util.TreeMap;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.xbill.DNS.DNSKEYRecord;
|
import org.xbill.DNS.DNSKEYRecord;
|
||||||
import org.xbill.DNS.DNSSEC;
|
|
||||||
import org.xbill.DNS.NSEC3PARAMRecord;
|
import org.xbill.DNS.NSEC3PARAMRecord;
|
||||||
import org.xbill.DNS.NSEC3Record;
|
import org.xbill.DNS.NSEC3Record;
|
||||||
import org.xbill.DNS.NSECRecord;
|
import org.xbill.DNS.NSECRecord;
|
||||||
@@ -49,7 +48,7 @@ import org.xbill.DNS.utils.base32;
|
|||||||
* A class for whole zone DNSSEC verification. Along with cryptographically
|
* A class for whole zone DNSSEC verification. Along with cryptographically
|
||||||
* verifying signatures, this class will also detect invalid NSEC and NSEC3
|
* verifying signatures, this class will also detect invalid NSEC and NSEC3
|
||||||
* chains.
|
* chains.
|
||||||
*
|
*
|
||||||
* @author David Blacka (original)
|
* @author David Blacka (original)
|
||||||
* @author $Author: davidb $
|
* @author $Author: davidb $
|
||||||
* @version $Revision: 172 $
|
* @version $Revision: 172 $
|
||||||
@@ -64,6 +63,7 @@ public class ZoneVerifier
|
|||||||
private Name mZoneName;
|
private Name mZoneName;
|
||||||
private DNSSECType mDNSSECType;
|
private DNSSECType mDNSSECType;
|
||||||
private NSEC3PARAMRecord mNSEC3params;
|
private NSEC3PARAMRecord mNSEC3params;
|
||||||
|
private boolean mIgnoreDuplicateRRs;
|
||||||
|
|
||||||
private DnsSecVerifier mVerifier;
|
private DnsSecVerifier mVerifier;
|
||||||
private base32 mBase32;
|
private base32 mBase32;
|
||||||
@@ -108,22 +108,48 @@ public class ZoneVerifier
|
|||||||
mVerifier = new DnsSecVerifier();
|
mVerifier = new DnsSecVerifier();
|
||||||
mBase32 = new base32(base32.Alphabet.BASE32HEX, false, true);
|
mBase32 = new base32(base32.Alphabet.BASE32HEX, false, true);
|
||||||
mBAcmp = new ByteArrayComparator();
|
mBAcmp = new ByteArrayComparator();
|
||||||
|
mIgnoreDuplicateRRs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the DnsSecVerifier object used to verify individual RRsets. */
|
||||||
public DnsSecVerifier getVerifier()
|
public DnsSecVerifier getVerifier()
|
||||||
{
|
{
|
||||||
return mVerifier;
|
return mVerifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIgnoreDuplicateRRs(boolean value)
|
||||||
|
{
|
||||||
|
mIgnoreDuplicateRRs = value;
|
||||||
|
}
|
||||||
|
|
||||||
private static String key(Name n, int type)
|
private static String key(Name n, int type)
|
||||||
{
|
{
|
||||||
return n.toString() + ':' + type;
|
return n.toString() + ':' + type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private boolean addRRtoRRset(RRset rrset, Record rr)
|
||||||
|
{
|
||||||
|
if (mIgnoreDuplicateRRs)
|
||||||
|
{
|
||||||
|
rrset.addRR(rr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Iterator i = rrset.rrs(); i.hasNext(); )
|
||||||
|
{
|
||||||
|
Record record = (Record) i.next();
|
||||||
|
if (rr.equals(record)) return false;
|
||||||
|
}
|
||||||
|
rrset.addRR(rr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a record to the various maps.
|
* Add a record to the various maps.
|
||||||
|
* @return TODO
|
||||||
*/
|
*/
|
||||||
private void addRR(Record r)
|
private boolean addRR(Record r)
|
||||||
{
|
{
|
||||||
Name r_name = r.getName();
|
Name r_name = r.getName();
|
||||||
int r_type = r.getType();
|
int r_type = r.getType();
|
||||||
@@ -139,8 +165,8 @@ public class ZoneVerifier
|
|||||||
rrset = new MarkRRset();
|
rrset = new MarkRRset();
|
||||||
mNSECMap.put(r_name, rrset);
|
mNSECMap.put(r_name, rrset);
|
||||||
}
|
}
|
||||||
rrset.addRR(r);
|
|
||||||
return;
|
return addRRtoRRset(rrset, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_type == Type.NSEC3)
|
if (r_type == Type.NSEC3)
|
||||||
@@ -152,8 +178,8 @@ public class ZoneVerifier
|
|||||||
rrset = new MarkRRset();
|
rrset = new MarkRRset();
|
||||||
mNSEC3Map.put(r_name, rrset);
|
mNSEC3Map.put(r_name, rrset);
|
||||||
}
|
}
|
||||||
rrset.addRR(r);
|
|
||||||
return;
|
return addRRtoRRset(rrset, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the name and type to the node map
|
// Add the name and type to the node map
|
||||||
@@ -173,7 +199,7 @@ public class ZoneVerifier
|
|||||||
rrset = new RRset();
|
rrset = new RRset();
|
||||||
mRRsetMap.put(k, rrset);
|
mRRsetMap.put(k, rrset);
|
||||||
}
|
}
|
||||||
rrset.addRR(r);
|
return addRRtoRRset(rrset, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -199,10 +225,11 @@ public class ZoneVerifier
|
|||||||
/**
|
/**
|
||||||
* Given an unsorted list of records, load the node and rrset maps, as well as
|
* Given an unsorted list of records, load the node and rrset maps, as well as
|
||||||
* determine the NSEC3 parameters and signing type.
|
* determine the NSEC3 parameters and signing type.
|
||||||
*
|
*
|
||||||
* @param records
|
* @param records
|
||||||
|
* @return TODO
|
||||||
*/
|
*/
|
||||||
private void calculateNodes(List<Record> records)
|
private int calculateNodes(List<Record> records)
|
||||||
{
|
{
|
||||||
mNodeMap = new TreeMap<Name, Set<Integer>>();
|
mNodeMap = new TreeMap<Name, Set<Integer>>();
|
||||||
mRRsetMap = new HashMap<String, RRset>();
|
mRRsetMap = new HashMap<String, RRset>();
|
||||||
@@ -210,13 +237,19 @@ public class ZoneVerifier
|
|||||||
// The zone is unsigned until we get a clue otherwise.
|
// The zone is unsigned until we get a clue otherwise.
|
||||||
mDNSSECType = DNSSECType.UNSIGNED;
|
mDNSSECType = DNSSECType.UNSIGNED;
|
||||||
|
|
||||||
|
int errors = 0;
|
||||||
for (Record r : records)
|
for (Record r : records)
|
||||||
{
|
{
|
||||||
Name r_name = r.getName();
|
Name r_name = r.getName();
|
||||||
int r_type = r.getType();
|
int r_type = r.getType();
|
||||||
|
|
||||||
// Add the record to the various maps.
|
// Add the record to the various maps.
|
||||||
addRR(r);
|
boolean res = addRR(r);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
log.warning("Record '" + r + "' detected as a duplicate");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
|
||||||
// Learn some things about the zone as we do this pass.
|
// Learn some things about the zone as we do this pass.
|
||||||
if (r_type == Type.SOA) mZoneName = r_name;
|
if (r_type == Type.SOA) mZoneName = r_name;
|
||||||
@@ -230,6 +263,8 @@ public class ZoneVerifier
|
|||||||
|
|
||||||
if (mDNSSECType == DNSSECType.UNSIGNED) mDNSSECType = determineDNSSECType(r);
|
if (mDNSSECType == DNSSECType.UNSIGNED) mDNSSECType = determineDNSSECType(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,7 +326,7 @@ public class ZoneVerifier
|
|||||||
last_cut = n;
|
last_cut = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check all of the RRset that should be signed
|
// check all of the RRsets that should be signed
|
||||||
for (int type : typeset)
|
for (int type : typeset)
|
||||||
{
|
{
|
||||||
if (type == Type.RRSIG) continue;
|
if (type == Type.RRSIG) continue;
|
||||||
@@ -354,24 +389,24 @@ public class ZoneVerifier
|
|||||||
private int processRRset(RRset rrset)
|
private int processRRset(RRset rrset)
|
||||||
{
|
{
|
||||||
List<String> reasons = new ArrayList<String>();
|
List<String> reasons = new ArrayList<String>();
|
||||||
int result = DNSSEC.Failed;
|
boolean result = false;
|
||||||
|
|
||||||
for (Iterator<Record> i = rrset.sigs(); i.hasNext();)
|
for (Iterator<Record> i = rrset.sigs(); i.hasNext();)
|
||||||
{
|
{
|
||||||
RRSIGRecord sigrec = (RRSIGRecord) i.next();
|
RRSIGRecord sigrec = (RRSIGRecord) i.next();
|
||||||
byte res = mVerifier.verifySignature(rrset, sigrec, null, reasons);
|
boolean res = mVerifier.verifySignature(rrset, sigrec, reasons);
|
||||||
if (res != DNSSEC.Secure)
|
if (!res)
|
||||||
{
|
{
|
||||||
log.warning("Signature failed to verify RRset:\n rr: "
|
log.warning("Signature failed to verify RRset:\n rr: "
|
||||||
+ ZoneUtils.rrsetToString(rrset, false) + "\n sig: " + sigrec + "\n"
|
+ ZoneUtils.rrsetToString(rrset, false) + "\n sig: " + sigrec + "\n"
|
||||||
+ reasonListToString(reasons));
|
+ reasonListToString(reasons));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res > result) result = res;
|
if (res) result = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
String rrsetname = rrset.getName() + "/" + Type.string(rrset.getType());
|
String rrsetname = rrset.getName() + "/" + Type.string(rrset.getType());
|
||||||
if (result == DNSSEC.Secure)
|
if (result)
|
||||||
{
|
{
|
||||||
log.fine("RRset " + rrsetname + " verified.");
|
log.fine("RRset " + rrsetname + " verified.");
|
||||||
}
|
}
|
||||||
@@ -380,7 +415,7 @@ public class ZoneVerifier
|
|||||||
log.warning("RRset " + rrsetname + " did not verify.");
|
log.warning("RRset " + rrsetname + " did not verify.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result == DNSSEC.Secure ? 0 : 1;
|
return result ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String typesToString(int[] types)
|
private String typesToString(int[] types)
|
||||||
@@ -710,9 +745,9 @@ public class ZoneVerifier
|
|||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
calculateNodes(records);
|
errors += calculateNodes(records);
|
||||||
|
|
||||||
errors = processNodes();
|
errors += processNodes();
|
||||||
|
|
||||||
if (mDNSSECType == DNSSECType.NSEC)
|
if (mDNSSECType == DNSSECType.NSEC)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user