Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
||||
20
ChangeLog
20
ChangeLog
@@ -1,3 +1,23 @@
|
||||
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>
|
||||
|
||||
* Released version 0.10.1.
|
||||
|
||||
17
README
17
README
@@ -1,6 +1,7 @@
|
||||
jdnssec-tools
|
||||
|
||||
http://www.verisignlabs.com/jdnssec-tools/
|
||||
https://github.com/dblacka/jdnssec-tools/wiki
|
||||
|
||||
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),
|
||||
and Sun's Java Cryptography extensions. A copy of each of these
|
||||
libraries is included in the distribution. Currently, these tools use
|
||||
a custom version of the DNSjava library (for NSEC3 support), which is
|
||||
provided.
|
||||
a custom version of the DNSjava library with minor modifications,
|
||||
which is provided.
|
||||
|
||||
See the "licenses" directory for the licensing information of this
|
||||
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.
|
||||
|
||||
|
||||
The source for this project is available in subversion, at
|
||||
http://svn.verisignlabs.com/jdnssec/tools/trunk. Source for
|
||||
the modified DNSjava library can be found in subversion at
|
||||
http://svn.verisignlabs.com/jdnssec/dnsjava/trunk.
|
||||
The source for this project is available in git on github:
|
||||
https://github.com/dblacka/jdnssec-tools
|
||||
|
||||
---
|
||||
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
|
||||
(mailto:davidb@verisign.com) or sent to the
|
||||
dnssec@verisignlabs.com mailing list
|
||||
(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.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.xbill.DNS.DNSSEC;
|
||||
import org.xbill.DNS.Name;
|
||||
import org.xbill.DNS.RRSIGRecord;
|
||||
import org.xbill.DNS.RRset;
|
||||
@@ -186,11 +185,11 @@ public class SignKeyset extends CLBase
|
||||
// skip unsigned rrsets.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
|
||||
import org.xbill.DNS.DNSSEC;
|
||||
import org.xbill.DNS.Name;
|
||||
import org.xbill.DNS.RRSIGRecord;
|
||||
import org.xbill.DNS.RRset;
|
||||
@@ -185,11 +184,11 @@ public class SignRRset extends CLBase
|
||||
// skip unsigned rrsets.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
import org.xbill.DNS.DNSKEYRecord;
|
||||
import org.xbill.DNS.DNSSEC;
|
||||
import org.xbill.DNS.DSRecord;
|
||||
import org.xbill.DNS.Name;
|
||||
import org.xbill.DNS.RRset;
|
||||
@@ -343,11 +342,11 @@ public class SignZone extends CLBase
|
||||
// skip unsigned rrsets.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public class VerifyZone extends CLBase
|
||||
public int startfudge = 0;
|
||||
public int expirefudge = 0;
|
||||
public boolean ignoreTime = false;
|
||||
public boolean ignoreDups = false;
|
||||
|
||||
public CLIState()
|
||||
{
|
||||
@@ -71,6 +72,10 @@ public class VerifyZone extends CLBase
|
||||
OptionBuilder.withLongOpt("ignore-time");
|
||||
OptionBuilder.withDescription("Ignore RRSIG inception and expiration time errors.");
|
||||
opts.addOption(OptionBuilder.create());
|
||||
|
||||
OptionBuilder.withLongOpt("ignore-duplicate-rrs");
|
||||
OptionBuilder.withDescription("Ignore duplicate record errors.");
|
||||
opts.addOption(OptionBuilder.create());
|
||||
}
|
||||
|
||||
protected void processOptions(CommandLine cli)
|
||||
@@ -80,6 +85,11 @@ public class VerifyZone extends CLBase
|
||||
ignoreTime = true;
|
||||
}
|
||||
|
||||
if (cli.hasOption("ignore-duplicate-rrs"))
|
||||
{
|
||||
ignoreDups = true;
|
||||
}
|
||||
|
||||
String optstr = null;
|
||||
if ((optstr = cli.getOptionValue('S')) != null)
|
||||
{
|
||||
@@ -126,6 +136,7 @@ public class VerifyZone extends CLBase
|
||||
zoneverifier.getVerifier().setStartFudge(state.startfudge);
|
||||
zoneverifier.getVerifier().setExpireFudge(state.expirefudge);
|
||||
zoneverifier.getVerifier().setIgnoreTime(state.ignoreTime);
|
||||
zoneverifier.setIgnoreDuplicateRRs(state.ignoreDups);
|
||||
|
||||
List<Record> records = ZoneUtils.readZoneFile(state.zonefile, null);
|
||||
|
||||
|
||||
@@ -105,25 +105,25 @@ public class DnsKeyAlgorithm
|
||||
mIdToMnemonicMap = new HashMap<Integer, String>();
|
||||
|
||||
// Load the standard DNSSEC algorithms.
|
||||
addAlgorithm(DNSSEC.RSAMD5, new Entry("MD5withRSA", RSA));
|
||||
addMnemonic("RSAMD5", DNSSEC.RSAMD5);
|
||||
addAlgorithm(DNSSEC.Algorithm.RSAMD5, new Entry("MD5withRSA", RSA));
|
||||
addMnemonic("RSAMD5", DNSSEC.Algorithm.RSAMD5);
|
||||
|
||||
addAlgorithm(DNSSEC.DH, new Entry("", DH));
|
||||
addMnemonic("DH", DNSSEC.DH);
|
||||
addAlgorithm(DNSSEC.Algorithm.DH, new Entry("", DH));
|
||||
addMnemonic("DH", DNSSEC.Algorithm.DH);
|
||||
|
||||
addAlgorithm(DNSSEC.DSA, new Entry("SHA1withDSA", DSA));
|
||||
addMnemonic("DSA", DNSSEC.DSA);
|
||||
addAlgorithm(DNSSEC.Algorithm.DSA, new Entry("SHA1withDSA", DSA));
|
||||
addMnemonic("DSA", DNSSEC.Algorithm.DSA);
|
||||
|
||||
addAlgorithm(DNSSEC.RSASHA1, new Entry("SHA1withRSA", RSA));
|
||||
addMnemonic("RSASHA1", DNSSEC.RSASHA1);
|
||||
addMnemonic("RSA", DNSSEC.RSASHA1);
|
||||
addAlgorithm(DNSSEC.Algorithm.RSASHA1, new Entry("SHA1withRSA", RSA));
|
||||
addMnemonic("RSASHA1", DNSSEC.Algorithm.RSASHA1);
|
||||
addMnemonic("RSA", DNSSEC.Algorithm.RSASHA1);
|
||||
|
||||
// Load the (now) standard aliases
|
||||
addAlias(DNSSEC.DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1", DNSSEC.DSA);
|
||||
addAlias(DNSSEC.RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1", DNSSEC.RSASHA1);
|
||||
addAlias(DNSSEC.Algorithm.DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1", DNSSEC.Algorithm.DSA);
|
||||
addAlias(DNSSEC.Algorithm.RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1", DNSSEC.Algorithm.RSASHA1);
|
||||
// Also recognize the BIND 9.6 mnemonics
|
||||
addMnemonic("NSEC3DSA", DNSSEC.DSA_NSEC3_SHA1);
|
||||
addMnemonic("NSEC3RSASHA1", DNSSEC.RSA_NSEC3_SHA1);
|
||||
addMnemonic("NSEC3DSA", DNSSEC.Algorithm.DSA_NSEC3_SHA1);
|
||||
addMnemonic("NSEC3RSASHA1", DNSSEC.Algorithm.RSA_NSEC3_SHA1);
|
||||
|
||||
// Algorithms added by RFC 5702.
|
||||
// NOTE: these algorithms aren't available in Java 1.4's sunprovider
|
||||
@@ -221,11 +221,11 @@ public class DnsKeyAlgorithm
|
||||
switch (baseType(algorithm))
|
||||
{
|
||||
case RSA:
|
||||
return DNSSEC.RSASHA1;
|
||||
return DNSSEC.Algorithm.RSASHA1;
|
||||
case DSA:
|
||||
return DNSSEC.DSA;
|
||||
return DNSSEC.Algorithm.DSA;
|
||||
case DH:
|
||||
return DNSSEC.DH;
|
||||
return DNSSEC.Algorithm.DH;
|
||||
default:
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -44,10 +44,8 @@ import javax.crypto.spec.DHParameterSpec;
|
||||
import javax.crypto.spec.DHPrivateKeySpec;
|
||||
|
||||
import org.xbill.DNS.DNSKEYRecord;
|
||||
import org.xbill.DNS.DNSSEC.DNSSECException;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -98,7 +96,14 @@ public class DnsKeyConverter
|
||||
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,
|
||||
int flags, int alg, PublicKey key)
|
||||
{
|
||||
Record kr = KEYConverter.buildRecord(name, Type.DNSKEY, dclass, ttl, flags,
|
||||
DNSKEYRecord.Protocol.DNSSEC, alg, key);
|
||||
|
||||
return (DNSKEYRecord) kr;
|
||||
try
|
||||
{
|
||||
return new DNSKEYRecord(name, dclass, ttl, flags, DNSKEYRecord.Protocol.DNSSEC, alg,
|
||||
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
|
||||
|
||||
@@ -333,15 +333,15 @@ public class DnsKeyPair
|
||||
if (pk != null)
|
||||
{
|
||||
// currently, alg 5 is the default over alg 1 (RSASHA1).
|
||||
if (pk instanceof RSAPublicKey) return DNSSEC.RSASHA1;
|
||||
if (pk instanceof DSAPublicKey) return DNSSEC.DSA;
|
||||
if (pk instanceof RSAPublicKey) return DNSSEC.Algorithm.RSASHA1;
|
||||
if (pk instanceof DSAPublicKey) return DNSSEC.Algorithm.DSA;
|
||||
}
|
||||
|
||||
PrivateKey priv = getPrivate();
|
||||
if (priv != null)
|
||||
{
|
||||
if (priv instanceof RSAPrivateKey) return DNSSEC.RSASHA1;
|
||||
if (priv instanceof DSAPrivateKey) return DNSSEC.DSA;
|
||||
if (priv instanceof RSAPrivateKey) return DNSSEC.Algorithm.RSASHA1;
|
||||
if (priv instanceof DSAPrivateKey) return DNSSEC.Algorithm.DSA;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
@@ -43,7 +43,7 @@ import org.xbill.DNS.*;
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class DnsSecVerifier implements Verifier
|
||||
public class DnsSecVerifier
|
||||
{
|
||||
|
||||
private class TrustedKeyStore
|
||||
@@ -157,47 +157,19 @@ public class DnsSecVerifier implements Verifier
|
||||
mIgnoreTime = v;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private DnsKeyPair findCachedKey(Cache cache, Name name, int algorithm, int footprint)
|
||||
private DnsKeyPair findKey(Name name, int algorithm, int footprint)
|
||||
{
|
||||
RRset[] keysets = cache.findAnyRecords(name, Type.KEY);
|
||||
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;
|
||||
return mKeyStore.find(name, algorithm, footprint);
|
||||
}
|
||||
|
||||
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 (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 == null || sigrec == null) return false;
|
||||
if (!rrset.getName().equals(sigrec.getName()))
|
||||
{
|
||||
log.fine("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())
|
||||
{
|
||||
@@ -205,7 +177,7 @@ public class DnsSecVerifier implements Verifier
|
||||
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 start = sigrec.getTimeSigned();
|
||||
@@ -221,7 +193,7 @@ public class DnsSecVerifier implements Verifier
|
||||
{
|
||||
log.fine("Signature is 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);
|
||||
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.
|
||||
*
|
||||
* @return DNSSEC.Secure if the signature verified, DNSSEC.Failed if it did
|
||||
* not verify (for any reason), and DNSSEC.Insecure if verification
|
||||
* could not be completed (usually because the public key was not
|
||||
* available).
|
||||
* @return true if the signature verified, false if it did
|
||||
* not verify (for any reason, including not finding the DNSKEY.)
|
||||
*/
|
||||
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);
|
||||
if (result != DNSSEC.Secure) return result;
|
||||
boolean result = validateSignature(rrset, sigrec, reasons);
|
||||
if (!result) return result;
|
||||
|
||||
DnsKeyPair keypair = findKey(cache, sigrec.getSigner(), sigrec.getAlgorithm(),
|
||||
DnsKeyPair keypair = findKey(sigrec.getSigner(), sigrec.getAlgorithm(),
|
||||
sigrec.getFootprint());
|
||||
|
||||
if (keypair == null)
|
||||
{
|
||||
if (reasons != null) reasons.add("Could not find matching trusted key");
|
||||
log.fine("could not find matching trusted key");
|
||||
return DNSSEC.Insecure;
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -290,10 +260,10 @@ public class DnsSecVerifier implements Verifier
|
||||
{
|
||||
if (reasons != null) reasons.add("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)
|
||||
{
|
||||
@@ -305,39 +275,38 @@ public class DnsSecVerifier implements Verifier
|
||||
}
|
||||
if (reasons != null) reasons.add("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.
|
||||
*
|
||||
* @return DNSSEC.Secure if the set verified, DNSSEC.Failed if it did not, and
|
||||
* DNSSEC.Insecure if verification could not complete.
|
||||
* @return true if the set verified, false if it did not.
|
||||
*/
|
||||
@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();
|
||||
|
||||
if (!i.hasNext())
|
||||
{
|
||||
log.fine("RRset failed to verify due to lack of signatures");
|
||||
return DNSSEC.Insecure;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
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;
|
||||
|
||||
if (mVerifyAllSigs && res != DNSSEC.Secure && res < result)
|
||||
// Otherwise, note if a signature failed to validate.
|
||||
if (mVerifyAllSigs && !res)
|
||||
{
|
||||
result = res;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.xbill.DNS.utils.base32;
|
||||
public class ProtoNSEC3
|
||||
{
|
||||
private Name originalOwner;
|
||||
private byte hashAlg;
|
||||
private int hashAlg;
|
||||
private byte flags;
|
||||
private int iterations;
|
||||
private byte[] salt;
|
||||
@@ -63,7 +63,7 @@ public class ProtoNSEC3
|
||||
* Creates an NSEC3 Record from the given data.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
this.zone = zone;
|
||||
@@ -80,7 +80,7 @@ public class ProtoNSEC3
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
this(owner, originalOwner, zone, dclass, ttl, hashAlg, flags, iterations, salt, next,
|
||||
@@ -168,7 +168,7 @@ public class ProtoNSEC3
|
||||
return dclass;
|
||||
}
|
||||
|
||||
public byte getHashAlgorithm()
|
||||
public int getHashAlgorithm()
|
||||
{
|
||||
return hashAlg;
|
||||
}
|
||||
|
||||
@@ -1430,7 +1430,7 @@ public class SignUtils
|
||||
* @throws NoSuchAlgorithmException
|
||||
* 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
|
||||
{
|
||||
MessageDigest md;
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.TreeMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.xbill.DNS.DNSKEYRecord;
|
||||
import org.xbill.DNS.DNSSEC;
|
||||
import org.xbill.DNS.NSEC3PARAMRecord;
|
||||
import org.xbill.DNS.NSEC3Record;
|
||||
import org.xbill.DNS.NSECRecord;
|
||||
@@ -64,6 +63,7 @@ public class ZoneVerifier
|
||||
private Name mZoneName;
|
||||
private DNSSECType mDNSSECType;
|
||||
private NSEC3PARAMRecord mNSEC3params;
|
||||
private boolean mIgnoreDuplicateRRs;
|
||||
|
||||
private DnsSecVerifier mVerifier;
|
||||
private base32 mBase32;
|
||||
@@ -108,22 +108,48 @@ public class ZoneVerifier
|
||||
mVerifier = new DnsSecVerifier();
|
||||
mBase32 = new base32(base32.Alphabet.BASE32HEX, false, true);
|
||||
mBAcmp = new ByteArrayComparator();
|
||||
mIgnoreDuplicateRRs = false;
|
||||
}
|
||||
|
||||
/** @return the DnsSecVerifier object used to verify individual RRsets. */
|
||||
public DnsSecVerifier getVerifier()
|
||||
{
|
||||
return mVerifier;
|
||||
}
|
||||
|
||||
public void setIgnoreDuplicateRRs(boolean value)
|
||||
{
|
||||
mIgnoreDuplicateRRs = value;
|
||||
}
|
||||
|
||||
private static String key(Name n, int 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.
|
||||
* @return TODO
|
||||
*/
|
||||
private void addRR(Record r)
|
||||
private boolean addRR(Record r)
|
||||
{
|
||||
Name r_name = r.getName();
|
||||
int r_type = r.getType();
|
||||
@@ -139,8 +165,8 @@ public class ZoneVerifier
|
||||
rrset = new MarkRRset();
|
||||
mNSECMap.put(r_name, rrset);
|
||||
}
|
||||
rrset.addRR(r);
|
||||
return;
|
||||
|
||||
return addRRtoRRset(rrset, r);
|
||||
}
|
||||
|
||||
if (r_type == Type.NSEC3)
|
||||
@@ -152,8 +178,8 @@ public class ZoneVerifier
|
||||
rrset = new MarkRRset();
|
||||
mNSEC3Map.put(r_name, rrset);
|
||||
}
|
||||
rrset.addRR(r);
|
||||
return;
|
||||
|
||||
return addRRtoRRset(rrset, r);
|
||||
}
|
||||
|
||||
// Add the name and type to the node map
|
||||
@@ -173,7 +199,7 @@ public class ZoneVerifier
|
||||
rrset = new RRset();
|
||||
mRRsetMap.put(k, rrset);
|
||||
}
|
||||
rrset.addRR(r);
|
||||
return addRRtoRRset(rrset, r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,8 +227,9 @@ public class ZoneVerifier
|
||||
* determine the NSEC3 parameters and signing type.
|
||||
*
|
||||
* @param records
|
||||
* @return TODO
|
||||
*/
|
||||
private void calculateNodes(List<Record> records)
|
||||
private int calculateNodes(List<Record> records)
|
||||
{
|
||||
mNodeMap = new TreeMap<Name, Set<Integer>>();
|
||||
mRRsetMap = new HashMap<String, RRset>();
|
||||
@@ -210,13 +237,19 @@ public class ZoneVerifier
|
||||
// The zone is unsigned until we get a clue otherwise.
|
||||
mDNSSECType = DNSSECType.UNSIGNED;
|
||||
|
||||
int errors = 0;
|
||||
for (Record r : records)
|
||||
{
|
||||
Name r_name = r.getName();
|
||||
int r_type = r.getType();
|
||||
|
||||
// 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.
|
||||
if (r_type == Type.SOA) mZoneName = r_name;
|
||||
@@ -230,6 +263,8 @@ public class ZoneVerifier
|
||||
|
||||
if (mDNSSECType == DNSSECType.UNSIGNED) mDNSSECType = determineDNSSECType(r);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,7 +326,7 @@ public class ZoneVerifier
|
||||
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)
|
||||
{
|
||||
if (type == Type.RRSIG) continue;
|
||||
@@ -354,24 +389,24 @@ public class ZoneVerifier
|
||||
private int processRRset(RRset rrset)
|
||||
{
|
||||
List<String> reasons = new ArrayList<String>();
|
||||
int result = DNSSEC.Failed;
|
||||
boolean result = false;
|
||||
|
||||
for (Iterator<Record> i = rrset.sigs(); i.hasNext();)
|
||||
{
|
||||
RRSIGRecord sigrec = (RRSIGRecord) i.next();
|
||||
byte res = mVerifier.verifySignature(rrset, sigrec, null, reasons);
|
||||
if (res != DNSSEC.Secure)
|
||||
boolean res = mVerifier.verifySignature(rrset, sigrec, reasons);
|
||||
if (!res)
|
||||
{
|
||||
log.warning("Signature failed to verify RRset:\n rr: "
|
||||
+ ZoneUtils.rrsetToString(rrset, false) + "\n sig: " + sigrec + "\n"
|
||||
+ reasonListToString(reasons));
|
||||
}
|
||||
|
||||
if (res > result) result = res;
|
||||
if (res) result = res;
|
||||
}
|
||||
|
||||
String rrsetname = rrset.getName() + "/" + Type.string(rrset.getType());
|
||||
if (result == DNSSEC.Secure)
|
||||
if (result)
|
||||
{
|
||||
log.fine("RRset " + rrsetname + " verified.");
|
||||
}
|
||||
@@ -380,7 +415,7 @@ public class ZoneVerifier
|
||||
log.warning("RRset " + rrsetname + " did not verify.");
|
||||
}
|
||||
|
||||
return result == DNSSEC.Secure ? 0 : 1;
|
||||
return result ? 0 : 1;
|
||||
}
|
||||
|
||||
private String typesToString(int[] types)
|
||||
@@ -710,9 +745,9 @@ public class ZoneVerifier
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
calculateNodes(records);
|
||||
errors += calculateNodes(records);
|
||||
|
||||
errors = processNodes();
|
||||
errors += processNodes();
|
||||
|
||||
if (mDNSSECType == DNSSECType.NSEC)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user