Compare commits
10 Commits
7a15f36b17
...
a72a903d0b
Author | SHA1 | Date | |
---|---|---|---|
|
a72a903d0b | ||
|
37e9932d6e | ||
|
c95cd7e0e9 | ||
|
a440dcb477 | ||
|
df70e41643 | ||
|
6ae8eb27da | ||
|
fd31e22d92 | ||
|
f17ea4256e | ||
|
3360e70e88 | ||
|
f875a3d4bf |
115
README
Normal file
115
README
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
DNSSECValTool
|
||||||
|
-------------
|
||||||
|
|
||||||
|
This is a command line Java tool for doing DNSSEC response
|
||||||
|
validatation against a single authoritative DNS server.
|
||||||
|
|
||||||
|
usage: java -jar dnssecvaltool.jar [..options..]
|
||||||
|
server: the DNS server to query.
|
||||||
|
query: a name [type [flags]] string.
|
||||||
|
query_file: a list of queries, one query per line.
|
||||||
|
count: send up to'count' queries, then stop.
|
||||||
|
dnskey_file: a file containing DNSKEY RRs to trust.
|
||||||
|
dnskey_query: query 'server' for DNSKEY at given name to trust,
|
||||||
|
may repeat
|
||||||
|
error_file: write DNSSEC validation failure details to this file
|
||||||
|
|
||||||
|
The DNSSECValTool needs a server to query ('server'), a query or list
|
||||||
|
of queries ('query' or 'query_file'), and a set of DNSKEYs to trust
|
||||||
|
('dnskey_file' or 'dnskey_query') -- these keys MUST be the ones used
|
||||||
|
to sign everything in the responses.
|
||||||
|
|
||||||
|
By default it logs everything to stdout. DNSSEC validation errors
|
||||||
|
(which is most of the output) can be redirected to a file (which will
|
||||||
|
be appended to if it already exists).
|
||||||
|
|
||||||
|
Note that the DNSSECValTool will skip queries if the qname isn't a
|
||||||
|
subdomain (or matches) the names of the DNSKEYs that have been added.
|
||||||
|
|
||||||
|
query_file
|
||||||
|
----------
|
||||||
|
|
||||||
|
This is a file of one query per line, with a query formatted as:
|
||||||
|
|
||||||
|
qname [qtype] [qclass] [flags]
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
pietbarber.com ns +ad
|
||||||
|
blacka.com a IN +do
|
||||||
|
verisign.com
|
||||||
|
|
||||||
|
The DO bit is redundant since all queries will be made with the DO bit
|
||||||
|
set.
|
||||||
|
|
||||||
|
Note: at the moment, flags are ignored.
|
||||||
|
|
||||||
|
dnskey_file
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The is a list of DNSKEYs in zone file format. It will ignore zone
|
||||||
|
file comments and non-DNSKEY records, so you can just use dig output:
|
||||||
|
|
||||||
|
dig @0 edu dnskey +dnssec > keys
|
||||||
|
dig @0 net dnskey +dnssec >> keys
|
||||||
|
|
||||||
|
dnskey_query
|
||||||
|
------------
|
||||||
|
|
||||||
|
For each one of these, do a DNSKEY query to the server for that name,
|
||||||
|
and add the resultant keys to the set of trusted keys.
|
||||||
|
|
||||||
|
Generating Queries
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The query files are basically the same as those used by the
|
||||||
|
dnsreconciler tool, so similar techniques can be used to query names
|
||||||
|
out of ISFs, etc. Here is a little perl code that will generate
|
||||||
|
queries for domain.tld, domain_.tld, and nameserver.tld for "EDU"
|
||||||
|
only:
|
||||||
|
|
||||||
|
#! /usr/bin/perl
|
||||||
|
|
||||||
|
while (<>) {
|
||||||
|
# parse domain table lines
|
||||||
|
/^i A / && do {
|
||||||
|
@fields = split();
|
||||||
|
$dn = $fields[3];
|
||||||
|
($dom, $tld) = split(/\./, $dn, 2);
|
||||||
|
next if $tld ne "EDU";
|
||||||
|
print "$dn. A\n";
|
||||||
|
print "${dom}_.$tld. A\n";
|
||||||
|
};
|
||||||
|
# parse nameserver table lines
|
||||||
|
/^i B / && do {
|
||||||
|
@fields = split();
|
||||||
|
$ns = $fields[3];
|
||||||
|
print "$ns. A\n";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
1. Query "a.edu-servers.net", fetching the .edu keys directly from
|
||||||
|
that server. Use queries.txt for the queries, and log all DNSSEC
|
||||||
|
validation failures to 'dnssecvaltool_errors.log'.
|
||||||
|
|
||||||
|
java -jar dnssecvaltool.jar server=a.edu-servers.net \
|
||||||
|
dnskey_query=edu \
|
||||||
|
query_file=queries.txt \
|
||||||
|
error_file=dnssecvaltool_errors.log
|
||||||
|
|
||||||
|
2. Query localhost with a single query for edu/soa, using stored keys
|
||||||
|
in the file 'keys'. Validation failures will be logged to stdout.
|
||||||
|
|
||||||
|
java -jar dnssecvaltool.jar server=127.0.0.1 \
|
||||||
|
dnskey_file=keys \
|
||||||
|
query="edu soa"
|
||||||
|
|
||||||
|
3. Query "a.gov-servers.net", fetching the .gov keys directly from
|
||||||
|
that server, then query for nasa.gov/A.
|
||||||
|
|
||||||
|
java -jar dnssecvaltool.jar server=a.gov-servers.net \
|
||||||
|
dnskey_query=gov \
|
||||||
|
query="nasa.gov a"
|
20
build.xml
20
build.xml
@ -5,7 +5,7 @@
|
|||||||
<property file="build.properties" />
|
<property file="build.properties" />
|
||||||
<property file="VERSION" />
|
<property file="VERSION" />
|
||||||
|
|
||||||
<property name="distname" value="dnssecreconciler-${version}" />
|
<property name="distname" value="dnssecvaltool-${version}" />
|
||||||
|
|
||||||
<property name="build.dir" value="build" />
|
<property name="build.dir" value="build" />
|
||||||
<property name="build.dest" value="${build.dir}/classes" />
|
<property name="build.dest" value="${build.dir}/classes" />
|
||||||
@ -40,15 +40,14 @@
|
|||||||
|
|
||||||
<target name="jar" depends="usage,compile">
|
<target name="jar" depends="usage,compile">
|
||||||
|
|
||||||
<jar destfile="${build.lib.dest}/dnssecreconciler.jar">
|
<jar destfile="${build.lib.dest}/dnssecvaltool.jar">
|
||||||
<zipfileset dir="${build.dest}" includes="**/*.class" />
|
<zipfileset dir="${build.dest}" includes="**/*.class" />
|
||||||
|
|
||||||
<zipfileset src="${lib.dir}/dnsjava-2.0.8-vrsn-2.jar" />
|
<zipfileset src="${lib.dir}/dnsjava-2.1.3-vrsn-3.jar" />
|
||||||
<zipfileset src="${lib.dir}/log4j-1.2.15.jar" />
|
<zipfileset src="${lib.dir}/log4j-1.2.15.jar" />
|
||||||
<zipfileset dir="${lib.dir}" prefix="lib" includes="**/*.properties" />
|
|
||||||
<manifest>
|
<manifest>
|
||||||
<attribute name="Main-Class"
|
<attribute name="Main-Class"
|
||||||
value="com.verisign.cl.DNSSECReconciler" />
|
value="com.verisign.cl.DNSSECValTool" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
</target>
|
</target>
|
||||||
@ -67,6 +66,15 @@
|
|||||||
</javadoc>
|
</javadoc>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="dist" depends="usage,jar">
|
||||||
|
<property name="dprefix" value="dnssecvaltool-${version}" />
|
||||||
|
<property name="tarfile" value="${dprefix}.tar.gz" />
|
||||||
|
<tar destfile="${tarfile}" compression="gzip">
|
||||||
|
<tarfileset dir="${build.lib.dest}" prefix="${dprefix}"
|
||||||
|
includes="*.jar" />
|
||||||
|
<tarfileset dir="." prefix="${dprefix}" includes="README" />
|
||||||
|
</tar>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="clean" depends="usage">
|
<target name="clean" depends="usage">
|
||||||
<delete dir="${build.dest}" />
|
<delete dir="${build.dest}" />
|
||||||
@ -76,7 +84,7 @@
|
|||||||
|
|
||||||
<target name="usage">
|
<target name="usage">
|
||||||
<echo message=" " />
|
<echo message=" " />
|
||||||
<echo message="DNSSECReconciler v. ${version} Build System" />
|
<echo message="DNSSECValTool v. ${version} Build System" />
|
||||||
<echo message="--------------------------------" />
|
<echo message="--------------------------------" />
|
||||||
<echo message="Available Targets:" />
|
<echo message="Available Targets:" />
|
||||||
<echo message=" compile - compiles the source code" />
|
<echo message=" compile - compiles the source code" />
|
||||||
|
Binary file not shown.
BIN
lib/dnsjava-2.1.3-vrsn-3.jar
Normal file
BIN
lib/dnsjava-2.1.3-vrsn-3.jar
Normal file
Binary file not shown.
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
####################################################################
|
|
||||||
#
|
|
||||||
# L O G 4 j A P P E N D E R s
|
|
||||||
#
|
|
||||||
###################################################################
|
|
||||||
|
|
||||||
###################
|
|
||||||
# Write Output to Console (aka TTY)
|
|
||||||
#
|
|
||||||
log4j.appender.console=org.apache.log4j.ConsoleAppender
|
|
||||||
log4j.appender.console.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.console.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
|
|
||||||
|
|
||||||
####################################################################
|
|
||||||
#
|
|
||||||
# R O O T D E B U G G I N G L E V E L
|
|
||||||
#
|
|
||||||
###################################################################
|
|
||||||
|
|
||||||
######################
|
|
||||||
# Set root logger level to an (Appender)
|
|
||||||
#
|
|
||||||
log4j.rootLogger=FATAL, console
|
|
@ -4,14 +4,16 @@ import java.io.*;
|
|||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import org.apache.log4j.PropertyConfigurator;
|
import org.apache.log4j.BasicConfigurator;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
import org.xbill.DNS.*;
|
import org.xbill.DNS.*;
|
||||||
|
|
||||||
import com.verisign.tat.dnssec.CaptiveValidator;
|
import com.verisign.tat.dnssec.CaptiveValidator;
|
||||||
import com.verisign.tat.dnssec.SecurityStatus;
|
import com.verisign.tat.dnssec.SecurityStatus;
|
||||||
import com.verisign.tat.dnssec.Util;
|
import com.verisign.tat.dnssec.Util;
|
||||||
|
|
||||||
public class DNSSECReconciler {
|
public class DNSSECValTool {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke with java -jar dnssecreconciler.jar server=127.0.0.1 \
|
* Invoke with java -jar dnssecreconciler.jar server=127.0.0.1 \
|
||||||
@ -32,8 +34,9 @@ public class DNSSECReconciler {
|
|||||||
public List<String> dnskeyNames;
|
public List<String> dnskeyNames;
|
||||||
public String errorFile;
|
public String errorFile;
|
||||||
public long count = 0;
|
public long count = 0;
|
||||||
|
public boolean debug = false;
|
||||||
|
|
||||||
DNSSECReconciler() {
|
DNSSECValTool() {
|
||||||
validator = new CaptiveValidator();
|
validator = new CaptiveValidator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +203,12 @@ public class DNSSECReconciler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log our set of trusted keys
|
// Log our set of trusted keys
|
||||||
|
List<String> trustedKeys = validator.listTrustedKeys();
|
||||||
|
if (trustedKeys.size() == 0) {
|
||||||
|
System.err.println("ERROR: no trusted keys found/provided.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (String key : validator.listTrustedKeys()) {
|
for (String key : validator.listTrustedKeys()) {
|
||||||
System.out.println("Trusted Key: " + key);
|
System.out.println("Trusted Key: " + key);
|
||||||
}
|
}
|
||||||
@ -215,11 +224,20 @@ public class DNSSECReconciler {
|
|||||||
Name zone = zoneFromQuery(query);
|
Name zone = zoneFromQuery(query);
|
||||||
// Skip queries in zones that we don't have keys for
|
// Skip queries in zones that we don't have keys for
|
||||||
if (zone == null) {
|
if (zone == null) {
|
||||||
|
if (debug) {
|
||||||
|
System.out.println("DEBUG: skipping query " + queryToString(query));
|
||||||
|
}
|
||||||
|
query = nextQuery();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
System.out.println("DEBUG: querying for: " + queryToString(query));
|
||||||
|
}
|
||||||
|
|
||||||
Message response = resolve(query);
|
Message response = resolve(query);
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
|
System.out.println("ERROR: No response for query: " + queryToString(query));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
byte result = validator.validateMessage(response, zone.toString());
|
byte result = validator.validateMessage(response, zone.toString());
|
||||||
@ -248,6 +266,7 @@ public class DNSSECReconciler {
|
|||||||
errorCount++;
|
errorCount++;
|
||||||
break;
|
break;
|
||||||
case SecurityStatus.SECURE:
|
case SecurityStatus.SECURE:
|
||||||
|
if (debug) System.out.println("DEBUG: response for " + queryToString(query) + " was valid.");
|
||||||
validCount++;
|
validCount++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -258,6 +277,7 @@ public class DNSSECReconciler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count > 0 && total >= count) {
|
if (count > 0 && total >= count) {
|
||||||
|
if (debug) System.out.println("DEBUG: reached maximum number of queries, exiting");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,21 +290,25 @@ public class DNSSECReconciler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void usage() {
|
private static void usage() {
|
||||||
System.err.println("usage: java -jar dnssecreconiler.jar [..options..]");
|
System.err.println("usage: java -jar dnssecvaltool.jar [..options..]");
|
||||||
System.err.println(" server: the DNS server to query.");
|
System.err.println(" server: the DNS server to query.");
|
||||||
System.err.println(" query: a name [type [flags]] string.");
|
System.err.println(" query: a name [type [flags]] string.");
|
||||||
System.err.println(" query_file: a list of queries, one query per line.");
|
System.err.println(" query_file: a list of queries, one query per line.");
|
||||||
System.err.println(" count: send up to'count' queries, then stop.");
|
System.err.println(" count: send up to'count' queries, then stop.");
|
||||||
System.err.println(" dnskey_file: a file containing DNSKEY RRs to trust.");
|
System.err.println(" dnskey_file: a file containing DNSKEY RRs to trust.");
|
||||||
System.err.println(" dnskey_query: query 'server' for DNSKEY at given name to trust, may repeat");
|
System.err.println(" dnskey_query: query 'server' for DNSKEY at given name to trust, may repeat.");
|
||||||
System.err.println(" error_file: write DNSSEC validation failure details to this file");
|
System.err.println(" error_file: write DNSSEC validation failure details to this file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] argv) {
|
public static void main(String[] argv) {
|
||||||
|
|
||||||
PropertyConfigurator.configure("lib/log4j.properties");
|
// Set up Log4J to just log to console.
|
||||||
|
BasicConfigurator.configure();
|
||||||
|
// And raise the log level quite high
|
||||||
|
Logger rootLogger = Logger.getRootLogger();
|
||||||
|
rootLogger.setLevel(Level.FATAL);
|
||||||
|
|
||||||
DNSSECReconciler dr = new DNSSECReconciler();
|
DNSSECValTool dr = new DNSSECValTool();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Parse the command line options
|
// Parse the command line options
|
||||||
@ -317,6 +341,9 @@ public class DNSSECReconciler {
|
|||||||
dr.dnskeyNames = new ArrayList<String>();
|
dr.dnskeyNames = new ArrayList<String>();
|
||||||
}
|
}
|
||||||
dr.dnskeyNames.add(optarg);
|
dr.dnskeyNames.add(optarg);
|
||||||
|
} else if (opt.equals("debug")) {
|
||||||
|
dr.debug = Boolean.parseBoolean(optarg);
|
||||||
|
rootLogger.setLevel(Level.TRACE);
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Unrecognized option: " + opt);
|
System.err.println("Unrecognized option: " + opt);
|
||||||
usage();
|
usage();
|
@ -26,6 +26,7 @@ package com.verisign.tat.dnssec;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import org.xbill.DNS.*;
|
import org.xbill.DNS.*;
|
||||||
|
import org.xbill.DNS.utils.base64;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -377,6 +378,13 @@ public class CaptiveValidator {
|
|||||||
// If so, an additional check will need to be made in the authority
|
// If so, an additional check will need to be made in the authority
|
||||||
// section.
|
// section.
|
||||||
wc = ValUtils.rrsetWildcard(rrsets[i]);
|
wc = ValUtils.rrsetWildcard(rrsets[i]);
|
||||||
|
// if the wildcard expansion equals the orig name, then we
|
||||||
|
// have the actual wildcard record and no actual wildcard
|
||||||
|
// expansion happened, so we shouldn't do the extra
|
||||||
|
// validation.
|
||||||
|
if (wc.equals(rrsets[i].getName())) {
|
||||||
|
wc = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Notice a DNAME that should be followed by an unsigned CNAME.
|
// Notice a DNAME that should be followed by an unsigned CNAME.
|
||||||
if ((qtype != Type.DNAME) && (rrsets[i].getType() == Type.DNAME)) {
|
if ((qtype != Type.DNAME) && (rrsets[i].getType() == Type.DNAME)) {
|
||||||
@ -446,8 +454,8 @@ public class CaptiveValidator {
|
|||||||
// If after all this, we still haven't proven the positive wildcard
|
// If after all this, we still haven't proven the positive wildcard
|
||||||
// response, fail.
|
// response, fail.
|
||||||
if ((wc != null) && !wcNSEC_ok) {
|
if ((wc != null) && !wcNSEC_ok) {
|
||||||
// log.debug("positive response was wildcard expansion and "
|
mErrorList.add("Positive response was wildcard expansion " +
|
||||||
// + "did not prove original data did not exist");
|
"and did not prove original data did not exist.");
|
||||||
m.setStatus(SecurityStatus.BOGUS);
|
m.setStatus(SecurityStatus.BOGUS);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -578,7 +586,7 @@ public class CaptiveValidator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsec3s.size() > 0) {
|
if (nsec3s != null && nsec3s.size() > 0) {
|
||||||
byte status = NSEC3ValUtils.proveNoDS(nsec3s, delegation, nsec3zone, mErrorList);
|
byte status = NSEC3ValUtils.proveNoDS(nsec3s, delegation, nsec3zone, mErrorList);
|
||||||
|
|
||||||
if (status != SecurityStatus.SECURE) {
|
if (status != SecurityStatus.SECURE) {
|
||||||
@ -944,7 +952,7 @@ public class CaptiveValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ValUtils.ResponseType subtype = ValUtils.classifyResponse(message, zone);
|
ValUtils.ResponseType subtype = ValUtils.classifyResponse(message, zone);
|
||||||
|
log.debug("Response was classified as a " + subtype);
|
||||||
switch (subtype) {
|
switch (subtype) {
|
||||||
case POSITIVE:
|
case POSITIVE:
|
||||||
log.trace("Validating a positive response");
|
log.trace("Validating a positive response");
|
||||||
@ -957,9 +965,9 @@ public class CaptiveValidator {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODATA:
|
case NODATA:
|
||||||
log.trace("Validating a NODATA response");
|
log.trace("Validating a NODATA response");
|
||||||
validateNodataResponse(message, key_rrset, mErrorList);
|
validateNodataResponse(message, key_rrset, mErrorList);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -996,6 +1004,18 @@ public class CaptiveValidator {
|
|||||||
return validateMessage(sm, z);
|
return validateMessage(sm, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte validateMessage(byte[] messagebytes, String zone)
|
||||||
|
throws IOException {
|
||||||
|
Message message = new Message(messagebytes);
|
||||||
|
return validateMessage(message, zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte validateMessage(String b64messagebytes, String zone)
|
||||||
|
throws IOException {
|
||||||
|
byte[] messagebytes = base64.fromString(b64messagebytes);
|
||||||
|
return validateMessage(messagebytes, zone);
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> listTrustedKeys() {
|
public List<String> listTrustedKeys() {
|
||||||
return mTrustedKeys.listTrustAnchors();
|
return mTrustedKeys.listTrustAnchors();
|
||||||
}
|
}
|
||||||
|
@ -46,46 +46,53 @@ public class DnsSecVerifier {
|
|||||||
private Logger log = Logger.getLogger(this.getClass());
|
private Logger log = Logger.getLogger(this.getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a mapping of DNSSEC algorithm numbers/private identifiers to JCA
|
* This is a mapping of DNSSEC algorithm numbers to JCA algorithm
|
||||||
* algorithm identifiers.
|
* identifiers.
|
||||||
*/
|
*/
|
||||||
private HashMap<Integer, AlgEntry> mAlgorithmMap;
|
private HashMap<Integer, AlgEntry> mAlgorithmMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a mapping of DNSSEC private (DNS name) identifiers to JCA
|
||||||
|
* algorithm identifiers.
|
||||||
|
*/
|
||||||
|
private HashMap<Name, AlgEntry> mPrivateAlgorithmMap;
|
||||||
|
|
||||||
public DnsSecVerifier() {
|
public DnsSecVerifier() {
|
||||||
mAlgorithmMap = new HashMap<Integer, AlgEntry>();
|
mAlgorithmMap = new HashMap<Integer, AlgEntry>();
|
||||||
|
mPrivateAlgorithmMap = new HashMap<Name, AlgEntry>();
|
||||||
|
|
||||||
// set the default algorithm map.
|
// set the default algorithm map.
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.RSAMD5), new AlgEntry(
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.RSAMD5), new AlgEntry(
|
||||||
"MD5withRSA", DNSSEC.RSAMD5, false));
|
"MD5withRSA", DNSSEC.Algorithm.RSAMD5, false));
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.DSA), new AlgEntry("SHA1withDSA",
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.DSA), new AlgEntry("SHA1withDSA",
|
||||||
DNSSEC.DSA, true));
|
DNSSEC.Algorithm.DSA, true));
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.RSASHA1), new AlgEntry(
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.RSASHA1), new AlgEntry(
|
||||||
"SHA1withRSA", DNSSEC.RSASHA1, false));
|
"SHA1withRSA", DNSSEC.Algorithm.RSASHA1, false));
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.DSA_NSEC3_SHA1), new AlgEntry(
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.DSA_NSEC3_SHA1), new AlgEntry(
|
||||||
"SHA1withDSA", DNSSEC.DSA, true));
|
"SHA1withDSA", DNSSEC.Algorithm.DSA, true));
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.RSA_NSEC3_SHA1), new AlgEntry(
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.RSA_NSEC3_SHA1), new AlgEntry(
|
||||||
"SHA1withRSA", DNSSEC.RSASHA1, false));
|
"SHA1withRSA", DNSSEC.Algorithm.RSASHA1, false));
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.RSASHA256), new AlgEntry(
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.RSASHA256), new AlgEntry(
|
||||||
"SHA256withRSA", DNSSEC.RSASHA256, false));
|
"SHA256withRSA", DNSSEC.Algorithm.RSASHA256, false));
|
||||||
mAlgorithmMap.put(new Integer(DNSSEC.RSASHA512), new AlgEntry(
|
mAlgorithmMap.put(Integer.valueOf(DNSSEC.Algorithm.RSASHA512), new AlgEntry(
|
||||||
"SHA512withRSA", DNSSEC.RSASHA512, false));
|
"SHA512withRSA", DNSSEC.Algorithm.RSASHA512, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDSA(int algorithm) {
|
private boolean isDSA(int algorithm) {
|
||||||
// shortcut the standard algorithms
|
// shortcut the standard algorithms
|
||||||
if (algorithm == DNSSEC.DSA) {
|
if (algorithm == DNSSEC.Algorithm.DSA) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (algorithm == DNSSEC.RSASHA1) {
|
if (algorithm == DNSSEC.Algorithm.RSASHA1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (algorithm == DNSSEC.RSAMD5) {
|
if (algorithm == DNSSEC.Algorithm.RSAMD5) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
|
AlgEntry entry = (AlgEntry) mAlgorithmMap.get(Integer.valueOf(algorithm));
|
||||||
|
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
return entry.isDSA;
|
return entry.isDSA;
|
||||||
@ -107,8 +114,8 @@ public class DnsSecVerifier {
|
|||||||
"dns.algorithm.");
|
"dns.algorithm.");
|
||||||
|
|
||||||
for (Util.ConfigEntry entry : aliases) {
|
for (Util.ConfigEntry entry : aliases) {
|
||||||
Integer alg_alias = new Integer(Util.parseInt(entry.key, -1));
|
Integer alg_alias = Integer.valueOf(Util.parseInt(entry.key, -1));
|
||||||
Integer alg_orig = new Integer(Util.parseInt(entry.value, -1));
|
Integer alg_orig = Integer.valueOf(Util.parseInt(entry.value, -1));
|
||||||
|
|
||||||
if (!mAlgorithmMap.containsKey(alg_orig)) {
|
if (!mAlgorithmMap.containsKey(alg_orig)) {
|
||||||
log.warn("Unable to alias " + alg_alias
|
log.warn("Unable to alias " + alg_alias
|
||||||
@ -152,7 +159,7 @@ public class DnsSecVerifier {
|
|||||||
* @return A List contains a one or more DNSKEYRecord objects, or null if a
|
* @return A List contains a one or more DNSKEYRecord objects, or null if a
|
||||||
* matching DNSKEY could not be found.
|
* matching DNSKEY could not be found.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
private List<DNSKEYRecord> findKey(RRset dnskey_rrset, RRSIGRecord signature) {
|
private List<DNSKEYRecord> findKey(RRset dnskey_rrset, RRSIGRecord signature) {
|
||||||
if (!signature.getSigner().equals(dnskey_rrset.getName())) {
|
if (!signature.getSigner().equals(dnskey_rrset.getName())) {
|
||||||
log.trace("findKey: could not find appropriate key because "
|
log.trace("findKey: could not find appropriate key because "
|
||||||
@ -195,12 +202,12 @@ public class DnsSecVerifier {
|
|||||||
* The rrset that the signature belongs to.
|
* The rrset that the signature belongs to.
|
||||||
* @param sigrec
|
* @param sigrec
|
||||||
* The signature record to check.
|
* The signature record to check.
|
||||||
* @return A value of DNSSEC.Secure if it looks OK, DNSSEC.Faile if it looks
|
* @return A value of SecurityStatus.SECURE if it looks OK, SecurityStatus.BOGUS if it looks
|
||||||
* bad.
|
* bad.
|
||||||
*/
|
*/
|
||||||
private byte checkSignature(RRset rrset, RRSIGRecord sigrec) {
|
private byte checkSignature(RRset rrset, RRSIGRecord sigrec) {
|
||||||
if ((rrset == null) || (sigrec == null)) {
|
if ((rrset == null) || (sigrec == null)) {
|
||||||
return DNSSEC.Failed;
|
return SecurityStatus.BOGUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rrset.getName().equals(sigrec.getName())) {
|
if (!rrset.getName().equals(sigrec.getName())) {
|
||||||
@ -236,7 +243,7 @@ public class DnsSecVerifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PublicKey parseDNSKEY(DNSKEYRecord key) {
|
public PublicKey parseDNSKEY(DNSKEYRecord key) {
|
||||||
AlgEntry ae = (AlgEntry) mAlgorithmMap.get(new Integer(key
|
AlgEntry ae = (AlgEntry) mAlgorithmMap.get(Integer.valueOf(key
|
||||||
.getAlgorithm()));
|
.getAlgorithm()));
|
||||||
|
|
||||||
if (key.getAlgorithm() != ae.dnssecAlg) {
|
if (key.getAlgorithm() != ae.dnssecAlg) {
|
||||||
@ -361,7 +368,7 @@ public class DnsSecVerifier {
|
|||||||
* @return SecurityStatus.SECURE if the rrest verified positively,
|
* @return SecurityStatus.SECURE if the rrest verified positively,
|
||||||
* SecurityStatus.BOGUS otherwise.
|
* SecurityStatus.BOGUS otherwise.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public byte verify(RRset rrset, RRset key_rrset) {
|
public byte verify(RRset rrset, RRset key_rrset) {
|
||||||
Iterator i = rrset.sigs();
|
Iterator i = rrset.sigs();
|
||||||
|
|
||||||
@ -397,7 +404,7 @@ public class DnsSecVerifier {
|
|||||||
* The DNSKEY to verify with.
|
* The DNSKEY to verify with.
|
||||||
* @return SecurityStatus.SECURE if the rrset verified, BOGUS otherwise.
|
* @return SecurityStatus.SECURE if the rrset verified, BOGUS otherwise.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public byte verify(RRset rrset, DNSKEYRecord dnskey) {
|
public byte verify(RRset rrset, DNSKEYRecord dnskey) {
|
||||||
// Iterate over RRSIGS
|
// Iterate over RRSIGS
|
||||||
Iterator i = rrset.sigs();
|
Iterator i = rrset.sigs();
|
||||||
@ -429,24 +436,24 @@ public class DnsSecVerifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsAlgorithm(int algorithm) {
|
public boolean supportsAlgorithm(int algorithm) {
|
||||||
return mAlgorithmMap.containsKey(new Integer(algorithm));
|
return mAlgorithmMap.containsKey(Integer.valueOf(algorithm));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsAlgorithm(Name private_id) {
|
public boolean supportsAlgorithm(Name private_id) {
|
||||||
return mAlgorithmMap.containsKey(private_id);
|
return mPrivateAlgorithmMap.containsKey(private_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int baseAlgorithm(int algorithm) {
|
public int baseAlgorithm(int algorithm) {
|
||||||
switch (algorithm) {
|
switch (algorithm) {
|
||||||
case DNSSEC.RSAMD5:
|
case DNSSEC.Algorithm.RSAMD5:
|
||||||
case DNSSEC.RSASHA1:
|
case DNSSEC.Algorithm.RSASHA1:
|
||||||
return RSA;
|
return RSA;
|
||||||
|
|
||||||
case DNSSEC.DSA:
|
case DNSSEC.Algorithm.DSA:
|
||||||
return DSA;
|
return DSA;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
|
AlgEntry entry = (AlgEntry) mAlgorithmMap.get(Integer.valueOf(algorithm));
|
||||||
|
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
@ -465,7 +472,7 @@ public class DnsSecVerifier {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
AlgEntry entry = (AlgEntry) mAlgorithmMap
|
AlgEntry entry = (AlgEntry) mAlgorithmMap
|
||||||
.get(new Integer(algorithm));
|
.get(Integer.valueOf(algorithm));
|
||||||
|
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
log.info("DNSSEC algorithm " + algorithm + " not recognized.");
|
log.info("DNSSEC algorithm " + algorithm + " not recognized.");
|
||||||
|
@ -137,17 +137,6 @@ public class NSEC3ValUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] hash(Name name, NSEC3Record nsec3) {
|
|
||||||
try {
|
|
||||||
return nsec3.hashName(name);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
st_log.warn("Did not recognize hash algorithm: "
|
|
||||||
+ nsec3.getHashAlgorithm());
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the name of a closest encloser, return the name *.closest_encloser.
|
* Given the name of a closest encloser, return the name *.closest_encloser.
|
||||||
*
|
*
|
||||||
@ -458,7 +447,7 @@ public class NSEC3ValUtils {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
private static boolean validIterations(NSEC3Parameters nsec3params,
|
private static boolean validIterations(NSEC3Parameters nsec3params,
|
||||||
RRset dnskey_rrset, DnsSecVerifier verifier) {
|
RRset dnskey_rrset, DnsSecVerifier verifier) {
|
||||||
// for now, we return the maximum iterations based simply on the key
|
// for now, we return the maximum iterations based simply on the key
|
||||||
|
@ -31,6 +31,7 @@ import java.util.*;
|
|||||||
* A version of the RRset class overrides the standard security status.
|
* A version of the RRset class overrides the standard security status.
|
||||||
*/
|
*/
|
||||||
public class SRRset extends RRset {
|
public class SRRset extends RRset {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private SecurityStatus mSecurityStatus;
|
private SecurityStatus mSecurityStatus;
|
||||||
|
|
||||||
/** Create a new, blank SRRset. */
|
/** Create a new, blank SRRset. */
|
||||||
@ -43,7 +44,7 @@ public class SRRset extends RRset {
|
|||||||
* Create a new SRRset from an existing RRset. This SRRset will contain that
|
* Create a new SRRset from an existing RRset. This SRRset will contain that
|
||||||
* same internal Record objects as the original RRset.
|
* same internal Record objects as the original RRset.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public SRRset(RRset r) {
|
public SRRset(RRset r) {
|
||||||
this();
|
this();
|
||||||
|
|
||||||
|
@ -23,12 +23,16 @@
|
|||||||
|
|
||||||
package com.verisign.tat.dnssec;
|
package com.verisign.tat.dnssec;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Codes for DNSSEC security statuses.
|
* Codes for DNSSEC security statuses.
|
||||||
*
|
*
|
||||||
* @author davidb
|
* @author davidb
|
||||||
*/
|
*/
|
||||||
public class SecurityStatus {
|
public class SecurityStatus implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public static final byte INVALID = -1;
|
public static final byte INVALID = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +35,7 @@ import org.xbill.DNS.utils.base64;
|
|||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.security.interfaces.DSAParams;
|
import java.security.interfaces.DSAParams;
|
||||||
@ -178,7 +179,7 @@ public class SignUtils {
|
|||||||
* @return the canonical wire line format of the rrset. This is the second
|
* @return the canonical wire line format of the rrset. This is the second
|
||||||
* part of data to be signed.
|
* part of data to be signed.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public static byte[] generateCanonicalRRsetData(RRset rrset, long ttl,
|
public static byte[] generateCanonicalRRsetData(RRset rrset, long ttl,
|
||||||
int labels) {
|
int labels) {
|
||||||
DNSOutput image = new DNSOutput();
|
DNSOutput image = new DNSOutput();
|
||||||
@ -456,7 +457,8 @@ public class SignUtils {
|
|||||||
* useful for comparing RDATA portions of DNS records in doing DNSSEC
|
* useful for comparing RDATA portions of DNS records in doing DNSSEC
|
||||||
* canonical ordering.
|
* canonical ordering.
|
||||||
*/
|
*/
|
||||||
public static class ByteArrayComparator implements Comparator<byte[]> {
|
public static class ByteArrayComparator implements Comparator<byte[]>, Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private int mOffset = 0;
|
private int mOffset = 0;
|
||||||
private boolean mDebug = false;
|
private boolean mDebug = false;
|
||||||
|
|
||||||
|
@ -86,6 +86,10 @@ public class TrustAnchorStore {
|
|||||||
public List<String> listTrustAnchors() {
|
public List<String> listTrustAnchors() {
|
||||||
List<String> res = new ArrayList<String>();
|
List<String> res = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (mMap == null) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, SRRset> entry : mMap.entrySet()) {
|
for (Map.Entry<String, SRRset> entry : mMap.entrySet()) {
|
||||||
for (Iterator<Record> i = entry.getValue().rrs(); i.hasNext();) {
|
for (Iterator<Record> i = entry.getValue().rrs(); i.hasNext();) {
|
||||||
DNSKEYRecord r = (DNSKEYRecord) i.next();
|
DNSKEYRecord r = (DNSKEYRecord) i.next();
|
||||||
|
@ -339,7 +339,7 @@ public class ValUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public static RRSIGRecord rrsetFirstSig(RRset rrset) {
|
public static RRSIGRecord rrsetFirstSig(RRset rrset) {
|
||||||
for (Iterator i = rrset.sigs(); i.hasNext();) {
|
for (Iterator i = rrset.sigs(); i.hasNext();) {
|
||||||
return (RRSIGRecord) i.next();
|
return (RRSIGRecord) i.next();
|
||||||
|
Loading…
Reference in New Issue
Block a user