-/*
- * Copyright (c) 2009 VeriSign, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
+/***************************** -*- Java -*- ********************************\
+ * *
+ * Copyright (c) 2009 VeriSign, Inc. All rights reserved. *
+ * *
+ * This software is provided solely in connection with the terms of the *
+ * license agreement. Any other use without the prior express written *
+ * permission of VeriSign is completely prohibited. The software and *
+ * documentation are "Commercial Items", as that term is defined in 48 *
+ * C.F.R. section 2.101, consisting of "Commercial Computer Software" and *
+ * "Commercial Computer Software Documentation" as such terms are defined *
+ * in 48 C.F.R. section 252.227-7014(a)(5) and 48 C.F.R. section *
+ * 252.227-7014(a)(1), and used in 48 C.F.R. section 12.212 and 48 C.F.R. *
+ * section 227.7202, as applicable. Pursuant to the above and other *
+ * relevant sections of the Code of Federal Regulations, as applicable, *
+ * VeriSign's publications, commercial computer software, and commercial *
+ * computer software documentation are distributed and licensed to United *
+ * States Government end users with only those rights as granted to all *
+ * other end users, according to the terms and conditions contained in the *
+ * license agreement(s) that accompany the products and software *
+ * documentation. *
+ * *
+\***************************************************************************/
+
+package com.verisign.tat.dnssec;
+
+import org.apache.log4j.Logger;
-package com.versign.tat.dnssec;
+import org.xbill.DNS.*;
+import org.xbill.DNS.security.*;
-import java.util.*;
import java.io.*;
-import java.security.*;
-import org.xbill.DNS.*;
-import org.xbill.DNS.security.*;
+import java.security.*;
-import com.versign.tat.dnssec.SecurityStatus;
-import com.versign.tat.dnssec.Util;
+import java.util.*;
/**
* contains a similar class. This is a re-implementation that allows us to have
* finer control over the validation process.
*/
-public class DnsSecVerifier
-{
- public static final int UNKNOWN = 0;
- public static final int RSA = 1;
- public static final int DSA = 2;
-
- /**
- * This is a mapping of DNSSEC algorithm numbers/private identifiers to JCA
- * algorithm identifiers.
- */
- private HashMap<Integer, AlgEntry> mAlgorithmMap;
-
- private static class AlgEntry
- {
- public String jcaName;
- public boolean isDSA;
- public int dnssecAlg;
-
- public AlgEntry(String name, int dnssecAlg, boolean isDSA)
- {
- jcaName = name;
- this.dnssecAlg = dnssecAlg;
- this.isDSA = isDSA;
- }
- }
-
- public DnsSecVerifier()
- {
- mAlgorithmMap = new HashMap<Integer, AlgEntry>();
-
- // 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));
- }
-
- private boolean isDSA(int algorithm)
- {
- // shortcut the standard algorithms
- if (algorithm == DNSSEC.DSA) return true;
- if (algorithm == DNSSEC.RSASHA1) return false;
- if (algorithm == DNSSEC.RSAMD5) return false;
-
- AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
- if (entry != null) return entry.isDSA;
- return false;
- }
-
- public void init(Properties config)
- {
- if (config == null) return;
-
- // Algorithm configuration
-
- // For now, we just accept new identifiers for existing algoirthms.
- // FIXME: handle private identifiers.
- List<Util.ConfigEntry> aliases = Util.parseConfigPrefix(config, "dns.algorithm.");
-
- 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));
-
- if (!mAlgorithmMap.containsKey(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");
- continue;
- }
-
- mAlgorithmMap.put(alg_alias, mAlgorithmMap.get(alg_orig));
+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());
+
+ /**
+ * This is a mapping of DNSSEC algorithm numbers/private identifiers to JCA
+ * algorithm identifiers.
+ */
+ private HashMap<Integer, AlgEntry> mAlgorithmMap;
+
+ public DnsSecVerifier() {
+ mAlgorithmMap = new HashMap<Integer, AlgEntry>();
+
+ // 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));
}
- // for debugging purposes, log the entire algorithm map table.
-// for (Integer alg : mAlgorithmMap.keySet()) {
-// AlgEntry entry = mAlgorithmMap.get(alg);
-// if (entry == null)
-// log.warn("DNSSEC alg " + alg + " has a null entry!");
-// else
-// log.debug("DNSSEC alg " + alg + " maps to " + entry.jcaName
-// + " (" + entry.dnssecAlg + ")");
-// }
- }
-
- /**
- * 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 The RRSIG to match against.
- * @return A List contains a one or more DNSKEYRecord objects, or null if a
- * matching DNSKEY could not be found.
- */
- @SuppressWarnings("unchecked")
-private List<DNSKEYRecord> 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());
- return null;
- }
+ private boolean isDSA(int algorithm) {
+ // shortcut the standard algorithms
+ if (algorithm == DNSSEC.DSA) {
+ return true;
+ }
- int keyid = signature.getFootprint();
- int alg = signature.getAlgorithm();
+ if (algorithm == DNSSEC.RSASHA1) {
+ return false;
+ }
- List<DNSKEYRecord> res = new ArrayList<DNSKEYRecord>(dnskey_rrset.size());
+ if (algorithm == DNSSEC.RSAMD5) {
+ return false;
+ }
- for (Iterator i = dnskey_rrset.rrs(); i.hasNext();)
- {
- DNSKEYRecord r = (DNSKEYRecord) i.next();
- if (r.getAlgorithm() == alg && r.getFootprint() == keyid)
- {
- res.add(r);
- }
- }
+ AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
- if (res.size() == 0)
- {
-// log.trace("findKey: could not find a key matching "
-// + "the algorithm and footprint in supplied keyset. ");
- return null;
- }
- return res;
- }
-
- /**
- * 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 The signature record to check.
- * @return A value of DNSSEC.Secure if it looks OK, DNSSEC.Faile if it looks
- * bad.
- */
- private byte checkSignature(RRset rrset, RRSIGRecord sigrec)
- {
- if (rrset == null || sigrec == null) return DNSSEC.Failed;
- if (!rrset.getName().equals(sigrec.getName()))
- {
-// log.debug("Signature name does not match RRset name");
- return SecurityStatus.BOGUS;
- }
- if (rrset.getType() != sigrec.getTypeCovered())
- {
-// log.debug("Signature type does not match RRset type");
- return SecurityStatus.BOGUS;
- }
+ if (entry != null) {
+ return entry.isDSA;
+ }
- Date now = new Date();
- Date start = sigrec.getTimeSigned();
- Date expire = sigrec.getExpire();
- if (now.before(start))
- {
-// log.debug("Signature is not yet valid");
- return SecurityStatus.BOGUS;
+ return false;
}
- if (now.after(expire))
- {
-// log.debug("Signature has expired (now = " + now + ", sig expires = "
-// + expire);
- return SecurityStatus.BOGUS;
+ public void init(Properties config) {
+ if (config == null) {
+ return;
+ }
+
+ // Algorithm configuration
+
+ // For now, we just accept new identifiers for existing algorithms.
+ // FIXME: handle private identifiers.
+ List<Util.ConfigEntry> aliases = Util.parseConfigPrefix(config,
+ "dns.algorithm.");
+
+ 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));
+
+ if (!mAlgorithmMap.containsKey(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");
+
+ continue;
+ }
+
+ mAlgorithmMap.put(alg_alias, mAlgorithmMap.get(alg_orig));
+ }
+
+ // for debugging purposes, log the entire algorithm map table.
+ for (Integer alg : mAlgorithmMap.keySet()) {
+ AlgEntry entry = mAlgorithmMap.get(alg);
+
+ if (entry == null) {
+ log.warn("DNSSEC alg " + alg + " has a null entry!");
+ } else {
+ log.debug("DNSSEC alg " + alg + " maps to " + entry.jcaName +
+ " (" + entry.dnssecAlg + ")");
+ }
+ }
}
- return SecurityStatus.SECURE;
- }
-
- public PublicKey parseDNSKEY(DNSKEYRecord key)
- {
- AlgEntry ae = (AlgEntry) mAlgorithmMap
- .get(new Integer(key.getAlgorithm()));
- if (key.getAlgorithm() != ae.dnssecAlg)
- {
- // Recast the DNSKEYRecord in question as one using the offical
- // algorithm, to work around the lack of alias support in the underlying
- // KEYConverter class from DNSjava
-
- key = new DNSKEYRecord(key.getName(), key.getDClass(), key.getTTL(),
- key.getFlags(), key.getProtocol(), ae.dnssecAlg, key.getKey());
+ /**
+ * 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
+ * The RRSIG to match against.
+ * @return A List contains a one or more DNSKEYRecord objects, or null if a
+ * matching DNSKEY could not be found.
+ */
+ @SuppressWarnings("unchecked")
+ private List<DNSKEYRecord> 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());
+
+ return null;
+ }
+
+ int keyid = signature.getFootprint();
+ int alg = signature.getAlgorithm();
+
+ List<DNSKEYRecord> res = new ArrayList<DNSKEYRecord>(dnskey_rrset.size());
+
+ for (Iterator i = dnskey_rrset.rrs(); i.hasNext();) {
+ DNSKEYRecord r = (DNSKEYRecord) i.next();
+
+ if ((r.getAlgorithm() == alg) && (r.getFootprint() == keyid)) {
+ res.add(r);
+ }
+ }
+
+ if (res.size() == 0) {
+ log.trace("findKey: could not find a key matching " +
+ "the algorithm and footprint in supplied keyset. ");
+
+ return null;
+ }
+
+ return res;
}
- return KEYConverter.parseRecord(key);
- }
-
-
- /**
- * 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 The signature to verify with.
- * @param key The (public) key associated with the RRSIG record.
- * @return A security status code: SECURE if it worked, BOGUS if not,
- * UNCHECKED if we just couldn't actually do the function.
- */
- public byte verifySignature(RRset rrset, RRSIGRecord sigrec,
- DNSKEYRecord key)
- {
- try
- {
- PublicKey pk = parseDNSKEY(key);
-
- if (pk == null)
- {
-// log.warn("Could not convert DNSKEY record to a JCA public key: "
-// + key);
- return SecurityStatus.UNCHECKED;
- }
+ /**
+ * 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
+ * The signature record to check.
+ * @return A value of DNSSEC.Secure if it looks OK, DNSSEC.Faile if it looks
+ * bad.
+ */
+ private byte checkSignature(RRset rrset, RRSIGRecord sigrec) {
+ if ((rrset == null) || (sigrec == null)) {
+ return DNSSEC.Failed;
+ }
- byte[] data = SignUtils.generateSigData(rrset, sigrec);
+ if (!rrset.getName().equals(sigrec.getName())) {
+ log.debug("Signature name does not match RRset name");
- Signature signer = getSignature(sigrec.getAlgorithm());
- if (signer == null)
- {
- return SecurityStatus.BOGUS;
- }
-
- signer.initVerify(pk);
- signer.update(data);
-
- byte[] sig = sigrec.getSignature();
- if (isDSA(sigrec.getAlgorithm()))
- {
- sig = SignUtils.convertDSASignature(sig);
- }
- if (!signer.verify(sig))
- {
-// log.info("Signature failed to verify cryptographically");
-// log.debug("Failed signature: " + sigrec);
- return SecurityStatus.BOGUS;
- }
-// log.trace("Signature verified: " + sigrec);
- return SecurityStatus.SECURE;
- }
- catch (IOException e)
- {
-// log.error("I/O error", e);
+ return SecurityStatus.BOGUS;
+ }
+
+ if (rrset.getType() != sigrec.getTypeCovered()) {
+ log.debug("Signature type does not match RRset type");
+
+ return SecurityStatus.BOGUS;
+ }
+
+ Date now = new Date();
+ Date start = sigrec.getTimeSigned();
+ Date expire = sigrec.getExpire();
+
+ if (now.before(start)) {
+ log.debug("Signature is not yet valid");
+
+ return SecurityStatus.BOGUS;
+ }
+
+ if (now.after(expire)) {
+ log.debug("Signature has expired (now = " + now +
+ ", sig expires = " + expire);
+
+ return SecurityStatus.BOGUS;
+ }
+
+ return SecurityStatus.SECURE;
}
- catch (GeneralSecurityException e)
- {
-// log.error("Security error", e);
+
+ public PublicKey parseDNSKEY(DNSKEYRecord key) {
+ AlgEntry ae = (AlgEntry) mAlgorithmMap.get(new Integer(
+ key.getAlgorithm()));
+
+ if (key.getAlgorithm() != ae.dnssecAlg) {
+ // Recast the DNSKEYRecord in question as one using the offical
+ // algorithm, to work around the lack of alias support in the
+ // underlying
+ // KEYConverter class from DNSjava
+ key = new DNSKEYRecord(key.getName(), key.getDClass(),
+ key.getTTL(), key.getFlags(), key.getProtocol(),
+ ae.dnssecAlg, key.getKey());
+ }
+
+ return KEYConverter.parseRecord(key);
}
- // FIXME: Since I'm not sure what would cause an exception here (failure
- // to have the required crypto?)
- // We default to UNCHECKED instead of BOGUS. This could be wrong.
- return SecurityStatus.UNCHECKED;
-
- }
-
- /**
- * 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
- * available).
- */
- public byte verifySignature(RRset rrset, RRSIGRecord sigrec, RRset key_rrset)
- {
- byte result = checkSignature(rrset, sigrec);
- if (result != SecurityStatus.SECURE) return result;
-
- List<DNSKEYRecord> keys = findKey(key_rrset, sigrec);
-
- if (keys == null)
- {
-// log.trace("could not find appropriate key");
- return SecurityStatus.BOGUS;
+ /**
+ * 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
+ * The signature to verify with.
+ * @param key
+ * The (public) key associated with the RRSIG record.
+ * @return A security status code: SECURE if it worked, BOGUS if not,
+ * UNCHECKED if we just couldn't actually do the function.
+ */
+ public byte verifySignature(RRset rrset, RRSIGRecord sigrec,
+ DNSKEYRecord key) {
+ try {
+ PublicKey pk = parseDNSKEY(key);
+
+ if (pk == null) {
+ log.warn(
+ "Could not convert DNSKEY record to a JCA public key: " +
+ key);
+
+ return SecurityStatus.UNCHECKED;
+ }
+
+ byte [] data = SignUtils.generateSigData(rrset, sigrec);
+
+ Signature signer = getSignature(sigrec.getAlgorithm());
+
+ if (signer == null) {
+ return SecurityStatus.BOGUS;
+ }
+
+ signer.initVerify(pk);
+ signer.update(data);
+
+ byte [] sig = sigrec.getSignature();
+
+ if (isDSA(sigrec.getAlgorithm())) {
+ sig = SignUtils.convertDSASignature(sig);
+ }
+
+ if (!signer.verify(sig)) {
+ log.info("Signature failed to verify cryptographically");
+ log.debug("Failed signature: " + sigrec);
+
+ return SecurityStatus.BOGUS;
+ }
+
+ log.trace("Signature verified: " + sigrec);
+
+ return SecurityStatus.SECURE;
+ } catch (IOException e) {
+ log.error("I/O error", e);
+ } catch (GeneralSecurityException e) {
+ log.error("Security error", e);
+ }
+
+ // FIXME: Since I'm not sure what would cause an exception here (failure
+ // to have the required crypto?)
+ // We default to UNCHECKED instead of BOGUS. This could be wrong.
+ return SecurityStatus.UNCHECKED;
}
- byte status = SecurityStatus.UNCHECKED;
+ /**
+ * 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
+ * available).
+ */
+ public byte verifySignature(RRset rrset, RRSIGRecord sigrec, RRset key_rrset) {
+ byte result = checkSignature(rrset, sigrec);
+
+ if (result != SecurityStatus.SECURE) {
+ return result;
+ }
+
+ List<DNSKEYRecord> keys = findKey(key_rrset, sigrec);
- for (DNSKEYRecord key : keys) {
- status = verifySignature(rrset, sigrec, key);
+ if (keys == null) {
+ log.trace("could not find appropriate key");
- if (status == SecurityStatus.SECURE) break;
+ return SecurityStatus.BOGUS;
+ }
+
+ byte status = SecurityStatus.UNCHECKED;
+
+ for (DNSKEYRecord key : keys) {
+ status = verifySignature(rrset, sigrec, key);
+
+ if (status == SecurityStatus.SECURE) {
+ break;
+ }
+ }
+
+ return status;
}
- return status;
- }
-
- /**
- * 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.
- */
- @SuppressWarnings("unchecked")
-public byte verify(RRset rrset, RRset key_rrset)
- {
- Iterator i = rrset.sigs();
-
- if (!i.hasNext())
- {
-// log.info("RRset failed to verify due to lack of signatures");
- return SecurityStatus.BOGUS;
+ /**
+ * 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.
+ */
+ @SuppressWarnings("unchecked")
+ public byte verify(RRset rrset, RRset key_rrset) {
+ Iterator i = rrset.sigs();
+
+ if (!i.hasNext()) {
+ log.info("RRset failed to verify due to lack of signatures");
+
+ return SecurityStatus.BOGUS;
+ }
+
+ while (i.hasNext()) {
+ RRSIGRecord sigrec = (RRSIGRecord) i.next();
+
+ byte res = verifySignature(rrset, sigrec, key_rrset);
+
+ if (res == SecurityStatus.SECURE) {
+ return res;
+ }
+ }
+
+ log.info("RRset failed to verify: all signatures were BOGUS");
+
+ return SecurityStatus.BOGUS;
}
- while (i.hasNext())
- {
- RRSIGRecord sigrec = (RRSIGRecord) i.next();
+ /**
+ * 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
+ * The DNSKEY to verify with.
+ * @return SecurityStatus.SECURE if the rrset verified, BOGUS otherwise.
+ */
+ @SuppressWarnings("unchecked")
+ public byte verify(RRset rrset, DNSKEYRecord dnskey) {
+ // Iterate over RRSIGS
+ Iterator i = rrset.sigs();
+
+ if (!i.hasNext()) {
+ log.info("RRset failed to verify due to lack of signatures");
+
+ return SecurityStatus.BOGUS;
+ }
+
+ while (i.hasNext()) {
+ RRSIGRecord sigrec = (RRSIGRecord) i.next();
+
+ // Skip RRSIGs that do not match our given key's footprint.
+ if (sigrec.getFootprint() != dnskey.getFootprint()) {
+ continue;
+ }
+
+ byte res = verifySignature(rrset, sigrec, dnskey);
+
+ if (res == SecurityStatus.SECURE) {
+ return res;
+ }
+ }
+
+ log.info("RRset failed to verify: all signatures were BOGUS");
- byte res = verifySignature(rrset, sigrec, key_rrset);
+ return SecurityStatus.BOGUS;
+ }
- if (res == SecurityStatus.SECURE) return res;
+ public boolean supportsAlgorithm(int algorithm) {
+ return mAlgorithmMap.containsKey(new Integer(algorithm));
}
-// log.info("RRset failed to verify: all signatures were BOGUS");
- return SecurityStatus.BOGUS;
- }
-
- /**
- * 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 The DNSKEY to verify with.
- * @return SecurityStatus.SECURE if the rrset verified, BOGUS otherwise.
- */
- @SuppressWarnings("unchecked")
-public byte verify(RRset rrset, DNSKEYRecord dnskey)
- {
- // Iterate over RRSIGS
-
- Iterator i = rrset.sigs();
- if (!i.hasNext())
- {
-// log.info("RRset failed to verify due to lack of signatures");
- return SecurityStatus.BOGUS;
+ public boolean supportsAlgorithm(Name private_id) {
+ return mAlgorithmMap.containsKey(private_id);
}
- while (i.hasNext())
- {
- RRSIGRecord sigrec = (RRSIGRecord) i.next();
+ public int baseAlgorithm(int algorithm) {
+ switch (algorithm) {
+ case DNSSEC.RSAMD5:
+ case DNSSEC.RSASHA1:
+ return RSA;
- // Skip RRSIGs that do not match our given key's footprint.
- if (sigrec.getFootprint() != dnskey.getFootprint()) continue;
+ case DNSSEC.DSA:
+ return DSA;
+ }
- byte res = verifySignature(rrset, sigrec, dnskey);
+ AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
- if (res == SecurityStatus.SECURE) return res;
- }
+ if (entry == null) {
+ return UNKNOWN;
+ }
+
+ if (entry.isDSA) {
+ return DSA;
+ }
-// log.info("RRset failed to verify: all signatures were BOGUS");
- return SecurityStatus.BOGUS;
- }
-
- public boolean supportsAlgorithm(int algorithm)
- {
- return mAlgorithmMap.containsKey(new Integer(algorithm));
- }
-
- public boolean supportsAlgorithm(Name private_id)
- {
- return mAlgorithmMap.containsKey(private_id);
- }
-
- public int baseAlgorithm(int algorithm)
- {
- switch (algorithm)
- {
- case DNSSEC.RSAMD5:
- case DNSSEC.RSASHA1:
return RSA;
- case DNSSEC.DSA:
- return DSA;
}
- AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
- if (entry == null) return UNKNOWN;
- if (entry.isDSA) return DSA;
- return RSA;
- }
-
- /** @return the appropriate Signature object for this keypair. */
- private Signature getSignature(int algorithm)
- {
- Signature s = null;
-
-
- try
- {
- AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
- if (entry == null)
- {
-// log.info("DNSSEC algorithm " + algorithm + " not recognized.");
- return null;
- }
- // TODO: should we cache the instance?
- s = Signature.getInstance(entry.jcaName);
+
+ /** @return the appropriate Signature object for this keypair. */
+ private Signature getSignature(int algorithm) {
+ Signature s = null;
+
+ try {
+ AlgEntry entry = (AlgEntry) mAlgorithmMap.get(new Integer(algorithm));
+
+ if (entry == null) {
+ log.info("DNSSEC algorithm " + algorithm + " not recognized.");
+
+ return null;
+ }
+
+ // TODO: should we cache the instance?
+ s = Signature.getInstance(entry.jcaName);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("error getting Signature object", e);
+ }
+
+ return s;
}
- catch (NoSuchAlgorithmException e)
- {
-// log.error("error getting Signature object", e);
+
+ private static class AlgEntry {
+ public String jcaName;
+ public boolean isDSA;
+ public int dnssecAlg;
+
+ public AlgEntry(String name, int dnssecAlg, boolean isDSA) {
+ jcaName = name;
+ this.dnssecAlg = dnssecAlg;
+ this.isDSA = isDSA;
+ }
}
- return s;
- }
-
- // TODO: enable private algorithm support in dnsjava.
- // Right now, this cannot be used because the DNSKEYRecord object doesn't
- // give us
- // the private key name.
- // private Signature getSignature(Name private_alg)
- // {
- // Signature s = null;
- //
- // try
- // {
- // String alg_id = (String) mAlgorithmMap.get(private_alg);
- // if (alg_id == null)
- // {
- // log.debug("DNSSEC private algorithm '" + private_alg
- // + "' not recognized.");
- // return null;
- // }
- //
- // s = Signature.getInstance(alg_id);
- // }
- // catch (NoSuchAlgorithmException e)
- // {
- // log.error("error getting Signature object", e);
- // }
- //
- // return s;
- // }
+ // TODO: enable private algorithm support in dnsjava.
+ // Right now, this cannot be used because the DNSKEYRecord object doesn't
+ // give us
+ // the private key name.
+ // private Signature getSignature(Name private_alg)
+ // {
+ // Signature s = null;
+ //
+ // try
+ // {
+ // String alg_id = (String) mAlgorithmMap.get(private_alg);
+ // if (alg_id == null)
+ // {
+ // log.debug("DNSSEC private algorithm '" + private_alg
+ // + "' not recognized.");
+ // return null;
+ // }
+ //
+ // s = Signature.getInstance(alg_id);
+ // }
+ // catch (NoSuchAlgorithmException e)
+ // {
+ // log.error("error getting Signature object", e);
+ // }
+ //
+ // return s;
+ // }
}