diff --git a/src/com/verisign/tat/dnssec/CaptiveValidator.java b/src/com/verisign/tat/dnssec/CaptiveValidator.java index 9bfba09..4ada2aa 100644 --- a/src/com/verisign/tat/dnssec/CaptiveValidator.java +++ b/src/com/verisign/tat/dnssec/CaptiveValidator.java @@ -31,7 +31,6 @@ import java.io.IOException; import java.util.*; - /** * This resolver module implements a "captive" DNSSEC validator. The captive * validator does not have direct access to the Internet and DNS system -- @@ -48,12 +47,12 @@ public class CaptiveValidator { // The local verification utility. private DnsSecVerifier mVerifier; - private Logger log = Logger.getLogger(this.getClass()); + private Logger log = Logger.getLogger(this.getClass()); public CaptiveValidator() { - mVerifier = new DnsSecVerifier(); - mValUtils = new ValUtils(mVerifier); - mTrustedKeys = new TrustAnchorStore(); + mVerifier = new DnsSecVerifier(); + mValUtils = new ValUtils(mVerifier); + mTrustedKeys = new TrustAnchorStore(); } // ---------------- Module Initialization ------------------- @@ -61,18 +60,17 @@ public class CaptiveValidator { /** * Add a set of trusted keys from a file. The file should be in DNS master * zone file format. Only DNSKEY records will be added. - * + * * @param filename * The file contains the trusted keys. * @throws IOException */ @SuppressWarnings("unchecked") - public void addTrustedKeysFromFile(String filename) - throws IOException { + public void addTrustedKeysFromFile(String filename) throws IOException { // First read in the whole trust anchor file. - Master master = new Master(filename, Name.root, 0); + Master master = new Master(filename, Name.root, 0); ArrayList records = new ArrayList(); - Record r = null; + Record r = null; while ((r = master.nextRecord()) != null) { records.add(r); @@ -100,9 +98,9 @@ public class CaptiveValidator { } // If this record matches our current RRset, we can just add it. - if (cur_rrset.getName().equals(rec.getName()) && - (cur_rrset.getType() == rec.getType()) && - (cur_rrset.getDClass() == rec.getDClass())) { + if (cur_rrset.getName().equals(rec.getName()) + && (cur_rrset.getType() == rec.getType()) + && (cur_rrset.getDClass() == rec.getDClass())) { cur_rrset.addRR(rec); continue; @@ -121,7 +119,7 @@ public class CaptiveValidator { } public void addTrustedKeysFromResponse(Message m) { - RRset [] rrsets = m.getSectionRRsets(Section.ANSWER); + RRset[] rrsets = m.getSectionRRsets(Section.ANSWER); for (int i = 0; i < rrsets.length; ++i) { if (rrsets[i].getType() == Type.DNSKEY) { @@ -137,7 +135,7 @@ public class CaptiveValidator { * This routine normalizes a response. This includes removing "irrelevant" * records from the answer and additional sections and (re)synthesizing * CNAMEs from DNAMEs, if present. - * + * * @param response */ private SMessage normalize(SMessage m) { @@ -145,26 +143,25 @@ public class CaptiveValidator { return m; } - if ((m.getRcode() != Rcode.NOERROR) && - (m.getRcode() != Rcode.NXDOMAIN)) { + if ((m.getRcode() != Rcode.NOERROR) && (m.getRcode() != Rcode.NXDOMAIN)) { return m; } - Name qname = m.getQuestion().getName(); - int qtype = m.getQuestion().getType(); + Name qname = m.getQuestion().getName(); + int qtype = m.getQuestion().getType(); - Name sname = qname; + Name sname = qname; // For the ANSWER section, remove all "irrelevant" records and add // synthesized CNAMEs from DNAMEs // This will strip out-of-order CNAMEs as well. - List rrset_list = m.getSectionList(Section.ANSWER); - Set additional_names = new HashSet(); + List rrset_list = m.getSectionList(Section.ANSWER); + Set additional_names = new HashSet(); for (ListIterator i = rrset_list.listIterator(); i.hasNext();) { SRRset rrset = i.next(); - int type = rrset.getType(); - Name n = rrset.getName(); + int type = rrset.getType(); + Name n = rrset.getName(); // Handle DNAME synthesis; DNAME synthesis does not occur at the // DNAME name itself. @@ -182,16 +179,16 @@ public class CaptiveValidator { Name cname_alias = sname.fromDNAME(dname); // Note that synthesized CNAMEs should have a TTL of zero. - CNAMERecord cname = new CNAMERecord(sname, - dname.getDClass(), 0, cname_alias); - SRRset cname_rrset = new SRRset(); + CNAMERecord cname = new CNAMERecord(sname, dname + .getDClass(), 0, cname_alias); + SRRset cname_rrset = new SRRset(); cname_rrset.addRR(cname); i.add(cname_rrset); sname = cname_alias; } catch (NameTooLongException e) { - log.debug("not adding synthesized CNAME -- " + - "generated name is too long", e); + log.debug("not adding synthesized CNAME -- " + + "generated name is too long", e); } continue; @@ -244,10 +241,10 @@ public class CaptiveValidator { for (Iterator i = rrset_list.iterator(); i.hasNext();) { SRRset rrset = i.next(); - int type = rrset.getType(); + int type = rrset.getType(); - if (((type == Type.A) || (type == Type.AAAA)) && - !additional_names.contains(rrset.getName())) { + if (((type == Type.A) || (type == Type.AAAA)) + && !additional_names.contains(rrset.getName())) { i.remove(); } } @@ -257,7 +254,7 @@ public class CaptiveValidator { /** * Extract additional names from the records in an rrset. - * + * * @param additional_names * The set to add the additional names to, if any. * @param rrset @@ -269,8 +266,8 @@ public class CaptiveValidator { } for (Iterator i = rrset.rrs(); i.hasNext();) { - Record r = i.next(); - Name add_name = r.getAdditionalName(); + Record r = i.next(); + Name add_name = r.getAdditionalName(); if (add_name != null) { additional_names.add(add_name); @@ -279,8 +276,8 @@ public class CaptiveValidator { } private SRRset findKeys(SMessage message) { - Name qname = message.getQName(); - int qclass = message.getQClass(); + Name qname = message.getQName(); + int qclass = message.getQClass(); return mTrustedKeys.find(qname, qclass); } @@ -291,12 +288,12 @@ public class CaptiveValidator { * on in the original request, the response was already validated, or the * response is a kind of message that is unvalidatable (i.e., SERVFAIL, * REFUSED, etc.) - * + * * @param message * The message to check. * @param origRequest * The original request received from the client. - * + * * @return true if the response could use validation (although this does not * mean we can actually validate this response). */ @@ -310,8 +307,8 @@ public class CaptiveValidator { return false; } - if (!mTrustedKeys.isBelowTrustAnchor(message.getQName(), - message.getQClass())) { + if (!mTrustedKeys.isBelowTrustAnchor(message.getQName(), message + .getQClass())) { return false; } @@ -322,11 +319,11 @@ public class CaptiveValidator { * Given a "positive" response -- a response that contains an answer to the * question, and no CNAME chain, validate this response. This generally * consists of verifying the answer RRset and the authority RRsets. - * + * * Note that by the time this method is called, the process of finding the * trusted DNSKEY rrset that signs this response must already have been * completed. - * + * * @param response * The response to validate. * @param request @@ -336,18 +333,18 @@ public class CaptiveValidator { * answer. */ private void validatePositiveResponse(SMessage message, SRRset key_rrset) { - Name qname = message.getQName(); - int qtype = message.getQType(); + Name qname = message.getQName(); + int qtype = message.getQType(); - SMessage m = message; + SMessage m = message; // validate the ANSWER section - this will be the answer itself - SRRset [] rrsets = m.getSectionRRsets(Section.ANSWER); + SRRset[] rrsets = m.getSectionRRsets(Section.ANSWER); - Name wc = null; - boolean wcNSEC_ok = false; - boolean dname = false; - List nsec3s = null; + Name wc = null; + boolean wcNSEC_ok = false; + boolean dname = false; + List nsec3s = null; for (int i = 0; i < rrsets.length; i++) { // Skip the CNAME following a (validated) DNAME. @@ -366,8 +363,8 @@ public class CaptiveValidator { // If the (answer) rrset failed to validate, then this message is // BAD. if (status != SecurityStatus.SECURE) { - log.debug("Positive response has failed ANSWER rrset: " + - rrsets[i]); + log.debug("Positive response has failed ANSWER rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -395,8 +392,8 @@ public class CaptiveValidator { // a // bad message. if (status != SecurityStatus.SECURE) { - log.debug("Positive response has failed AUTHORITY rrset: " + - rrsets[i]); + log.debug("Positive response has failed AUTHORITY rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -408,8 +405,8 @@ public class CaptiveValidator { if ((wc != null) && (rrsets[i].getType() == Type.NSEC)) { NSECRecord nsec = (NSECRecord) rrsets[i].first(); - if (ValUtils.nsecProvesNameError(nsec, qname, - key_rrset.getName())) { + if (ValUtils.nsecProvesNameError(nsec, qname, key_rrset + .getName())) { Name nsec_wc = ValUtils.nsecWildcard(qname, nsec); if (!wc.equals(nsec_wc)) { @@ -440,7 +437,7 @@ public class CaptiveValidator { // records. if ((wc != null) && !wcNSEC_ok && (nsec3s != null)) { if (NSEC3ValUtils.proveWildcard(nsec3s, qname, key_rrset.getName(), - wc)) { + wc)) { wcNSEC_ok = true; } } @@ -469,13 +466,13 @@ public class CaptiveValidator { } // validate the AUTHORITY section. - SRRset [] rrsets = m.getSectionRRsets(Section.AUTHORITY); + SRRset[] rrsets = m.getSectionRRsets(Section.AUTHORITY); - boolean secure_delegation = false; - Name delegation = null; - Name nsec3zone = null; - NSECRecord nsec = null; - List nsec3s = null; + boolean secure_delegation = false; + Name delegation = null; + Name nsec3zone = null; + NSECRecord nsec = null; + List nsec3s = null; // validate the AUTHORITY section as well - this will generally be the // NS rrset, plus proof of a secure delegation or not @@ -492,8 +489,8 @@ public class CaptiveValidator { // have // a bad message. if (status != SecurityStatus.SECURE) { - log.debug("Positive response has failed AUTHORITY rrset: " + - rrsets[i]); + log.debug("Positive response has failed AUTHORITY rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -501,40 +498,39 @@ public class CaptiveValidator { } switch (type) { - case Type.DS: - secure_delegation = true; + case Type.DS: + secure_delegation = true; - break; + break; - case Type.NS: - delegation = rrsets[i].getName(); + case Type.NS: + delegation = rrsets[i].getName(); - break; + break; - case Type.NSEC: - nsec = (NSECRecord) rrsets[i].first(); + case Type.NSEC: + nsec = (NSECRecord) rrsets[i].first(); - break; + break; - case Type.NSEC3: + case Type.NSEC3: - if (nsec3s == null) { - nsec3s = new ArrayList(); - } + if (nsec3s == null) { + nsec3s = new ArrayList(); + } - NSEC3Record nsec3 = (NSEC3Record) rrsets[i].first(); - nsec3s.add(nsec3); - nsec3zone = rrsets[i].getSignerName(); // this is a hack of - // sorts. + NSEC3Record nsec3 = (NSEC3Record) rrsets[i].first(); + nsec3s.add(nsec3); + nsec3zone = rrsets[i].getSignerName(); // this is a hack of + // sorts. - break; + break; - default: - log.warn( - "Encountered unexpected type in a REFERRAL response: " + - Type.string(type)); + default: + log.warn("Encountered unexpected type in a REFERRAL response: " + + Type.string(type)); - break; + break; } } @@ -579,7 +575,8 @@ public class CaptiveValidator { } if (nsec3s.size() > 0) { - byte status = NSEC3ValUtils.proveNoDS(nsec3s, delegation, nsec3zone); + byte status = NSEC3ValUtils + .proveNoDS(nsec3s, delegation, nsec3zone); if (status != SecurityStatus.SECURE) { // the NSEC3 RRs MUST prove no DS, so the INDETERMINATE state is @@ -598,25 +595,26 @@ public class CaptiveValidator { m.setStatus(SecurityStatus.BOGUS); } - private void validateCNAMEResponse(SMessage message, SRRset key_rrset) {} + private void validateCNAMEResponse(SMessage message, SRRset key_rrset) { + } /** * Given an "ANY" response -- a response that contains an answer to a * qtype==ANY question, with answers. This consists of simply verifying all * present answer/auth RRsets, with no checking that all types are present. - * + * * NOTE: it may be possible to get parent-side delegation point records * here, which won't all be signed. Right now, this routine relies on the * upstream iterative resolver to not return these responses -- instead * treating them as referrals. - * + * * NOTE: RFC 4035 is silent on this issue, so this may change upon * clarification. - * + * * Note that by the time this method is called, the process of finding the * trusted DNSKEY rrset that signs this response must already have been * completed. - * + * * @param message * The response to validate. * @param key_rrset @@ -628,13 +626,13 @@ public class CaptiveValidator { if (qtype != Type.ANY) { throw new IllegalArgumentException( - "ANY validation called on non-ANY response."); + "ANY validation called on non-ANY response."); } SMessage m = message; // validate the ANSWER section. - SRRset [] rrsets = m.getSectionRRsets(Section.ANSWER); + SRRset[] rrsets = m.getSectionRRsets(Section.ANSWER); for (int i = 0; i < rrsets.length; i++) { int status = mValUtils.verifySRRset(rrsets[i], key_rrset); @@ -642,8 +640,8 @@ public class CaptiveValidator { // If the (answer) rrset failed to validate, then this message is // BAD. if (status != SecurityStatus.SECURE) { - log.debug("Positive response has failed ANSWER rrset: " + - rrsets[i]); + log.debug("Positive response has failed ANSWER rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -661,8 +659,8 @@ public class CaptiveValidator { // a // bad message. if (status != SecurityStatus.SECURE) { - log.debug("Positive response has failed AUTHORITY rrset: " + - rrsets[i]); + log.debug("Positive response has failed AUTHORITY rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -679,11 +677,11 @@ public class CaptiveValidator { * the authority section rrsets and making certain that the authority * section NSEC/NSEC3s proves that the qname does exist and the qtype * doesn't. - * + * * Note that by the time this method is called, the process of finding the * trusted DNSKEY rrset that signs this response must already have been * completed. - * + * * @param response * The response to validate. * @param request @@ -692,10 +690,10 @@ public class CaptiveValidator { * The trusted DNSKEY rrset that signs this response. */ private void validateNodataResponse(SMessage message, SRRset key_rrset) { - Name qname = message.getQName(); - int qtype = message.getQType(); + Name qname = message.getQName(); + int qtype = message.getQType(); - SMessage m = message; + SMessage m = message; // Since we are here, there must be nothing in the ANSWER section to // validate. (Note: CNAME/DNAME responses will not directly get here -- @@ -703,29 +701,29 @@ public class CaptiveValidator { // responses.) // validate the AUTHORITY section - SRRset [] rrsets = m.getSectionRRsets(Section.AUTHORITY); + SRRset[] rrsets = m.getSectionRRsets(Section.AUTHORITY); - boolean hasValidNSEC = false; // If true, then the NODATA has been - // proven. + boolean hasValidNSEC = false; // If true, then the NODATA has been + // proven. - Name ce = null; // for wildcard NODATA responses. This is the proven - // closest encloser. + Name ce = null; // for wildcard NODATA responses. This is the proven + // closest encloser. - NSECRecord wc = null; // for wildcard NODATA responses. This is the - // wildcard NSEC. + NSECRecord wc = null; // for wildcard NODATA responses. This is the + // wildcard NSEC. - List nsec3s = null; // A collection of NSEC3 RRs found in - // the authority - // section. + List nsec3s = null; // A collection of NSEC3 RRs found in + // the authority + // section. - Name nsec3Signer = null; // The RRSIG signer field for the NSEC3 RRs. + Name nsec3Signer = null; // The RRSIG signer field for the NSEC3 RRs. for (int i = 0; i < rrsets.length; i++) { int status = mValUtils.verifySRRset(rrsets[i], key_rrset); if (status != SecurityStatus.SECURE) { - log.debug("NODATA response has failed AUTHORITY rrset: " + - rrsets[i]); + log.debug("NODATA response has failed AUTHORITY rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -742,8 +740,8 @@ public class CaptiveValidator { if (nsec.getName().isWild()) { wc = nsec; } - } else if (ValUtils.nsecProvesNameError(nsec, qname, - rrsets[i].getSignerName())) { + } else if (ValUtils.nsecProvesNameError(nsec, qname, rrsets[i] + .getSignerName())) { ce = ValUtils.closestEncloser(qname, nsec); } } @@ -785,8 +783,8 @@ public class CaptiveValidator { } if (!hasValidNSEC) { - log.debug("NODATA response failed to prove NODATA " + - "status with NSEC/NSEC3"); + log.debug("NODATA response failed to prove NODATA " + + "status with NSEC/NSEC3"); log.trace("Failed NODATA:\n" + m); m.setStatus(SecurityStatus.BOGUS); @@ -802,11 +800,11 @@ public class CaptiveValidator { * Rcode. This consists of verifying the authority section rrsets and making * certain that the authority section NSEC proves that the qname doesn't * exist and the covering wildcard also doesn't exist.. - * + * * Note that by the time this method is called, the process of finding the * trusted DNSKEY rrset that signs this response must already have been * completed. - * + * * @param response * The response to validate. * @param request @@ -815,13 +813,13 @@ public class CaptiveValidator { * The trusted DNSKEY rrset that signs this response. */ private void validateNameErrorResponse(SMessage message, SRRset key_rrset) { - Name qname = message.getQName(); + Name qname = message.getQName(); - SMessage m = message; + SMessage m = message; if (message.getCount(Section.ANSWER) > 0) { - log.warn( - "NAME ERROR response contained records in the ANSWER SECTION"); + log + .warn("NAME ERROR response contained records in the ANSWER SECTION"); message.setStatus(SecurityStatus.INVALID); return; @@ -830,18 +828,18 @@ public class CaptiveValidator { // Validate the authority section -- all RRsets in the authority section // must be signed and valid. // In addition, the NSEC record(s) must prove the NXDOMAIN condition. - boolean hasValidNSEC = false; - boolean hasValidWCNSEC = false; - SRRset [] rrsets = m.getSectionRRsets(Section.AUTHORITY); - List nsec3s = null; - Name nsec3Signer = null; + boolean hasValidNSEC = false; + boolean hasValidWCNSEC = false; + SRRset[] rrsets = m.getSectionRRsets(Section.AUTHORITY); + List nsec3s = null; + Name nsec3Signer = null; for (int i = 0; i < rrsets.length; i++) { int status = mValUtils.verifySRRset(rrsets[i], key_rrset); if (status != SecurityStatus.SECURE) { - log.debug("NameError response has failed AUTHORITY rrset: " + - rrsets[i]); + log.debug("NameError response has failed AUTHORITY rrset: " + + rrsets[i]); m.setStatus(SecurityStatus.BOGUS); return; @@ -850,13 +848,13 @@ public class CaptiveValidator { if (rrsets[i].getType() == Type.NSEC) { NSECRecord nsec = (NSECRecord) rrsets[i].first(); - if (ValUtils.nsecProvesNameError(nsec, qname, - rrsets[i].getSignerName())) { + if (ValUtils.nsecProvesNameError(nsec, qname, rrsets[i] + .getSignerName())) { hasValidNSEC = true; } - if (ValUtils.nsecProvesNoWC(nsec, qname, - rrsets[i].getSignerName())) { + if (ValUtils.nsecProvesNoWC(nsec, qname, rrsets[i] + .getSignerName())) { hasValidWCNSEC = true; } } @@ -884,26 +882,26 @@ public class CaptiveValidator { return; } - hasValidNSEC = NSEC3ValUtils.proveNameError(nsec3s, qname, + hasValidNSEC = NSEC3ValUtils.proveNameError(nsec3s, qname, nsec3Signer); // Note that we assume that the NSEC3ValUtils proofs encompass the // wildcard part of the proof. - hasValidWCNSEC = hasValidNSEC; + hasValidWCNSEC = hasValidNSEC; } // If the message fails to prove either condition, it is bogus. if (!hasValidNSEC) { - log.debug("NameError response has failed to prove: " + - "qname does not exist"); + log.debug("NameError response has failed to prove: " + + "qname does not exist"); m.setStatus(SecurityStatus.BOGUS); return; } if (!hasValidWCNSEC) { - log.debug("NameError response has failed to prove: " + - "covering wildcard does not exist"); + log.debug("NameError response has failed to prove: " + + "covering wildcard does not exist"); m.setStatus(SecurityStatus.BOGUS); return; @@ -939,55 +937,56 @@ public class CaptiveValidator { return SecurityStatus.BOGUS; } - ValUtils.ResponseType subtype = ValUtils.classifyResponse(message, zone); + ValUtils.ResponseType subtype = ValUtils + .classifyResponse(message, zone); switch (subtype) { - case POSITIVE: - log.trace("Validating a positive response"); - validatePositiveResponse(message, key_rrset); + case POSITIVE: + log.trace("Validating a positive response"); + validatePositiveResponse(message, key_rrset); - break; + break; - case REFERRAL: - validateReferral(message, key_rrset); + case REFERRAL: + validateReferral(message, key_rrset); - break; + break; - case NODATA: - log.trace("Validating a NODATA response"); - validateNodataResponse(message, key_rrset); + case NODATA: + log.trace("Validating a NODATA response"); + validateNodataResponse(message, key_rrset); - break; + break; - case NAMEERROR: - log.trace("Validating a NXDOMAIN response"); - validateNameErrorResponse(message, key_rrset); + case NAMEERROR: + log.trace("Validating a NXDOMAIN response"); + validateNameErrorResponse(message, key_rrset); - break; + break; - case CNAME: - log.trace("Validating a CNAME response"); - validateCNAMEResponse(message, key_rrset); + case CNAME: + log.trace("Validating a CNAME response"); + validateCNAMEResponse(message, key_rrset); - break; + break; - case ANY: - log.trace("Validating a positive ANY response"); - validateAnyResponse(message, key_rrset); + case ANY: + log.trace("Validating a positive ANY response"); + validateAnyResponse(message, key_rrset); - break; + break; - default: - log.error("unhandled response subtype: " + subtype); + default: + log.error("unhandled response subtype: " + subtype); } return message.getSecurityStatus().getStatus(); } public byte validateMessage(Message message, String zone) - throws TextParseException { + throws TextParseException { SMessage sm = new SMessage(message); - Name z = Name.fromString(zone); + Name z = Name.fromString(zone); return validateMessage(sm, z); } diff --git a/src/com/verisign/tat/dnssec/DnsSecVerifier.java b/src/com/verisign/tat/dnssec/DnsSecVerifier.java index dac34cb..904558e 100644 --- a/src/com/verisign/tat/dnssec/DnsSecVerifier.java +++ b/src/com/verisign/tat/dnssec/DnsSecVerifier.java @@ -34,7 +34,6 @@ import java.security.*; import java.util.*; - /** * A class for performing basic DNSSEC verification. The DNSJAVA package * contains a similar class. This is a re-implementation that allows us to have @@ -42,9 +41,9 @@ import java.util.*; */ public class DnsSecVerifier { public static final int UNKNOWN = 0; - public static final int RSA = 1; - public static final int DSA = 2; - private Logger log = Logger.getLogger(this.getClass()); + public static final int RSA = 1; + public static final int DSA = 2; + private Logger log = Logger.getLogger(this.getClass()); /** * This is a mapping of DNSSEC algorithm numbers/private identifiers to JCA @@ -56,20 +55,20 @@ public class DnsSecVerifier { mAlgorithmMap = new HashMap(); // set the default algorithm map. - mAlgorithmMap.put(new Integer(DNSSEC.RSAMD5), - new AlgEntry("MD5withRSA", DNSSEC.RSAMD5, false)); - mAlgorithmMap.put(new Integer(DNSSEC.DSA), - new AlgEntry("SHA1withDSA", DNSSEC.DSA, true)); - mAlgorithmMap.put(new Integer(DNSSEC.RSASHA1), - new AlgEntry("SHA1withRSA", DNSSEC.RSASHA1, false)); - mAlgorithmMap.put(new Integer(DNSSEC.DSA_NSEC3_SHA1), - new AlgEntry("SHA1withDSA", DNSSEC.DSA, true)); - mAlgorithmMap.put(new Integer(DNSSEC.RSA_NSEC3_SHA1), - new AlgEntry("SHA1withRSA", DNSSEC.RSASHA1, false)); - mAlgorithmMap.put(new Integer(DNSSEC.RSASHA256), - new AlgEntry("SHA256withRSA", DNSSEC.RSASHA256, false)); - mAlgorithmMap.put(new Integer(DNSSEC.RSASHA512), - new AlgEntry("SHA512withRSA", DNSSEC.RSASHA512, false)); + mAlgorithmMap.put(new Integer(DNSSEC.RSAMD5), new AlgEntry( + "MD5withRSA", DNSSEC.RSAMD5, false)); + mAlgorithmMap.put(new Integer(DNSSEC.DSA), new AlgEntry("SHA1withDSA", + DNSSEC.DSA, true)); + mAlgorithmMap.put(new Integer(DNSSEC.RSASHA1), new AlgEntry( + "SHA1withRSA", DNSSEC.RSASHA1, false)); + mAlgorithmMap.put(new Integer(DNSSEC.DSA_NSEC3_SHA1), new AlgEntry( + "SHA1withDSA", DNSSEC.DSA, true)); + mAlgorithmMap.put(new Integer(DNSSEC.RSA_NSEC3_SHA1), new AlgEntry( + "SHA1withRSA", DNSSEC.RSASHA1, false)); + mAlgorithmMap.put(new Integer(DNSSEC.RSASHA256), new AlgEntry( + "SHA256withRSA", DNSSEC.RSASHA256, false)); + mAlgorithmMap.put(new Integer(DNSSEC.RSASHA512), new AlgEntry( + "SHA512withRSA", DNSSEC.RSASHA512, false)); } private boolean isDSA(int algorithm) { @@ -109,18 +108,18 @@ public class DnsSecVerifier { for (Util.ConfigEntry entry : aliases) { Integer alg_alias = new Integer(Util.parseInt(entry.key, -1)); - Integer alg_orig = new Integer(Util.parseInt(entry.value, -1)); + Integer alg_orig = new Integer(Util.parseInt(entry.value, -1)); if (!mAlgorithmMap.containsKey(alg_orig)) { - log.warn("Unable to alias " + alg_alias + - " to unknown algorithm " + alg_orig); + log.warn("Unable to alias " + alg_alias + + " to unknown algorithm " + alg_orig); continue; } if (mAlgorithmMap.containsKey(alg_alias)) { - log.warn("Algorithm alias " + alg_alias + - " is already defined and cannot be redefined"); + log.warn("Algorithm alias " + alg_alias + + " is already defined and cannot be redefined"); continue; } @@ -135,8 +134,8 @@ public class DnsSecVerifier { if (entry == null) { log.warn("DNSSEC alg " + alg + " has a null entry!"); } else { - log.debug("DNSSEC alg " + alg + " maps to " + entry.jcaName + - " (" + entry.dnssecAlg + ")"); + log.debug("DNSSEC alg " + alg + " maps to " + entry.jcaName + + " (" + entry.dnssecAlg + ")"); } } } @@ -145,7 +144,7 @@ public class DnsSecVerifier { * Find the matching DNSKEY(s) to an RRSIG within a DNSKEY rrset. Normally * this will only return one DNSKEY. It can return more than one, since * KeyID/Footprints are not guaranteed to be unique. - * + * * @param dnskey_rrset * The DNSKEY rrset to search. * @param signature @@ -156,17 +155,19 @@ public class DnsSecVerifier { @SuppressWarnings("unchecked") private List findKey(RRset dnskey_rrset, RRSIGRecord signature) { if (!signature.getSigner().equals(dnskey_rrset.getName())) { - log.trace("findKey: could not find appropriate key because " + - "incorrect keyset was supplied. Wanted: " + - signature.getSigner() + ", got: " + dnskey_rrset.getName()); + log.trace("findKey: could not find appropriate key because " + + "incorrect keyset was supplied. Wanted: " + + signature.getSigner() + ", got: " + + dnskey_rrset.getName()); return null; } - int keyid = signature.getFootprint(); - int alg = signature.getAlgorithm(); + int keyid = signature.getFootprint(); + int alg = signature.getAlgorithm(); - List res = new ArrayList(dnskey_rrset.size()); + List res = new ArrayList(dnskey_rrset + .size()); for (Iterator i = dnskey_rrset.rrs(); i.hasNext();) { DNSKEYRecord r = (DNSKEYRecord) i.next(); @@ -177,8 +178,8 @@ public class DnsSecVerifier { } if (res.size() == 0) { - log.trace("findKey: could not find a key matching " + - "the algorithm and footprint in supplied keyset. "); + log.trace("findKey: could not find a key matching " + + "the algorithm and footprint in supplied keyset. "); return null; } @@ -189,7 +190,7 @@ public class DnsSecVerifier { /** * Check to see if a signature looks valid (i.e., matches the rrset in * question, in the validity period, etc.) - * + * * @param rrset * The rrset that the signature belongs to. * @param sigrec @@ -214,8 +215,8 @@ public class DnsSecVerifier { return SecurityStatus.BOGUS; } - Date now = new Date(); - Date start = sigrec.getTimeSigned(); + Date now = new Date(); + Date start = sigrec.getTimeSigned(); Date expire = sigrec.getExpire(); if (now.before(start)) { @@ -225,8 +226,8 @@ public class DnsSecVerifier { } if (now.after(expire)) { - log.debug("Signature has expired (now = " + now + - ", sig expires = " + expire); + log.debug("Signature has expired (now = " + now + + ", sig expires = " + expire); return SecurityStatus.BOGUS; } @@ -235,8 +236,8 @@ public class DnsSecVerifier { } public PublicKey parseDNSKEY(DNSKEYRecord key) { - AlgEntry ae = (AlgEntry) mAlgorithmMap.get(new Integer( - key.getAlgorithm())); + AlgEntry ae = (AlgEntry) mAlgorithmMap.get(new Integer(key + .getAlgorithm())); if (key.getAlgorithm() != ae.dnssecAlg) { // Recast the DNSKEYRecord in question as one using the offical @@ -254,7 +255,7 @@ public class DnsSecVerifier { /** * Actually cryptographically verify a signature over the rrset. The RRSIG * record must match the rrset being verified (see checkSignature). - * + * * @param rrset * The rrset to verify. * @param sigrec @@ -265,19 +266,19 @@ public class DnsSecVerifier { * UNCHECKED if we just couldn't actually do the function. */ public byte verifySignature(RRset rrset, RRSIGRecord sigrec, - DNSKEYRecord key) { + DNSKEYRecord key) { try { PublicKey pk = parseDNSKEY(key); if (pk == null) { - log.warn( - "Could not convert DNSKEY record to a JCA public key: " + - key); + log + .warn("Could not convert DNSKEY record to a JCA public key: " + + key); return SecurityStatus.UNCHECKED; } - byte [] data = SignUtils.generateSigData(rrset, sigrec); + byte[] data = SignUtils.generateSigData(rrset, sigrec); Signature signer = getSignature(sigrec.getAlgorithm()); @@ -288,7 +289,7 @@ public class DnsSecVerifier { signer.initVerify(pk); signer.update(data); - byte [] sig = sigrec.getSignature(); + byte[] sig = sigrec.getSignature(); if (isDSA(sigrec.getAlgorithm())) { sig = SignUtils.convertDSASignature(sig); @@ -318,7 +319,7 @@ public class DnsSecVerifier { /** * Verify an RRset against a particular signature. - * + * * @return DNSSEC.Secure if the signature verfied, 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 @@ -356,7 +357,7 @@ public class DnsSecVerifier { * Verifies an RRset. This routine does not modify the RRset. This RRset is * presumed to be verifiable, and the correct DNSKEY rrset is presumed to * have been found. - * + * * @return SecurityStatus.SECURE if the rrest verified positively, * SecurityStatus.BOGUS otherwise. */ @@ -373,7 +374,7 @@ public class DnsSecVerifier { while (i.hasNext()) { RRSIGRecord sigrec = (RRSIGRecord) i.next(); - byte res = verifySignature(rrset, sigrec, key_rrset); + byte res = verifySignature(rrset, sigrec, key_rrset); if (res == SecurityStatus.SECURE) { return res; @@ -389,7 +390,7 @@ public class DnsSecVerifier { * Verify an RRset against a single DNSKEY. Use this when you must be * certain that an RRset signed and verifies with a particular DNSKEY (as * opposed to a particular DNSKEY rrset). - * + * * @param rrset * The rrset to verify. * @param dnskey @@ -437,12 +438,12 @@ public class DnsSecVerifier { public int baseAlgorithm(int algorithm) { switch (algorithm) { - case DNSSEC.RSAMD5: - case DNSSEC.RSASHA1: - return RSA; + case DNSSEC.RSAMD5: + case DNSSEC.RSASHA1: + return RSA; - case DNSSEC.DSA: - return DSA; + case DNSSEC.DSA: + return DSA; } AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm)); @@ -463,7 +464,8 @@ public class DnsSecVerifier { Signature s = null; try { - AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm)); + AlgEntry entry = (AlgEntry) mAlgorithmMap + .get(new Integer(algorithm)); if (entry == null) { log.info("DNSSEC algorithm " + algorithm + " not recognized."); @@ -481,14 +483,14 @@ public class DnsSecVerifier { } private static class AlgEntry { - public String jcaName; + public String jcaName; public boolean isDSA; - public int dnssecAlg; + public int dnssecAlg; public AlgEntry(String name, int dnssecAlg, boolean isDSA) { - jcaName = name; - this.dnssecAlg = dnssecAlg; - this.isDSA = isDSA; + jcaName = name; + this.dnssecAlg = dnssecAlg; + this.isDSA = isDSA; } } diff --git a/src/com/verisign/tat/dnssec/NSEC3ValUtils.java b/src/com/verisign/tat/dnssec/NSEC3ValUtils.java index 9eb6698..f0485b5 100644 --- a/src/com/verisign/tat/dnssec/NSEC3ValUtils.java +++ b/src/com/verisign/tat/dnssec/NSEC3ValUtils.java @@ -34,17 +34,16 @@ import java.security.NoSuchAlgorithmException; import java.util.*; - public class NSEC3ValUtils { // FIXME: should probably refactor to handle different NSEC3 parameters more // efficiently. // Given a list of NSEC3 RRs, they should be grouped according to // parameters. The idea is to hash and compare for each group independently, // instead of having to skip NSEC3 RRs with the wrong parameters. - private static Name asterisk_label = Name.fromConstantString("*"); - private static Logger st_log = Logger.getLogger(NSEC3ValUtils.class); - private static final base32 b32 = new base32(base32.Alphabet.BASE32HEX, - false, false); + private static Name asterisk_label = Name.fromConstantString("*"); + private static Logger st_log = Logger.getLogger(NSEC3ValUtils.class); + private static final base32 b32 = new base32(base32.Alphabet.BASE32HEX, + false, false); public static boolean supportsHashAlgorithm(int alg) { if (alg == NSEC3Record.SHA1_DIGEST_ID) { @@ -76,7 +75,7 @@ public class NSEC3ValUtils { * Given a list of NSEC3Records that are part of a message, determine the * NSEC3 parameters (hash algorithm, iterations, and salt) present. If there * is more than one distinct grouping, return null; - * + * * @param nsec3s * A list of NSEC3Record object. * @return A set containing a number of objects (NSEC3Parameter objects) @@ -88,9 +87,9 @@ public class NSEC3ValUtils { return null; } - NSEC3Parameters params = new NSEC3Parameters((NSEC3Record) nsec3s.get( - 0)); - ByteArrayComparator bac = new ByteArrayComparator(); + NSEC3Parameters params = new NSEC3Parameters((NSEC3Record) nsec3s + .get(0)); + ByteArrayComparator bac = new ByteArrayComparator(); for (NSEC3Record nsec3 : nsec3s) { if (!params.match(nsec3, bac)) { @@ -103,14 +102,14 @@ public class NSEC3ValUtils { /** * Given a hash and an a zone name, construct an NSEC3 ownername. - * + * * @param hash * The hash of an original name. * @param zonename * The zone to use in constructing the NSEC3 name. * @return The NSEC3 name. */ - private static Name hashName(byte [] hash, Name zonename) { + private static Name hashName(byte[] hash, Name zonename) { try { return new Name(b32.toString(hash).toLowerCase(), zonename); } catch (TextParseException e) { @@ -121,14 +120,14 @@ public class NSEC3ValUtils { /** * Given a set of NSEC3 parameters, hash a name. - * + * * @param name * The name to hash. * @param params * The parameters to hash with. * @return The hash. */ - private static byte [] hash(Name name, NSEC3Parameters params) { + private static byte[] hash(Name name, NSEC3Parameters params) { try { return params.hash(name); } catch (NoSuchAlgorithmException e) { @@ -142,7 +141,8 @@ public class NSEC3ValUtils { try { return nsec3.hashName(name); } catch (NoSuchAlgorithmException e) { - st_log.warn("Did not recognize hash algorithm: " + nsec3.getHashAlgorithm()); + st_log.warn("Did not recognize hash algorithm: " + + nsec3.getHashAlgorithm()); return null; } @@ -150,7 +150,7 @@ public class NSEC3ValUtils { /** * Given the name of a closest encloser, return the name *.closest_encloser. - * + * * @param closestEncloser * The name to start with. * @return The wildcard name. @@ -169,7 +169,7 @@ public class NSEC3ValUtils { * Given a qname and its proven closest encloser, calculate the "next * closest" name. Basically, this is the name that is one label longer than * the closest encloser that is still a subdomain of qname. - * + * * @param qname * The qname. * @param closestEncloser @@ -184,7 +184,7 @@ public class NSEC3ValUtils { /** * Find the NSEC3Record that matches a hash of a name. - * + * * @param hash * The pre-calculated hash of a name. * @param zonename @@ -196,12 +196,12 @@ public class NSEC3ValUtils { * @param bac * An already allocated ByteArrayComparator, for reuse. This may * be null. - * + * * @return The matching NSEC3Record, if one is present. */ - private static NSEC3Record findMatchingNSEC3(byte [] hash, Name zonename, - List nsec3s, NSEC3Parameters params, - ByteArrayComparator bac) { + private static NSEC3Record findMatchingNSEC3(byte[] hash, Name zonename, + List nsec3s, NSEC3Parameters params, + ByteArrayComparator bac) { Name n = hashName(hash, zonename); for (NSEC3Record nsec3 : nsec3s) { @@ -222,7 +222,7 @@ public class NSEC3ValUtils { * Given a hash and a candidate NSEC3Record, determine if that NSEC3Record * covers the hash. Covers specifically means that the hash is in between * the owner and next hashes and does not equal either. - * + * * @param nsec3 * The candidate NSEC3Record. * @param hash @@ -231,10 +231,10 @@ public class NSEC3ValUtils { * An already allocated comparator. This may be null. * @return True if the NSEC3Record covers the hash. */ - private static boolean nsec3Covers(NSEC3Record nsec3, byte [] hash, - ByteArrayComparator bac) { - byte [] owner = hash(nsec3.getName(), nsec3); - byte [] next = nsec3.getNext(); + private static boolean nsec3Covers(NSEC3Record nsec3, byte[] hash, + ByteArrayComparator bac) { + byte[] owner = hash(nsec3.getName(), nsec3); + byte[] next = nsec3.getNext(); // This is the "normal case: owner < next and owner < hash < next if ((bac.compare(owner, hash) < 0) && (bac.compare(hash, next) < 0)) { @@ -243,9 +243,8 @@ public class NSEC3ValUtils { // this is the end of zone case: next < owner && hash > owner || hash < // next - if ((bac.compare(next, owner) <= 0) && - ((bac.compare(hash, next) < 0) || - (bac.compare(owner, hash) < 0))) { + if ((bac.compare(next, owner) <= 0) + && ((bac.compare(hash, next) < 0) || (bac.compare(owner, hash) < 0))) { return true; } @@ -256,7 +255,7 @@ public class NSEC3ValUtils { /** * Given a pre-hashed name, find a covering NSEC3 from among a list of * NSEC3s. - * + * * @param hash * The hash to consider. * @param zonename @@ -266,12 +265,12 @@ public class NSEC3ValUtils { * @param params * The NSEC3 parameters used to generate the hash -- NSEC3s that * do not use those parameters will be skipped. - * + * * @return A covering NSEC3 if one is present, null otherwise. */ - private static NSEC3Record findCoveringNSEC3(byte [] hash, Name zonename, - List nsec3s, NSEC3Parameters params, - ByteArrayComparator bac) { + private static NSEC3Record findCoveringNSEC3(byte[] hash, Name zonename, + List nsec3s, NSEC3Parameters params, + ByteArrayComparator bac) { ByteArrayComparator comparator = new ByteArrayComparator(); for (NSEC3Record nsec3 : nsec3s) { @@ -291,7 +290,7 @@ public class NSEC3ValUtils { * Given a name and a list of NSEC3s, find the candidate closest encloser. * This will be the first ancestor of 'name' (including itself) to have a * matching NSEC3 RR. - * + * * @param name * The name the start with. * @param zonename @@ -302,14 +301,14 @@ public class NSEC3ValUtils { * The NSEC3 parameters. * @param bac * A pre-allocated comparator. May be null. - * + * * @return A CEResponse containing the closest encloser name and the NSEC3 * RR that matched it, or null if there wasn't one. */ private static CEResponse findClosestEncloser(Name name, Name zonename, - List nsec3s, NSEC3Parameters params, - ByteArrayComparator bac) { - Name n = name; + List nsec3s, NSEC3Parameters params, + ByteArrayComparator bac) { + Name n = name; NSEC3Record nsec3; @@ -318,8 +317,8 @@ public class NSEC3ValUtils { // FIXME: modify so that the NSEC3 matching the zone apex need not be // present. while (n.labels() >= zonename.labels()) { - nsec3 = findMatchingNSEC3(hash(n, params), zonename, - nsec3s, params, bac); + nsec3 = findMatchingNSEC3(hash(n, params), zonename, nsec3s, + params, bac); if (nsec3 != null) { return new CEResponse(n, nsec3); @@ -333,7 +332,7 @@ public class NSEC3ValUtils { /** * Given a List of nsec3 RRs, find and prove the closest encloser to qname. - * + * * @param qname * The qname in question. * @param zonename @@ -352,21 +351,22 @@ public class NSEC3ValUtils { * that matches it. */ private static CEResponse proveClosestEncloser(Name qname, Name zonename, - List nsec3s, NSEC3Parameters params, - ByteArrayComparator bac, boolean proveDoesNotExist) { + List nsec3s, NSEC3Parameters params, + ByteArrayComparator bac, boolean proveDoesNotExist) { CEResponse candidate = findClosestEncloser(qname, zonename, nsec3s, params, bac); if (candidate == null) { - st_log.debug("proveClosestEncloser: could not find a " + - "candidate for the closest encloser."); + st_log.debug("proveClosestEncloser: could not find a " + + "candidate for the closest encloser."); return null; } if (candidate.closestEncloser.equals(qname)) { if (proveDoesNotExist) { - st_log.debug("proveClosestEncloser: proved that qname existed!"); + st_log + .debug("proveClosestEncloser: proved that qname existed!"); return null; } @@ -380,10 +380,10 @@ public class NSEC3ValUtils { // should have been a referral. If it is a DNAME, then it should have // been // a DNAME response. - if (candidate.ce_nsec3.hasType(Type.NS) && - !candidate.ce_nsec3.hasType(Type.SOA)) { - st_log.debug("proveClosestEncloser: closest encloser " + - "was a delegation!"); + if (candidate.ce_nsec3.hasType(Type.NS) + && !candidate.ce_nsec3.hasType(Type.SOA)) { + st_log.debug("proveClosestEncloser: closest encloser " + + "was a delegation!"); return null; } @@ -395,15 +395,15 @@ public class NSEC3ValUtils { } // Otherwise, we need to show that the next closer name is covered. - Name nextClosest = nextClosest(qname, candidate.closestEncloser); + Name nextClosest = nextClosest(qname, candidate.closestEncloser); - byte [] nc_hash = hash(nextClosest, params); - candidate.nc_nsec3 = findCoveringNSEC3(nc_hash, zonename, nsec3s, + byte[] nc_hash = hash(nextClosest, params); + candidate.nc_nsec3 = findCoveringNSEC3(nc_hash, zonename, nsec3s, params, bac); if (candidate.nc_nsec3 == null) { - st_log.debug("Could not find proof that the " + - "closest encloser was the closest encloser"); + st_log.debug("Could not find proof that the " + + "closest encloser was the closest encloser"); return null; } @@ -413,41 +413,41 @@ public class NSEC3ValUtils { private static int maxIterations(int baseAlg, int keysize) { switch (baseAlg) { - case DnsSecVerifier.RSA: + case DnsSecVerifier.RSA: - if (keysize == 0) { - return 2500; // the max at 4096 - } + if (keysize == 0) { + return 2500; // the max at 4096 + } - if (keysize > 2048) { - return 2500; - } + if (keysize > 2048) { + return 2500; + } - if (keysize > 1024) { - return 500; - } + if (keysize > 1024) { + return 500; + } - if (keysize > 0) { - return 150; - } + if (keysize > 0) { + return 150; + } - break; + break; - case DnsSecVerifier.DSA: + case DnsSecVerifier.DSA: - if (keysize == 0) { - return 5000; // the max at 2048; - } + if (keysize == 0) { + return 5000; // the max at 2048; + } - if (keysize > 1024) { - return 5000; - } + if (keysize > 1024) { + return 5000; + } - if (keysize > 0) { - return 1500; - } + if (keysize > 0) { + return 1500; + } - break; + break; } return -1; @@ -455,17 +455,16 @@ public class NSEC3ValUtils { @SuppressWarnings("unchecked") 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 // algorithms that may have been used to sign the NSEC3 RRsets. int max_iterations = 0; for (Iterator i = dnskey_rrset.rrs(); i.hasNext();) { - DNSKEYRecord dnskey = (DNSKEYRecord) i.next(); - int baseAlg = verifier.baseAlgorithm(dnskey.getAlgorithm()); - int iters = maxIterations(baseAlg, 0); - max_iterations = (max_iterations < iters) ? iters - : max_iterations; + DNSKEYRecord dnskey = (DNSKEYRecord) i.next(); + int baseAlg = verifier.baseAlgorithm(dnskey.getAlgorithm()); + int iters = maxIterations(baseAlg, 0); + max_iterations = (max_iterations < iters) ? iters : max_iterations; } if (nsec3params.iterations > max_iterations) { @@ -479,7 +478,7 @@ public class NSEC3ValUtils { * Determine if all of the NSEC3s in a response are legally ignoreable * (i.e., their presence should lead to an INSECURE result). Currently, this * is solely based on iterations. - * + * * @param nsec3s * The list of NSEC3s. If there is more than one set of NSEC3 * parameters present, this test will not be performed. @@ -491,7 +490,7 @@ public class NSEC3ValUtils { * @return true if all of the NSEC3s can be legally ignored, false if not. */ public static boolean allNSEC3sIgnoreable(List nsec3s, - RRset dnskey_rrset, DnsSecVerifier verifier) { + RRset dnskey_rrset, DnsSecVerifier verifier) { NSEC3Parameters params = nsec3Parameters(nsec3s); if (params == null) { @@ -506,7 +505,7 @@ public class NSEC3ValUtils { * ERROR. This means that the NSEC3s prove a) the closest encloser exists, * b) the direct child of the closest encloser towards qname doesn't exist, * and c) *.closest encloser does not exist. - * + * * @param nsec3s * The list of NSEC3s. * @param qname @@ -520,7 +519,7 @@ public class NSEC3ValUtils { * ignored. */ public static boolean proveNameError(List nsec3s, Name qname, - Name zonename) { + Name zonename) { if ((nsec3s == null) || (nsec3s.size() == 0)) { return false; } @@ -528,8 +527,8 @@ public class NSEC3ValUtils { NSEC3Parameters nsec3params = nsec3Parameters(nsec3s); if (nsec3params == null) { - st_log.debug("Could not find a single set of " + - "NSEC3 parameters (multiple parameters present)."); + st_log.debug("Could not find a single set of " + + "NSEC3 parameters (multiple parameters present)."); return false; } @@ -550,14 +549,14 @@ public class NSEC3ValUtils { // At this point, we know that qname does not exist. Now we need to // prove // that the wildcard does not exist. - Name wc = ceWildcard(ce.closestEncloser); - byte [] wc_hash = hash(wc, nsec3params); - NSEC3Record nsec3 = findCoveringNSEC3(wc_hash, zonename, nsec3s, + Name wc = ceWildcard(ce.closestEncloser); + byte[] wc_hash = hash(wc, nsec3params); + NSEC3Record nsec3 = findCoveringNSEC3(wc_hash, zonename, nsec3s, nsec3params, bac); if (nsec3 == null) { - st_log.debug("proveNameError: could not prove that the " + - "applicable wildcard did not exist."); + st_log.debug("proveNameError: could not prove that the " + + "applicable wildcard did not exist."); return false; } @@ -568,23 +567,23 @@ public class NSEC3ValUtils { /** * Determine if the NSEC3s provided in a response prove the NOERROR/NODATA * status. There are a number of different variants to this: - * + * * 1) Normal NODATA -- qname is matched to an NSEC3 record, type is not * present. - * + * * 2) ENT NODATA -- because there must be NSEC3 record for * empty-non-terminals, this is the same as #1. - * + * * 3) NSEC3 ownername NODATA -- qname matched an existing, lone NSEC3 * ownername, but qtype was not NSEC3. NOTE: as of nsec-05, this case no * longer exists. - * + * * 4) Wildcard NODATA -- A wildcard matched the name, but not the type. - * + * * 5) Opt-In DS NODATA -- the qname is covered by an opt-in span and qtype * == DS. (or maybe some future record with the same parent-side-only * property) - * + * * @param nsec3s * The NSEC3Records to consider. * @param qname @@ -596,7 +595,7 @@ public class NSEC3ValUtils { * @return true if the NSEC3s prove the proposition. */ public static boolean proveNodata(List nsec3s, Name qname, - int qtype, Name zonename) { + int qtype, Name zonename) { if ((nsec3s == null) || (nsec3s.size() == 0)) { return false; } @@ -604,29 +603,29 @@ public class NSEC3ValUtils { NSEC3Parameters nsec3params = nsec3Parameters(nsec3s); if (nsec3params == null) { - st_log.debug("could not find a single set of " + - "NSEC3 parameters (multiple parameters present)"); + st_log.debug("could not find a single set of " + + "NSEC3 parameters (multiple parameters present)"); return false; } - ByteArrayComparator bac = new ByteArrayComparator(); + ByteArrayComparator bac = new ByteArrayComparator(); - NSEC3Record nsec3 = findMatchingNSEC3(hash(qname, nsec3params), + NSEC3Record nsec3 = findMatchingNSEC3(hash(qname, nsec3params), zonename, nsec3s, nsec3params, bac); // Cases 1 & 2. if (nsec3 != null) { if (nsec3.hasType(qtype)) { - st_log.debug( - "proveNodata: Matching NSEC3 proved that type existed!"); + st_log + .debug("proveNodata: Matching NSEC3 proved that type existed!"); return false; } if (nsec3.hasType(Type.CNAME)) { - st_log.debug("proveNodata: Matching NSEC3 proved " + - "that a CNAME existed!"); + st_log.debug("proveNodata: Matching NSEC3 proved " + + "that a CNAME existed!"); return false; } @@ -643,8 +642,8 @@ public class NSEC3ValUtils { // At this point, not finding a match or a proven closest encloser is a // problem. if (ce == null) { - st_log.debug("proveNodata: did not match qname, " + - "nor found a proven closest encloser."); + st_log.debug("proveNodata: did not match qname, " + + "nor found a proven closest encloser."); return false; } @@ -668,16 +667,17 @@ public class NSEC3ValUtils { // Case 5. if (qtype != Type.DS) { - st_log.debug("proveNodata: could not find matching NSEC3, " + - "nor matching wildcard, and qtype is not DS -- no more options."); + st_log + .debug("proveNodata: could not find matching NSEC3, " + + "nor matching wildcard, and qtype is not DS -- no more options."); return false; } // We need to make sure that the covering NSEC3 is opt-in. if (!isOptOut(ce.nc_nsec3)) { - st_log.debug("proveNodata: covering NSEC3 was not " + - "opt-in in an opt-in DS NOERROR/NODATA case."); + st_log.debug("proveNodata: covering NSEC3 was not " + + "opt-in in an opt-in DS NOERROR/NODATA case."); return false; } @@ -688,7 +688,7 @@ public class NSEC3ValUtils { /** * Prove that a positive wildcard match was appropriate (no direct match * RRset). - * + * * @param nsec3s * The NSEC3 records to work with. * @param qname @@ -700,7 +700,7 @@ public class NSEC3ValUtils { * @return true if the NSEC3 records prove this case. */ public static boolean proveWildcard(List nsec3s, Name qname, - Name zonename, Name wildcard) { + Name zonename, Name wildcard) { if ((nsec3s == null) || (nsec3s.size() == 0)) { return false; } @@ -712,8 +712,8 @@ public class NSEC3ValUtils { NSEC3Parameters nsec3params = nsec3Parameters(nsec3s); if (nsec3params == null) { - st_log.debug( - "couldn't find a single set of NSEC3 parameters (multiple parameters present)."); + st_log + .debug("couldn't find a single set of NSEC3 parameters (multiple parameters present)."); return false; } @@ -732,10 +732,10 @@ public class NSEC3ValUtils { zonename, nsec3s, nsec3params, bac); if (candidate.nc_nsec3 == null) { - st_log.debug("proveWildcard: did not find a covering NSEC3 " + - "that covered the next closer name to " + qname + " from " + - candidate.closestEncloser + " (derived from wildcard " + - wildcard + ")"); + st_log.debug("proveWildcard: did not find a covering NSEC3 " + + "that covered the next closer name to " + qname + + " from " + candidate.closestEncloser + + " (derived from wildcard " + wildcard + ")"); return false; } @@ -745,16 +745,16 @@ public class NSEC3ValUtils { /** * Prove that a DS response either had no DS, or wasn't a delegation point. - * + * * Fundamentally there are two cases here: normal NODATA and Opt-In NODATA. - * + * * @param nsec3s * The NSEC3 RRs to examine. * @param qname * The name of the DS in question. * @param zonename * The name of the zone that the NSEC3 RRs come from. - * + * * @return SecurityStatus.SECURE if it was proven that there is no DS in a * secure (i.e., not opt-in) way, SecurityStatus.INSECURE if there * was no DS in an insecure (i.e., opt-in) way, @@ -763,7 +763,7 @@ public class NSEC3ValUtils { * work out. */ public static byte proveNoDS(List nsec3s, Name qname, - Name zonename) { + Name zonename) { if ((nsec3s == null) || (nsec3s.size() == 0)) { return SecurityStatus.BOGUS; } @@ -771,8 +771,8 @@ public class NSEC3ValUtils { NSEC3Parameters nsec3params = nsec3Parameters(nsec3s); if (nsec3params == null) { - st_log.debug("couldn't find a single set of " + - "NSEC3 parameters (multiple parameters present)."); + st_log.debug("couldn't find a single set of " + + "NSEC3 parameters (multiple parameters present)."); return SecurityStatus.BOGUS; } @@ -824,18 +824,18 @@ public class NSEC3ValUtils { * algorithm, iterations, and salt. */ private static class NSEC3Parameters { - public int alg; - public byte [] salt; - public int iterations; + public int alg; + public byte[] salt; + public int iterations; private NSEC3PARAMRecord nsec3paramrec; public NSEC3Parameters(NSEC3Record r) { - alg = r.getHashAlgorithm(); - salt = r.getSalt(); - iterations = r.getIterations(); + alg = r.getHashAlgorithm(); + salt = r.getSalt(); + iterations = r.getIterations(); - nsec3paramrec = new NSEC3PARAMRecord(Name.root, DClass.IN, 0, - alg, 0, iterations, salt); + nsec3paramrec = new NSEC3PARAMRecord(Name.root, DClass.IN, 0, alg, + 0, iterations, salt); } public boolean match(NSEC3Record r, ByteArrayComparator bac) { @@ -872,13 +872,13 @@ public class NSEC3ValUtils { * encloser proof. */ private static class CEResponse { - public Name closestEncloser; + public Name closestEncloser; public NSEC3Record ce_nsec3; public NSEC3Record nc_nsec3; public CEResponse(Name ce, NSEC3Record nsec3) { - this.closestEncloser = ce; - this.ce_nsec3 = nsec3; + this.closestEncloser = ce; + this.ce_nsec3 = nsec3; } } } diff --git a/src/com/verisign/tat/dnssec/SMessage.java b/src/com/verisign/tat/dnssec/SMessage.java index d1e9a98..9d8d4bf 100644 --- a/src/com/verisign/tat/dnssec/SMessage.java +++ b/src/com/verisign/tat/dnssec/SMessage.java @@ -27,23 +27,22 @@ import org.xbill.DNS.*; import java.util.*; - /** * This class represents a DNS message with resolver/validator state. */ public class SMessage { - private static SRRset [] empty_srrset_array = new SRRset[0]; - private Header mHeader; - private Record mQuestion; - private OPTRecord mOPTRecord; - private List [] mSection; - private SecurityStatus mSecurityStatus; + private static SRRset[] empty_srrset_array = new SRRset[0]; + private Header mHeader; + private Record mQuestion; + private OPTRecord mOPTRecord; + private List[] mSection; + private SecurityStatus mSecurityStatus; @SuppressWarnings("unchecked") public SMessage(Header h) { - mSection = (List []) new List[3]; - mHeader = h; - mSecurityStatus = new SecurityStatus(); + mSection = (List[]) new List[3]; + mHeader = h; + mSecurityStatus = new SecurityStatus(); } public SMessage(int id) { @@ -56,11 +55,11 @@ public class SMessage { public SMessage(Message m) { this(m.getHeader()); - mQuestion = m.getQuestion(); - mOPTRecord = m.getOPT(); + mQuestion = m.getQuestion(); + mOPTRecord = m.getOPT(); for (int i = Section.ANSWER; i <= Section.ADDITIONAL; i++) { - RRset [] rrsets = m.getSectionRRsets(i); + RRset[] rrsets = m.getSectionRRsets(i); for (int j = 0; j < rrsets.length; j++) { addRRset(rrsets[j], i); @@ -151,13 +150,13 @@ public class SMessage { sectionList.addAll(0, rrsets); } - public SRRset [] getSectionRRsets(int section) { + public SRRset[] getSectionRRsets(int section) { List slist = getSectionList(section); - return (SRRset []) slist.toArray(empty_srrset_array); + return (SRRset[]) slist.toArray(empty_srrset_array); } - public SRRset [] getSectionRRsets(int section, int qtype) { + public SRRset[] getSectionRRsets(int section, int qtype) { List slist = getSectionList(section); if (slist.size() == 0) { @@ -172,7 +171,7 @@ public class SMessage { } } - return (SRRset []) result.toArray(empty_srrset_array); + return (SRRset[]) result.toArray(empty_srrset_array); } public void deleteRRset(SRRset rrset, int section) { @@ -314,7 +313,7 @@ public class SMessage { /** * Find a specific (S)RRset in a given section. - * + * * @param name * the name of the RRset. * @param type @@ -323,7 +322,7 @@ public class SMessage { * the class of the RRset. * @param section * the section to look in (ANSWER -> ADDITIONAL) - * + * * @return The SRRset if found, null otherwise. */ public SRRset findRRset(Name name, int type, int dclass, int section) { @@ -331,12 +330,12 @@ public class SMessage { throw new IllegalArgumentException("Invalid section."); } - SRRset [] rrsets = getSectionRRsets(section); + SRRset[] rrsets = getSectionRRsets(section); for (int i = 0; i < rrsets.length; i++) { - if (rrsets[i].getName().equals(name) && - (rrsets[i].getType() == type) && - (rrsets[i].getDClass() == dclass)) { + if (rrsets[i].getName().equals(name) + && (rrsets[i].getType() == type) + && (rrsets[i].getDClass() == dclass)) { return rrsets[i]; } } @@ -347,32 +346,32 @@ public class SMessage { /** * Find an "answer" RRset. This will look for RRsets in the ANSWER section * that match the , taking into consideration CNAMEs. - * + * * @param qname * The starting search name. * @param qtype * The search type. * @param qclass * The search class. - * + * * @return a SRRset matching the query. This SRRset may have a different * name from qname, due to following a CNAME chain. */ public SRRset findAnswerRRset(Name qname, int qtype, int qclass) { - SRRset [] srrsets = getSectionRRsets(Section.ANSWER); + SRRset[] srrsets = getSectionRRsets(Section.ANSWER); for (int i = 0; i < srrsets.length; i++) { - if (srrsets[i].getName().equals(qname) && - (srrsets[i].getType() == Type.CNAME)) { + if (srrsets[i].getName().equals(qname) + && (srrsets[i].getType() == Type.CNAME)) { CNAMERecord cname = (CNAMERecord) srrsets[i].first(); qname = cname.getTarget(); continue; } - if (srrsets[i].getName().equals(qname) && - (srrsets[i].getType() == qtype) && - (srrsets[i].getDClass() == qclass)) { + if (srrsets[i].getName().equals(qname) + && (srrsets[i].getType() == qtype) + && (srrsets[i].getDClass() == qclass)) { return srrsets[i]; } } diff --git a/src/com/verisign/tat/dnssec/SRRset.java b/src/com/verisign/tat/dnssec/SRRset.java index ab1c66e..25fff0c 100644 --- a/src/com/verisign/tat/dnssec/SRRset.java +++ b/src/com/verisign/tat/dnssec/SRRset.java @@ -27,7 +27,6 @@ import org.xbill.DNS.*; import java.util.*; - /** * A version of the RRset class overrides the standard security status. */ diff --git a/src/com/verisign/tat/dnssec/SecurityStatus.java b/src/com/verisign/tat/dnssec/SecurityStatus.java index 08617b2..a2f1e01 100644 --- a/src/com/verisign/tat/dnssec/SecurityStatus.java +++ b/src/com/verisign/tat/dnssec/SecurityStatus.java @@ -23,10 +23,9 @@ package com.verisign.tat.dnssec; - /** * Codes for DNSSEC security statuses. - * + * * @author davidb */ public class SecurityStatus { @@ -70,7 +69,7 @@ public class SecurityStatus { private byte status; public SecurityStatus() { - status = UNCHECKED; + status = UNCHECKED; } public SecurityStatus(byte status) { @@ -79,26 +78,26 @@ public class SecurityStatus { public static String string(int status) { switch (status) { - case INVALID: - return "Invalid"; + case INVALID: + return "Invalid"; - case BOGUS: - return "Bogus"; + case BOGUS: + return "Bogus"; - case SECURE: - return "Secure"; + case SECURE: + return "Secure"; - case INSECURE: - return "Insecure"; + case INSECURE: + return "Insecure"; - case INDETERMINATE: - return "Indeterminate"; + case INDETERMINATE: + return "Indeterminate"; - case UNCHECKED: - return "Unchecked"; + case UNCHECKED: + return "Unchecked"; - default: - return "UNKNOWN"; + default: + return "UNKNOWN"; } } diff --git a/src/com/verisign/tat/dnssec/SignUtils.java b/src/com/verisign/tat/dnssec/SignUtils.java index eb2cfdd..36a218d 100644 --- a/src/com/verisign/tat/dnssec/SignUtils.java +++ b/src/com/verisign/tat/dnssec/SignUtils.java @@ -46,25 +46,24 @@ import java.util.Comparator; import java.util.Date; import java.util.Iterator; - /** * This class contains a bunch of utility methods that are generally useful in * signing and verifying rrsets. */ public class SignUtils { // private static final int DSA_SIGNATURE_LENGTH = 20; - private static final int ASN1_INT = 0x02; - private static final int ASN1_SEQ = 0x30; - public static final int RR_NORMAL = 0; - public static final int RR_DELEGATION = 1; - public static final int RR_GLUE = 2; - public static final int RR_INVALID = 3; - private static Logger log = Logger.getLogger(SignUtils.class); + private static final int ASN1_INT = 0x02; + private static final int ASN1_SEQ = 0x30; + public static final int RR_NORMAL = 0; + public static final int RR_DELEGATION = 1; + public static final int RR_GLUE = 2; + public static final int RR_INVALID = 3; + private static Logger log = Logger.getLogger(SignUtils.class); /** * Generate from some basic information a prototype SIG RR containing * everything but the actual signature itself. - * + * * @param rrset * the RRset being signed. * @param signer @@ -82,16 +81,16 @@ public class SignUtils { * @return a prototype signature based on the RRset and key information. */ public static RRSIGRecord generatePreRRSIG(RRset rrset, Name signer, - int alg, int keyid, Date start, Date expire, long sig_ttl) { + int alg, int keyid, Date start, Date expire, long sig_ttl) { return new RRSIGRecord(rrset.getName(), rrset.getDClass(), sig_ttl, - rrset.getType(), alg, rrset.getTTL(), expire, start, keyid, signer, - null); + rrset.getType(), alg, rrset.getTTL(), expire, start, keyid, + signer, null); } /** * Generate from some basic information a prototype SIG RR containing * everything but the actual signature itself. - * + * * @param rrset * the RRset being signed. * @param key @@ -106,15 +105,15 @@ public class SignUtils { * @return a prototype signature based on the RRset and key information. */ public static RRSIGRecord generatePreRRSIG(RRset rrset, DNSKEYRecord key, - Date start, Date expire, long sig_ttl) { - return generatePreRRSIG(rrset, key.getName(), key.getAlgorithm(), - key.getFootprint(), start, expire, sig_ttl); + Date start, Date expire, long sig_ttl) { + return generatePreRRSIG(rrset, key.getName(), key.getAlgorithm(), key + .getFootprint(), start, expire, sig_ttl); } /** * Generate from some basic information a prototype SIG RR containing * everything but the actual signature itself. - * + * * @param rec * the DNS record being signed (forming an entire RRset). * @param key @@ -128,28 +127,28 @@ public class SignUtils { * @return a prototype signature based on the Record and key information. */ public static RRSIGRecord generatePreRRSIG(Record rec, DNSKEYRecord key, - Date start, Date expire, long sig_ttl) { - return new RRSIGRecord(rec.getName(), rec.getDClass(), sig_ttl, - rec.getType(), key.getAlgorithm(), rec.getTTL(), expire, start, - key.getFootprint(), key.getName(), null); + Date start, Date expire, long sig_ttl) { + return new RRSIGRecord(rec.getName(), rec.getDClass(), sig_ttl, rec + .getType(), key.getAlgorithm(), rec.getTTL(), expire, start, + key.getFootprint(), key.getName(), null); } /** * Generate the binary image of the prototype SIG RR. - * + * * @param presig * the SIG RR prototype. * @return the RDATA portion of the prototype SIG record. This forms the * first part of the data to be signed. */ - private static byte [] generatePreSigRdata(RRSIGRecord presig) { + private static byte[] generatePreSigRdata(RRSIGRecord presig) { // Generate the binary image; DNSOutput image = new DNSOutput(); // precalculate some things - int start_time = (int) (presig.getTimeSigned().getTime() / 1000); - int expire_time = (int) (presig.getExpire().getTime() / 1000); - Name signer = presig.getSigner(); + int start_time = (int) (presig.getTimeSigned().getTime() / 1000); + int expire_time = (int) (presig.getExpire().getTime() / 1000); + Name signer = presig.getSigner(); // first write out the partial SIG record (this is the SIG RDATA // minus the actual signature. @@ -167,7 +166,7 @@ public class SignUtils { /** * Calculate the canonical wire line format of the RRset. - * + * * @param rrset * the RRset to convert. * @param ttl @@ -180,8 +179,8 @@ public class SignUtils { * part of data to be signed. */ @SuppressWarnings("unchecked") - public static byte [] generateCanonicalRRsetData(RRset rrset, long ttl, - int labels) { + public static byte[] generateCanonicalRRsetData(RRset rrset, long ttl, + int labels) { DNSOutput image = new DNSOutput(); if (ttl == 0) { @@ -200,15 +199,15 @@ public class SignUtils { boolean wildcardName = false; if (n.labels() != labels) { - n = n.wild(n.labels() - labels); - wildcardName = true; - log.trace("Detected wildcard expansion: " + rrset.getName() + - " changed to " + n); + n = n.wild(n.labels() - labels); + wildcardName = true; + log.trace("Detected wildcard expansion: " + rrset.getName() + + " changed to " + n); } // now convert the wire format records in the RRset into a // list of byte arrays. - ArrayList canonical_rrs = new ArrayList(); + ArrayList canonical_rrs = new ArrayList(); for (Iterator i = rrset.rrs(); i.hasNext();) { Record r = (Record) i.next(); @@ -218,25 +217,24 @@ public class SignUtils { // or ownername. // In the TTL case, this avoids changing the ttl in the // response. - r = Record.newRecord(n, r.getType(), r.getDClass(), ttl, - r.rdataToWireCanonical()); + r = Record.newRecord(n, r.getType(), r.getDClass(), ttl, r + .rdataToWireCanonical()); } - byte [] wire_fmt = r.toWireCanonical(); + byte[] wire_fmt = r.toWireCanonical(); canonical_rrs.add(wire_fmt); } // put the records into the correct ordering. // Calculate the offset where the RDATA begins (we have to skip // past the length byte) - int offset = rrset.getName().toWireCanonical().length + - 10; - ByteArrayComparator bac = new ByteArrayComparator(offset, false); + int offset = rrset.getName().toWireCanonical().length + 10; + ByteArrayComparator bac = new ByteArrayComparator(offset, false); Collections.sort(canonical_rrs, bac); - for (Iterator i = canonical_rrs.iterator(); i.hasNext();) { - byte [] wire_fmt_rec = i.next(); + for (Iterator i = canonical_rrs.iterator(); i.hasNext();) { + byte[] wire_fmt_rec = i.next(); image.writeByteArray(wire_fmt_rec); } @@ -246,17 +244,17 @@ public class SignUtils { /** * Given an RRset and the prototype signature, generate the canonical data * that is to be signed. - * + * * @param rrset * the RRset to be signed. * @param presig * a prototype SIG RR created using the same RRset. * @return a block of data ready to be signed. */ - public static byte [] generateSigData(RRset rrset, RRSIGRecord presig) - throws IOException { - byte [] rrset_data = generateCanonicalRRsetData(rrset, - presig.getOrigTTL(), presig.getLabels()); + public static byte[] generateSigData(RRset rrset, RRSIGRecord presig) + throws IOException { + byte[] rrset_data = generateCanonicalRRsetData(rrset, presig + .getOrigTTL(), presig.getLabels()); return generateSigData(rrset_data, presig); } @@ -264,7 +262,7 @@ public class SignUtils { /** * Given an RRset and the prototype signature, generate the canonical data * that is to be signed. - * + * * @param rrset_data * the RRset converted into canonical wire line format (as per * the canonicalization rules in RFC 2535). @@ -273,12 +271,12 @@ public class SignUtils { * rrset_data. * @return a block of data ready to be signed. */ - public static byte [] generateSigData(byte [] rrset_data, RRSIGRecord presig) - throws IOException { - byte [] sig_rdata = generatePreSigRdata(presig); + public static byte[] generateSigData(byte[] rrset_data, RRSIGRecord presig) + throws IOException { + byte[] sig_rdata = generatePreSigRdata(presig); - ByteArrayOutputStream image = new ByteArrayOutputStream(sig_rdata.length + - rrset_data.length); + ByteArrayOutputStream image = new ByteArrayOutputStream( + sig_rdata.length + rrset_data.length); image.write(sig_rdata); image.write(rrset_data); @@ -289,33 +287,33 @@ public class SignUtils { /** * Given the actual signature and the prototype signature, combine them and * return the fully formed RRSIGRecord. - * + * * @param signature * the cryptographic signature, in DNSSEC format. * @param presig * the prototype RRSIG RR to add the signature to. * @return the fully formed RRSIG RR. */ - public static RRSIGRecord generateRRSIG(byte [] signature, - RRSIGRecord presig) { - return new RRSIGRecord(presig.getName(), presig.getDClass(), - presig.getTTL(), presig.getTypeCovered(), presig.getAlgorithm(), - presig.getOrigTTL(), presig.getExpire(), presig.getTimeSigned(), - presig.getFootprint(), presig.getSigner(), signature); + public static RRSIGRecord generateRRSIG(byte[] signature, RRSIGRecord presig) { + return new RRSIGRecord(presig.getName(), presig.getDClass(), presig + .getTTL(), presig.getTypeCovered(), presig.getAlgorithm(), + presig.getOrigTTL(), presig.getExpire(), + presig.getTimeSigned(), presig.getFootprint(), presig + .getSigner(), signature); } /** * Converts from a RFC 2536 formatted DSA signature to a JCE (ASN.1) * formatted signature. - * + * *

* ASN.1 format = ASN1_SEQ . seq_length . ASN1_INT . Rlength . R . ANS1_INT * . Slength . S *

- * + * * The integers R and S may have a leading null byte to force the integer * positive. - * + * * @param signature * the RFC 2536 formatted DSA signature. * @return The ASN.1 formatted DSA signature. @@ -323,11 +321,11 @@ public class SignUtils { * if there was something wrong with the RFC 2536 formatted * signature. */ - public static byte [] convertDSASignature(byte [] signature) - throws SignatureException { + public static byte[] convertDSASignature(byte[] signature) + throws SignatureException { if (signature.length != 41) { throw new SignatureException( - "RFC 2536 signature not expected length."); + "RFC 2536 signature not expected length."); } byte r_pad = 0; @@ -345,15 +343,15 @@ public class SignUtils { // ASN.1 length = R length + S length + (2 + 2 + 2), where each 2 // is for a ASN.1 type-length byte pair of which there are three // (SEQ, INT, INT). - byte sig_length = (byte) (40 + r_pad + s_pad + 6); + byte sig_length = (byte) (40 + r_pad + s_pad + 6); - byte [] sig = new byte[sig_length]; - byte pos = 0; + byte[] sig = new byte[sig_length]; + byte pos = 0; - sig[pos++] = ASN1_SEQ; - sig[pos++] = (byte) (sig_length - 2); // all but the SEQ type+length. - sig[pos++] = ASN1_INT; - sig[pos++] = (byte) (20 + r_pad); + sig[pos++] = ASN1_SEQ; + sig[pos++] = (byte) (sig_length - 2); // all but the SEQ type+length. + sig[pos++] = ASN1_INT; + sig[pos++] = (byte) (20 + r_pad); // copy the value of R, leaving a null byte if necessary if (r_pad == 1) { @@ -363,8 +361,8 @@ public class SignUtils { System.arraycopy(signature, 1, sig, pos, 20); pos += 20; - sig[pos++] = ASN1_INT; - sig[pos++] = (byte) (20 + s_pad); + sig[pos++] = ASN1_INT; + sig[pos++] = (byte) (20 + s_pad); // copy the value of S, leaving a null byte if necessary if (s_pad == 1) { @@ -379,15 +377,15 @@ public class SignUtils { /** * Converts from a JCE (ASN.1) formatted DSA signature to a RFC 2536 * compliant signature. - * + * *

* rfc2536 format = T . R . S *

- * + * * where T is a number between 0 and 8, which is based on the DSA key * length, and R & S are formatted to be exactly 20 bytes each (no leading * null bytes). - * + * * @param params * the DSA parameters associated with the DSA key used to * generate the signature. @@ -397,25 +395,25 @@ public class SignUtils { * @throws SignatureException * if something is wrong with the ASN.1 format. */ - public static byte [] convertDSASignature(DSAParams params, - byte [] signature) throws SignatureException { + public static byte[] convertDSASignature(DSAParams params, byte[] signature) + throws SignatureException { if ((signature[0] != ASN1_SEQ) || (signature[2] != ASN1_INT)) { throw new SignatureException( - "Invalid ASN.1 signature format: expected SEQ, INT"); + "Invalid ASN.1 signature format: expected SEQ, INT"); } byte r_pad = (byte) (signature[3] - 20); if (signature[24 + r_pad] != ASN1_INT) { throw new SignatureException( - "Invalid ASN.1 signature format: expected SEQ, INT, INT"); + "Invalid ASN.1 signature format: expected SEQ, INT, INT"); } log.trace("(start) ASN.1 DSA Sig:\n" + base64.toString(signature)); - byte s_pad = (byte) (signature[25 + r_pad] - 20); + byte s_pad = (byte) (signature[25 + r_pad] - 20); - byte [] sig = new byte[41]; // all rfc2536 signatures are 41 bytes. + byte[] sig = new byte[41]; // all rfc2536 signatures are 41 bytes. // Calculate T: sig[0] = (byte) ((params.getP().bitLength() - 512) / 64); @@ -437,13 +435,15 @@ public class SignUtils { // S is shorter than 20 bytes, so right justify the number // (s_pad is negative here). Arrays.fill(sig, 21, 21 - s_pad, (byte) 0); - System.arraycopy(signature, 26 + r_pad, sig, 21 - s_pad, 20 + - s_pad); + System + .arraycopy(signature, 26 + r_pad, sig, 21 - s_pad, + 20 + s_pad); } if ((r_pad < 0) || (s_pad < 0)) { - log.trace("(finish ***) RFC 2536 DSA Sig:\n" + - base64.toString(sig)); + log + .trace("(finish ***) RFC 2536 DSA Sig:\n" + + base64.toString(sig)); } else { log.trace("(finish) RFC 2536 DSA Sig:\n" + base64.toString(sig)); } @@ -456,24 +456,26 @@ public class SignUtils { * useful for comparing RDATA portions of DNS records in doing DNSSEC * canonical ordering. */ - public static class ByteArrayComparator implements Comparator { - private int mOffset = 0; - private boolean mDebug = false; + public static class ByteArrayComparator implements Comparator { + private int mOffset = 0; + private boolean mDebug = false; - public ByteArrayComparator() {} - - public ByteArrayComparator(int offset, boolean debug) { - mOffset = offset; - mDebug = debug; + public ByteArrayComparator() { } - public int compare(byte [] b1, byte [] b2) throws ClassCastException { + public ByteArrayComparator(int offset, boolean debug) { + mOffset = offset; + mDebug = debug; + } + + public int compare(byte[] b1, byte[] b2) throws ClassCastException { for (int i = mOffset; (i < b1.length) && (i < b2.length); i++) { if (b1[i] != b2[i]) { if (mDebug) { - System.out.println("offset " + i + - " differs (this is " + (i - mOffset) + - " bytes in from our offset.)"); + System.out + .println("offset " + i + " differs (this is " + + (i - mOffset) + + " bytes in from our offset.)"); } return (b1[i] & 0xFF) - (b2[i] & 0xFF); diff --git a/src/com/verisign/tat/dnssec/TrustAnchorStore.java b/src/com/verisign/tat/dnssec/TrustAnchorStore.java index a635f5c..9e30fb9 100644 --- a/src/com/verisign/tat/dnssec/TrustAnchorStore.java +++ b/src/com/verisign/tat/dnssec/TrustAnchorStore.java @@ -27,7 +27,6 @@ import org.xbill.DNS.*; import java.util.*; - /** * */ @@ -89,10 +88,10 @@ public class TrustAnchorStore { for (Map.Entry entry : mMap.entrySet()) { for (Iterator i = entry.getValue().rrs(); i.hasNext();) { - DNSKEYRecord r = (DNSKEYRecord) i.next(); - String key_desc = r.getName().toString() + "/" + - DNSSEC.Algorithm.string(r.getAlgorithm()) + "/" + - r.getFootprint(); + DNSKEYRecord r = (DNSKEYRecord) i.next(); + String key_desc = r.getName().toString() + "/" + + DNSSEC.Algorithm.string(r.getAlgorithm()) + "/" + + r.getFootprint(); res.add(key_desc); } } diff --git a/src/com/verisign/tat/dnssec/Util.java b/src/com/verisign/tat/dnssec/Util.java index 40890fb..2910390 100644 --- a/src/com/verisign/tat/dnssec/Util.java +++ b/src/com/verisign/tat/dnssec/Util.java @@ -27,15 +27,15 @@ import org.xbill.DNS.Name; import java.util.*; - /** * Some basic utility functions. */ public class Util { /** * Convert a DNS name into a string suitable for use as a cache key. - * - * @param name The name to convert. + * + * @param name + * The name to convert. * @return A string representing the name. This isn't ever meant to be * converted back into a DNS name. */ @@ -78,7 +78,7 @@ public class Util { } public static List parseConfigPrefix(Properties config, - String prefix) { + String prefix) { if (!prefix.endsWith(".")) { prefix = prefix + "."; } @@ -102,8 +102,8 @@ public class Util { public String value; public ConfigEntry(String key, String value) { - this.key = key; - this.value = value; + this.key = key; + this.value = value; } } } diff --git a/src/com/verisign/tat/dnssec/ValUtils.java b/src/com/verisign/tat/dnssec/ValUtils.java index 5d05e98..80dc0b7 100644 --- a/src/com/verisign/tat/dnssec/ValUtils.java +++ b/src/com/verisign/tat/dnssec/ValUtils.java @@ -32,14 +32,13 @@ import java.security.NoSuchAlgorithmException; import java.util.Iterator; - /** * This is a collection of routines encompassing the logic of validating * different message types. */ public class ValUtils { private static Logger st_log = Logger.getLogger(ValUtils.class); - private Logger log = Logger.getLogger(this.getClass()); + private Logger log = Logger.getLogger(this.getClass()); /** A local copy of the verifier object. */ private DnsSecVerifier mVerifier; @@ -50,19 +49,19 @@ public class ValUtils { /** * Given a response, classify ANSWER responses into a subtype. - * + * * @param m * The response to classify. - * + * * @return A subtype ranging from UNKNOWN to NAMEERROR. */ public static ResponseType classifyResponse(SMessage m, Name zone) { - SRRset [] rrsets; + SRRset[] rrsets; // Normal Name Error's are easy to detect -- but don't mistake a CNAME // chain ending in NXDOMAIN. - if ((m.getRcode() == Rcode.NXDOMAIN) && - (m.getCount(Section.ANSWER) == 0)) { + if ((m.getRcode() == Rcode.NXDOMAIN) + && (m.getCount(Section.ANSWER) == 0)) { return ResponseType.NAMEERROR; } @@ -75,13 +74,13 @@ public class ValUtils { // 1) nothing in the ANSWER section // 2) an NS RRset in the AUTHORITY section that is a strict subdomain of // 'zone' (the presumed queried zone). - if ((zone != null) && (m.getCount(Section.ANSWER) == 0) && - (m.getCount(Section.AUTHORITY) > 0)) { + if ((zone != null) && (m.getCount(Section.ANSWER) == 0) + && (m.getCount(Section.AUTHORITY) > 0)) { rrsets = m.getSectionRRsets(Section.AUTHORITY); for (int i = 0; i < rrsets.length; ++i) { - if ((rrsets[i].getType() == Type.NS) && - strictSubdomain(rrsets[i].getName(), zone)) { + if ((rrsets[i].getType() == Type.NS) + && strictSubdomain(rrsets[i].getName(), zone)) { return ResponseType.REFERRAL; } } @@ -125,7 +124,7 @@ public class ValUtils { * Given a response, determine the name of the "signer". This is primarily * to determine if the response is, in fact, signed at all, and, if so, what * is the name of the most pertinent keyset. - * + * * @param m * The response to analyze. * @return a signer name, if the response is signed (even partially), or @@ -135,9 +134,8 @@ public class ValUtils { // FIXME: this used to classify the message, then look in the pertinent // section. Now we just find the first RRSIG in the ANSWER and AUTHORIY // sections. - for (int section = Section.ANSWER; section < Section.ADDITIONAL; - ++section) { - SRRset [] rrsets = m.getSectionRRsets(section); + for (int section = Section.ANSWER; section < Section.ADDITIONAL; ++section) { + SRRset[] rrsets = m.getSectionRRsets(section); for (int i = 0; i < rrsets.length; ++i) { Name signerName = rrsets[i].getSignerName(); @@ -153,14 +151,14 @@ public class ValUtils { /** * Given a DNSKEY record, generate the DS record from it. - * + * * @param keyrec * the DNSKEY record in question. * @param ds_alg * The DS digest algorithm in use. * @return the corresponding {@link org.xbill.DNS.DSRecord} */ - public static byte [] calculateDSHash(DNSKEYRecord keyrec, int ds_alg) { + public static byte[] calculateDSHash(DNSKEYRecord keyrec, int ds_alg) { DNSOutput os = new DNSOutput(); os.writeByteArray(keyrec.getName().toWireCanonical()); @@ -170,20 +168,20 @@ public class ValUtils { MessageDigest md = null; switch (ds_alg) { - case DSRecord.SHA1_DIGEST_ID: - md = MessageDigest.getInstance("SHA"); + case DSRecord.SHA1_DIGEST_ID: + md = MessageDigest.getInstance("SHA"); - return md.digest(os.toByteArray()); + return md.digest(os.toByteArray()); - case DSRecord.SHA256_DIGEST_ID: - md = MessageDigest.getInstance("SHA256"); + case DSRecord.SHA256_DIGEST_ID: + md = MessageDigest.getInstance("SHA256"); - return md.digest(os.toByteArray()); + return md.digest(os.toByteArray()); - default: - st_log.warn("Unknown DS algorithm: " + ds_alg); + default: + st_log.warn("Unknown DS algorithm: " + ds_alg); - return null; + return null; } } catch (NoSuchAlgorithmException e) { st_log.error("Error using DS algorithm: " + ds_alg, e); @@ -206,30 +204,30 @@ public class ValUtils { /** * Check to see if a type is a special DNSSEC type. - * + * * @param type * The type. - * + * * @return true if the type is one of the special DNSSEC types. */ public static boolean isDNSSECType(int type) { switch (type) { - case Type.DNSKEY: - case Type.NSEC: - case Type.DS: - case Type.RRSIG: - case Type.NSEC3: - return true; + case Type.DNSKEY: + case Type.NSEC: + case Type.DS: + case Type.RRSIG: + case Type.NSEC3: + return true; - default: - return false; + default: + return false; } } /** * Set the security status of a particular RRset. This will only upgrade the * security status. - * + * * @param rrset * The SRRset to update. * @param security @@ -251,14 +249,14 @@ public class ValUtils { * Set the security status of a message and all of its RRsets. This will * only upgrade the status of the message (i.e., set to more secure, not * less) and all of the RRsets. - * + * * @param m * @param security * KeyEntry ke; - * + * * SMessage m = response.getSMessage(); SRRset ans_rrset = * m.findAnswerRRset(qname, qtype, qclass); - * + * * ke = verifySRRset(ans_rrset, key_rrset); if * (ans_rrset.getSecurityStatus() != SecurityStatus.SECURE) { * return; } key_rrset = ke.getRRset(); @@ -274,9 +272,8 @@ public class ValUtils { m.setStatus(security); } - for (int section = Section.ANSWER; section <= Section.ADDITIONAL; - section++) { - SRRset [] rrsets = m.getSectionRRsets(section); + for (int section = Section.ANSWER; section <= Section.ADDITIONAL; section++) { + SRRset[] rrsets = m.getSectionRRsets(section); for (int i = 0; i < rrsets.length; i++) { setRRsetSecurity(rrsets[i], security); @@ -288,7 +285,7 @@ public class ValUtils { * Given an SRRset that is signed by a DNSKEY found in the key_rrset, verify * it. This will return the status (either BOGUS or SECURE) and set that * status in rrset. - * + * * @param rrset * The SRRset to verify. * @param key_rrset @@ -296,13 +293,13 @@ public class ValUtils { * @return The status (BOGUS or SECURE). */ public byte verifySRRset(SRRset rrset, SRRset key_rrset) { - String rrset_name = rrset.getName() + "/" + - Type.string(rrset.getType()) + "/" + - DClass.string(rrset.getDClass()); + String rrset_name = rrset.getName() + "/" + + Type.string(rrset.getType()) + "/" + + DClass.string(rrset.getDClass()); if (rrset.getSecurityStatus() == SecurityStatus.SECURE) { - log.trace("verifySRRset: rrset <" + rrset_name + - "> previously found to be SECURE"); + log.trace("verifySRRset: rrset <" + rrset_name + + "> previously found to be SECURE"); return SecurityStatus.SECURE; } @@ -310,12 +307,12 @@ public class ValUtils { byte status = mVerifier.verify(rrset, key_rrset); if (status != SecurityStatus.SECURE) { - log.debug("verifySRRset: rrset <" + rrset_name + - "> found to be BAD"); + log.debug("verifySRRset: rrset <" + rrset_name + + "> found to be BAD"); status = SecurityStatus.BOGUS; } else { - log.trace("verifySRRset: rrset <" + rrset_name + - "> found to be SECURE"); + log.trace("verifySRRset: rrset <" + rrset_name + + "> found to be SECURE"); } rrset.setSecurityStatus(status); @@ -325,14 +322,14 @@ public class ValUtils { /** * Determine if a given type map has a given type. - * + * * @param types * The type map from the NSEC record. * @param type * The type to look for. * @return true if the type is present in the type map, false otherwise. */ - public static boolean typeMapHasType(int [] types, int type) { + public static boolean typeMapHasType(int[] types, int type) { for (int i = 0; i < types.length; i++) { if (types[i] == type) { return true; @@ -353,7 +350,7 @@ public class ValUtils { /** * Finds the longest common name between two domain names. - * + * * @param domain1 * @param domain2 * @return @@ -368,7 +365,7 @@ public class ValUtils { int d1_labels = domain1.labels(); int d2_labels = domain2.labels(); - int l = (d1_labels < d2_labels) ? d1_labels : d2_labels; + int l = (d1_labels < d2_labels) ? d1_labels : d2_labels; for (int i = l; i > 0; i--) { Name n1 = new Name(domain1, d1_labels - i); @@ -398,7 +395,7 @@ public class ValUtils { /** * Determine by looking at a signed RRset whether or not the rrset name was * the result of a wildcard expansion. - * + * * @param rrset * The rrset to examine. * @return true if the rrset is a wildcard expansion. This will return false @@ -422,7 +419,7 @@ public class ValUtils { * Determine by looking at a signed RRset whether or not the RRset name was * the result of a wildcard expansion. If so, return the name of the * generating wildcard. - * + * * @param rrset * The rrset to check. * @return the wildcard name, if the rrset was synthesized from a wildcard. @@ -466,7 +463,7 @@ public class ValUtils { /** * Determine if the given NSEC proves a NameError (NXDOMAIN) for a given * qname. - * + * * @param nsec * The NSEC to check. * @param qname @@ -478,9 +475,9 @@ public class ValUtils { * @return true if the NSEC proves the condition. */ public static boolean nsecProvesNameError(NSECRecord nsec, Name qname, - Name signerName) { + Name signerName) { Name owner = nsec.getName(); - Name next = nsec.getNext(); + Name next = nsec.getNext(); // If NSEC owner == qname, then this NSEC proves that qname exists. if (qname.equals(owner)) { @@ -490,16 +487,16 @@ public class ValUtils { // If NSEC is a parent of qname, we need to check the type map // If the parent name has a DNAME or is a delegation point, then this // NSEC is being misused. - boolean hasBadType = typeMapHasType(nsec.getTypes(), Type.DNAME) || - (typeMapHasType(nsec.getTypes(), Type.NS) && - !typeMapHasType(nsec.getTypes(), Type.SOA)); + boolean hasBadType = typeMapHasType(nsec.getTypes(), Type.DNAME) + || (typeMapHasType(nsec.getTypes(), Type.NS) && !typeMapHasType( + nsec.getTypes(), Type.SOA)); if (qname.subdomain(owner) && hasBadType) { return false; } - if (((qname.compareTo(owner) > 0) && (qname.compareTo(next) < 0)) || - signerName.equals(next)) { + if (((qname.compareTo(owner) > 0) && (qname.compareTo(next) < 0)) + || signerName.equals(next)) { return true; } @@ -509,7 +506,7 @@ public class ValUtils { /** * Determine if a NSEC record proves the non-existence of a wildcard that * could have produced qname. - * + * * @param nsec * The nsec to check. * @param qname @@ -519,18 +516,19 @@ public class ValUtils { * @return true if the NSEC proves the condition. */ public static boolean nsecProvesNoWC(NSECRecord nsec, Name qname, - Name signerName) { - Name owner = nsec.getName(); - Name next = nsec.getNext(); + Name signerName) { + Name owner = nsec.getName(); + Name next = nsec.getNext(); - int qname_labels = qname.labels(); - int signer_labels = signerName.labels(); + int qname_labels = qname.labels(); + int signer_labels = signerName.labels(); for (int i = qname_labels - signer_labels; i > 0; i--) { Name wc_name = qname.wild(i); - if ((wc_name.compareTo(owner) > 0) && - ((wc_name.compareTo(next) < 0) || signerName.equals(next))) { + if ((wc_name.compareTo(owner) > 0) + && ((wc_name.compareTo(next) < 0) || signerName + .equals(next))) { return true; } } @@ -544,7 +542,7 @@ public class ValUtils { * wildcard case. If the ownername of 'nsec' is a wildcard, the validator * must still be provided proof that qname did not directly exist and that * the wildcard is, in fact, *.closest_encloser. - * + * * @param nsec * The NSEC to check * @param qname @@ -554,7 +552,7 @@ public class ValUtils { * @return true if the NSEC proves the condition. */ public static boolean nsecProvesNodata(NSECRecord nsec, Name qname, - int qtype) { + int qtype) { if (!nsec.getName().equals(qname)) { // wildcard checking. @@ -571,8 +569,8 @@ public class ValUtils { // The qname must be a strict subdomain of the closest encloser, // and // the qtype must be absent from the type map. - if (!strictSubdomain(qname, ce) || - typeMapHasType(nsec.getTypes(), qtype)) { + if (!strictSubdomain(qname, ce) + || typeMapHasType(nsec.getTypes(), qtype)) { return false; } @@ -585,8 +583,8 @@ public class ValUtils { // be // less than qname, and the next name will be a child domain of the // qname. - if (strictSubdomain(nsec.getNext(), qname) && - (qname.compareTo(nsec.getName()) > 0)) { + if (strictSubdomain(nsec.getNext(), qname) + && (qname.compareTo(nsec.getName()) > 0)) { return true; } @@ -610,8 +608,8 @@ public class ValUtils { // not a zone apex), then we should have gotten a referral (or we just // got // the wrong NSEC). - if (typeMapHasType(nsec.getTypes(), Type.NS) && - !typeMapHasType(nsec.getTypes(), Type.SOA)) { + if (typeMapHasType(nsec.getTypes(), Type.NS) + && !typeMapHasType(nsec.getTypes(), Type.SOA)) { return false; } @@ -620,7 +618,7 @@ public class ValUtils { public static byte nsecProvesNoDS(NSECRecord nsec, Name qname) { // Could check to make sure the qname is a subdomain of nsec - int [] types = nsec.getTypes(); + int[] types = nsec.getTypes(); if (typeMapHasType(types, Type.SOA) || typeMapHasType(types, Type.DS)) { // SOA present means that this is the NSEC from the child, not the @@ -644,8 +642,8 @@ public class ValUtils { // These are response subtypes. They are necessary for determining the // validation strategy. They have no bearing on the iterative resolution // algorithm, so they are confined here. - public enum ResponseType {UNTYPED, UNKNOWN, POSITIVE, CNAME, NODATA, - NAMEERROR, ANY, REFERRAL, + public enum ResponseType { + UNTYPED, UNKNOWN, POSITIVE, CNAME, NODATA, NAMEERROR, ANY, REFERRAL, // a referral response THROWAWAY; // a throwaway response (i.e., an error)