add verbose signing mode to signzone; some comment fixes, some unused vars and imports removed

git-svn-id: https://svn.verisignlabs.com/jdnssec/tools/trunk@217 4cbd57fe-54e5-0310-bd9a-f30fe5ea5e6e
This commit is contained in:
David Blacka 2010-12-05 23:08:13 +00:00
parent 51d4ca0333
commit 14ea619299
9 changed files with 155 additions and 121 deletions

View File

@ -1,3 +1,12 @@
2010-12-05 David Blacka <davidb@verisignlabs.com>
* jdnssec-signzone: add a "verbose signing" option. This will
cause the pre-signed bytes and the raw signature bytes to be
output when signing.
* Other fixes: some minor tweaks and comment fixes.
Unfortunately, also a lot of rewrapping and whitespace changes due
to Eclipse. Sigh.
2010-01-14 David Blacka <davidb@verisignlabs.com>
* Released version 0.9.6

View File

@ -74,7 +74,6 @@ public class SignKeyset {
private Options opts;
private File keyDirectory = null;
public String[] keyFiles = null;
public String keysetFile = null;
public Date start = null;
public Date expire = null;
public String inputfile = null;

View File

@ -89,7 +89,6 @@ public class SignZone
public Date expire = null;
public String outputfile = null;
public boolean verifySigs = false;
public boolean selfSignKeys = true;
public boolean useOptOut = false;
public boolean fullySignKeyset = false;
public List includeNames = null;
@ -98,6 +97,7 @@ public class SignZone
public int iterations = 0;
public int digest_id = DSRecord.SHA1_DIGEST_ID;
public long nsec3paramttl = -1;
public boolean verboseSigning = false;
public CLIState()
{
@ -118,6 +118,7 @@ public class SignZone
opts.addOption("a", "verify", false, "verify generated signatures>");
opts.addOption("F", "fully-sign-keyset", false,
"sign the zone apex keyset with all available keys.");
opts.addOption("V", "verbose-signing", false, "Display verbose signing activity.");
OptionBuilder.hasOptionalArg();
OptionBuilder.withLongOpt("verbose");
@ -210,8 +211,7 @@ public class SignZone
}
public void parseCommandLine(String[] args)
throws org.apache.commons.cli.ParseException, ParseException,
IOException
throws org.apache.commons.cli.ParseException, ParseException, IOException
{
CommandLineParser cli_parser = new PosixParser();
CommandLine cli = cli_parser.parse(opts, args);
@ -250,7 +250,8 @@ public class SignZone
if (cli.hasOption('a')) verifySigs = true;
if (cli.hasOption('3')) useNsec3 = true;
if (cli.hasOption('O')) useOptOut = true;
if (cli.hasOption('V')) verboseSigning = true;
if (useOptOut && !useNsec3)
{
System.err.println("Opt-Out not supported without NSEC3 -- ignored.");
@ -406,10 +407,8 @@ public class SignZone
PrintWriter out = new PrintWriter(System.err);
// print our own usage statement:
out.println("usage: jdnssec-signzone [..options..] "
+ "zone_file [key_file ...] ");
f.printHelp(out, 75, "signZone.sh", null, opts,
HelpFormatter.DEFAULT_LEFT_PAD,
out.println("usage: jdnssec-signzone [..options..] " + "zone_file [key_file ...] ");
f.printHelp(out, 75, "signZone.sh", null, opts, HelpFormatter.DEFAULT_LEFT_PAD,
HelpFormatter.DEFAULT_DESC_PAD,
"\ntime/offset = YYYYMMDDHHmmss|+offset|\"now\"+offset\n");
@ -451,8 +450,7 @@ public class SignZone
* a list of keypairs used the sign the zone.
* @return true if all of the signatures validated.
*/
private static boolean verifyZoneSigs(Name zonename, List records,
List keypairs)
private static boolean verifyZoneSigs(Name zonename, List records, List keypairs)
{
boolean secure = true;
@ -478,8 +476,7 @@ public class SignZone
if (result != DNSSEC.Secure)
{
log.fine("Signatures did not verify for RRset: (" + result + "): "
+ rrset);
log.fine("Signatures did not verify for RRset: (" + result + "): " + rrset);
secure = false;
}
}
@ -500,8 +497,8 @@ public class SignZone
* the directory to look in (may be null).
* @return a list of keypair objects.
*/
private static List getKeys(String[] keyfiles, int start_index,
File inDirectory) throws IOException
private static List getKeys(String[] keyfiles, int start_index, File inDirectory)
throws IOException
{
if (keyfiles == null) return null;
@ -519,8 +516,7 @@ public class SignZone
return keys;
}
private static List getKeys(List dnskeyrrs, File inDirectory)
throws IOException
private static List getKeys(List dnskeyrrs, File inDirectory) throws IOException
{
List res = new ArrayList();
for (Iterator i = dnskeyrrs.iterator(); i.hasNext();)
@ -558,8 +554,7 @@ public class SignZone
}
}
private static List findZoneKeys(File inDirectory, Name zonename)
throws IOException
private static List findZoneKeys(File inDirectory, Name zonename) throws IOException
{
if (inDirectory == null)
{
@ -608,8 +603,7 @@ public class SignZone
* do not belong in the zone.
* @return a list of {@link org.xbill.DNS.Record}s found in the keyset files.
*/
private static List getKeysets(File inDirectory, Name zonename)
throws IOException
private static List getKeysets(File inDirectory, Name zonename) throws IOException
{
if (inDirectory == null)
{
@ -686,8 +680,7 @@ public class SignZone
* the time/offset string to parse.
* @return the calculated time.
*/
private static Date convertDuration(Date start, String duration)
throws ParseException
private static Date convertDuration(Date start, String duration) throws ParseException
{
if (start == null) start = new Date();
if (duration.startsWith("now"))
@ -854,18 +847,16 @@ public class SignZone
records.addAll(keysetrecs);
}
JCEDnsSecSigner signer = new JCEDnsSecSigner();
JCEDnsSecSigner signer = new JCEDnsSecSigner(state.verboseSigning);
// Sign the zone.
List signed_records;
if (state.useNsec3)
{
signed_records = signer.signZoneNSEC3(zonename, records, kskpairs,
keypairs, state.start,
state.expire,
state.fullySignKeyset,
state.useOptOut,
signed_records = signer.signZoneNSEC3(zonename, records, kskpairs, keypairs,
state.start, state.expire,
state.fullySignKeyset, state.useOptOut,
state.includeNames, state.salt,
state.iterations, state.digest_id,
state.nsec3paramttl);
@ -873,8 +864,8 @@ public class SignZone
else
{
signed_records = signer.signZone(zonename, records, kskpairs, keypairs,
state.start, state.expire,
state.fullySignKeyset, state.digest_id);
state.start, state.expire, state.fullySignKeyset,
state.digest_id);
}
// write out the signed zone

View File

@ -41,7 +41,7 @@ import java.util.logging.Logger;
import org.xbill.DNS.DNSSEC;
/**
* This class handles translated DNS signing algorithm identifiers into various
* This class handles translating DNS signing algorithm identifiers into various
* usable java implementations.
*
* Besides centralizing the logic surrounding matching a DNSKEY algorithm
@ -93,8 +93,7 @@ public class DnsKeyAlgorithm
/** This is a cache key pair generator for DSA keys. */
private KeyPairGenerator mDSAKeyGenerator;
private Logger log = Logger.getLogger(this.getClass()
.toString());
private Logger log = Logger.getLogger(this.getClass().toString());
/** This is the global instance for this class. */
private static DnsKeyAlgorithm mInstance = null;
@ -125,7 +124,7 @@ public class DnsKeyAlgorithm
// Also recognize the BIND 9.6 mnemonics
addMnemonic("NSEC3DSA", DNSSEC.DSA_NSEC3_SHA1);
addMnemonic("NSEC3RSASHA1", DNSSEC.RSA_NSEC3_SHA1);
// Algorithms added by RFC 5702.
// NOTE: these algorithms aren't available in Java 1.4's sunprovider
// implementation (but are in java 1.5's and later).

View File

@ -44,7 +44,6 @@ import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPrivateKeySpec;
import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.KEYRecord;
import org.xbill.DNS.Name;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;

View File

@ -38,6 +38,7 @@ import org.xbill.DNS.RRSIGRecord;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
import org.xbill.DNS.utils.hexdump;
/**
* This class contains routines for signing DNS zones.
@ -54,6 +55,19 @@ import org.xbill.DNS.Type;
public class JCEDnsSecSigner
{
private DnsKeyConverter mKeyConverter;
private boolean mVerboseSigning = false;
public JCEDnsSecSigner()
{
this.mKeyConverter = null;
this.mVerboseSigning = false;
}
public JCEDnsSecSigner(boolean verboseSigning)
{
this.mKeyConverter = null;
this.mVerboseSigning = verboseSigning;
}
/**
* Cryptographically generate a new DNSSEC key.
@ -74,27 +88,23 @@ public class JCEDnsSecSigner
* if generating an RSA key, use the large exponent.
* @return a DnsKeyPair with the public and private keys populated.
*/
public DnsKeyPair generateKey(Name owner, long ttl, int dclass,
int algorithm, int flags, int keysize,
boolean useLargeExponent)
public DnsKeyPair generateKey(Name owner, long ttl, int dclass, int algorithm,
int flags, int keysize, boolean useLargeExponent)
throws NoSuchAlgorithmException
{
DnsKeyAlgorithm algorithms = DnsKeyAlgorithm.getInstance();
if (ttl < 0) ttl = 86400; // set to a reasonable default.
KeyPair pair = algorithms.generateKeyPair(algorithm, keysize,
useLargeExponent);
KeyPair pair = algorithms.generateKeyPair(algorithm, keysize, useLargeExponent);
if (mKeyConverter == null)
{
mKeyConverter = new DnsKeyConverter();
}
DNSKEYRecord keyrec = mKeyConverter.generateDNSKEYRecord(owner, dclass,
ttl, flags,
algorithm,
pair.getPublic());
DNSKEYRecord keyrec = mKeyConverter.generateDNSKEYRecord(owner, dclass, ttl, flags,
algorithm, pair.getPublic());
DnsKeyPair dnspair = new DnsKeyPair();
dnspair.setDNSKEYRecord(keyrec);
@ -127,6 +137,12 @@ public class JCEDnsSecSigner
if (expire == null) expire = new Date(start.getTime() + 1000L);
if (keypairs.size() == 0) return null;
if (mVerboseSigning)
{
System.out.println("Signing RRset:");
System.out.println(ZoneUtils.rrsetToString(rrset, false));
}
// first, pre-calculate the RRset bytes.
byte[] rrset_data = SignUtils.generateCanonicalRRsetData(rrset, 0, 0);
@ -139,10 +155,17 @@ public class JCEDnsSecSigner
DNSKEYRecord keyrec = pair.getDNSKEYRecord();
if (keyrec == null) continue;
RRSIGRecord presig = SignUtils.generatePreRRSIG(rrset, keyrec, start,
expire, rrset.getTTL());
RRSIGRecord presig = SignUtils.generatePreRRSIG(rrset, keyrec, start, expire,
rrset.getTTL());
byte[] sign_data = SignUtils.generateSigData(rrset_data, presig);
if (mVerboseSigning)
{
System.out.println("Canonical pre-signature data to sign with key " + keyrec.getName().toString() + "/"
+ keyrec.getAlgorithm() + "/" + keyrec.getFootprint() + ":");
System.out.println(hexdump.dump(null, sign_data));
}
Signature signer = pair.getSigner();
if (signer == null)
@ -150,23 +173,33 @@ public class JCEDnsSecSigner
// debug
System.out.println("missing private key that goes with:\n"
+ pair.getDNSKEYRecord());
throw new GeneralSecurityException(
"cannot sign without a valid Signer (probably missing private key)");
throw new GeneralSecurityException("cannot sign without a valid Signer "
+ "(probably missing private key)");
}
// sign the data.
signer.update(sign_data);
byte[] sig = signer.sign();
if (mVerboseSigning)
{
System.out.println("Raw Signature:");
System.out.println(hexdump.dump(null, sig));
}
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
// Convert to RFC 2536 format, if necessary.
if (algs.baseType(pair.getDNSKEYAlgorithm()) == DnsKeyAlgorithm.DSA)
{
sig = SignUtils.convertDSASignature(
((DSAPublicKey) pair.getPublic()).getParams(),
sig);
DSAPublicKey pk = (DSAPublicKey) pair.getPublic();
sig = SignUtils.convertDSASignature(pk.getParams(), sig);
}
RRSIGRecord sigrec = SignUtils.generateRRSIG(sig, presig);
if (mVerboseSigning)
{
System.out.println("RRSIG:\n" + sigrec);
System.out.println();
}
sigs.add(sigrec);
}
@ -184,8 +217,8 @@ public class JCEDnsSecSigner
* the RRSIG expiration time.
* @return a signed RRset.
*/
public RRset makeKeySet(List keypairs, Date start, Date expire)
throws IOException, GeneralSecurityException
public RRset makeKeySet(List keypairs, Date start, Date expire) throws IOException,
GeneralSecurityException
{
// Generate a KEY RR set to sign.
@ -232,9 +265,8 @@ public class JCEDnsSecSigner
* @return the name of the new last_cut.
*/
private Name addRRset(List toList, Name zonename, RRset rrset, List kskpairs,
List zskpairs, Date start, Date expire,
boolean fullySignKeyset, Name last_cut)
throws IOException, GeneralSecurityException
List zskpairs, Date start, Date expire, boolean fullySignKeyset,
Name last_cut) throws IOException, GeneralSecurityException
{
// add the records themselves
for (Iterator i = rrset.rrs(); i.hasNext();)
@ -242,8 +274,8 @@ public class JCEDnsSecSigner
toList.add(i.next());
}
int type = SignUtils.recordSecType(zonename, rrset.getName(),
rrset.getType(), last_cut);
int type = SignUtils.recordSecType(zonename, rrset.getName(), rrset.getType(),
last_cut);
// we don't sign non-normal sets (delegations, glue, invalid).
if (type == SignUtils.RR_DELEGATION)
@ -331,11 +363,10 @@ public class JCEDnsSecSigner
* @throws IOException
* @throws GeneralSecurityException
*/
private List signZone(Name zonename, List records, List kskpairs,
List zskpairs, Date start, Date expire,
boolean fullySignKeyset, int ds_digest_alg, int mode,
List includedNames, byte[] salt, int iterations,
long nsec3paramttl, boolean beConservative)
private List signZone(Name zonename, List records, List kskpairs, List zskpairs,
Date start, Date expire, boolean fullySignKeyset,
int ds_digest_alg, int mode, List includedNames, byte[] salt,
int iterations, long nsec3paramttl, boolean beConservative)
throws IOException, GeneralSecurityException
{
// Remove any existing generated DNSSEC records (NSEC, NSEC3, NSEC3PARAM,
@ -360,12 +391,11 @@ public class JCEDnsSecSigner
SignUtils.generateNSECRecords(zonename, records);
break;
case NSEC3_MODE:
SignUtils.generateNSEC3Records(zonename, records, salt, iterations,
nsec3paramttl);
SignUtils.generateNSEC3Records(zonename, records, salt, iterations, nsec3paramttl);
break;
case NSEC3_OPTOUT_MODE:
SignUtils.generateOptOutNSEC3Records(zonename, records, includedNames,
salt, iterations, nsec3paramttl);
SignUtils.generateOptOutNSEC3Records(zonename, records, includedNames, salt,
iterations, nsec3paramttl);
break;
case NSEC_EXP_OPT_IN:
SignUtils.generateOptInNSECRecords(zonename, records, includedNames,
@ -393,8 +423,7 @@ public class JCEDnsSecSigner
}
// Current record is part of the current RRset.
if (rrset.getName().equals(r.getName())
&& rrset.getDClass() == r.getDClass()
if (rrset.getName().equals(r.getName()) && rrset.getDClass() == r.getDClass()
&& rrset.getType() == r.getType())
{
rrset.addRR(r);
@ -406,16 +435,16 @@ public class JCEDnsSecSigner
// add the RRset to the list of signed_records, regardless of
// whether or not we actually end up signing the set.
last_cut = addRRset(signed_records, zonename, rrset, kskpairs, zskpairs,
start, expire, fullySignKeyset, last_cut);
last_cut = addRRset(signed_records, zonename, rrset, kskpairs, zskpairs, start,
expire, fullySignKeyset, last_cut);
rrset.clear();
rrset.addRR(r);
}
// add the last RR set
addRRset(signed_records, zonename, rrset, kskpairs, zskpairs, start,
expire, fullySignKeyset, last_cut);
addRRset(signed_records, zonename, rrset, kskpairs, zskpairs, start, expire,
fullySignKeyset, last_cut);
return signed_records;
}
@ -445,14 +474,12 @@ public class JCEDnsSecSigner
* @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone.
*/
public List signZone(Name zonename, List records, List kskpairs,
List zskpairs, Date start, Date expire,
boolean fullySignKeyset, int ds_digest_alg)
public List signZone(Name zonename, List records, List kskpairs, List zskpairs,
Date start, Date expire, boolean fullySignKeyset, int ds_digest_alg)
throws IOException, GeneralSecurityException
{
return signZone(zonename, records, kskpairs, zskpairs, start, expire,
fullySignKeyset, ds_digest_alg, NSEC_MODE, null, null, 0,
0, false);
fullySignKeyset, ds_digest_alg, NSEC_MODE, null, null, 0, 0, false);
}
/**
@ -496,24 +523,23 @@ public class JCEDnsSecSigner
* @throws IOException
* @throws GeneralSecurityException
*/
public List signZoneNSEC3(Name zonename, List records, List kskpairs,
List zskpairs, Date start, Date expire,
boolean fullySignKeyset, boolean useOptOut,
List includedNames, byte[] salt, int iterations,
int ds_digest_alg, long nsec3paramttl)
public List signZoneNSEC3(Name zonename, List records, List kskpairs, List zskpairs,
Date start, Date expire, boolean fullySignKeyset,
boolean useOptOut, List includedNames, byte[] salt,
int iterations, int ds_digest_alg, long nsec3paramttl)
throws IOException, GeneralSecurityException
{
if (useOptOut)
{
return signZone(zonename, records, kskpairs, zskpairs, start, expire,
fullySignKeyset, ds_digest_alg, NSEC3_OPTOUT_MODE,
includedNames, salt, iterations, nsec3paramttl, false);
fullySignKeyset, ds_digest_alg, NSEC3_OPTOUT_MODE, includedNames,
salt, iterations, nsec3paramttl, false);
}
else
{
return signZone(zonename, records, kskpairs, zskpairs, start, expire,
fullySignKeyset, ds_digest_alg, NSEC3_MODE, null, salt,
iterations, nsec3paramttl, false);
fullySignKeyset, ds_digest_alg, NSEC3_MODE, null, salt, iterations,
nsec3paramttl, false);
}
}
@ -547,16 +573,15 @@ public class JCEDnsSecSigner
* @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone.
*/
public List signZoneOptIn(Name zonename, List records, List kskpairs,
List zskpairs, Date start, Date expire,
boolean useConservativeOptIn,
public List signZoneOptIn(Name zonename, List records, List kskpairs, List zskpairs,
Date start, Date expire, boolean useConservativeOptIn,
boolean fullySignKeyset, List NSECIncludeNames,
int ds_digest_alg)
throws IOException, GeneralSecurityException
int ds_digest_alg) throws IOException,
GeneralSecurityException
{
return signZone(zonename, records, kskpairs, zskpairs, start, expire,
fullySignKeyset, ds_digest_alg, NSEC_EXP_OPT_IN,
NSECIncludeNames, null, 0, 0, useConservativeOptIn);
fullySignKeyset, ds_digest_alg, NSEC_EXP_OPT_IN, NSECIncludeNames,
null, 0, 0, useConservativeOptIn);
}
}

View File

@ -33,28 +33,38 @@ import org.xbill.DNS.*;
import org.xbill.DNS.utils.base16;
import org.xbill.DNS.utils.base32;
/**
* This is a class representing a "prototype NSEC3" resource record. These are
* used as an intermediate stage (in zone signing) between determining the list
* of NSEC3 records and forming them into a viable chain.
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 183 $
*/
public class ProtoNSEC3
{
private Name originalOwner;
private byte hashAlg;
private byte flags;
private int iterations;
private byte[] salt;
private byte[] next;
private byte[] owner; // cached numerical owner value.
private TypeMap typemap;
private Name zone;
private Name name;
private int dclass;
private long ttl;
private Name originalOwner;
private byte hashAlg;
private byte flags;
private int iterations;
private byte[] salt;
private byte[] next;
private byte[] owner; // cached numerical owner value.
private TypeMap typemap;
private Name zone;
private Name name;
private int dclass;
private long ttl;
private static final base32 b32 = new base32(base32.Alphabet.BASE32HEX, false, false);
/**
* Creates an NSEC3 Record from the given data.
*/
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass,
long ttl, byte hashAlg, byte flags, int iterations, byte[] salt,
byte[] next, TypeMap typemap)
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
byte hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
TypeMap typemap)
{
this.zone = zone;
this.owner = owner;
@ -69,12 +79,12 @@ public class ProtoNSEC3
this.originalOwner = originalOwner;
}
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass,
long ttl, byte hashAlg, byte flags, int iterations, byte[] salt,
byte[] next, int[] types)
public ProtoNSEC3(byte[] owner, Name originalOwner, Name zone, int dclass, long ttl,
byte hashAlg, byte flags, int iterations, byte[] salt, byte[] next,
int[] types)
{
this(owner, originalOwner, zone, dclass, ttl, hashAlg, flags, iterations,
salt, next, TypeMap.fromTypes(types));
this(owner, originalOwner, zone, dclass, ttl, hashAlg, flags, iterations, salt, next,
TypeMap.fromTypes(types));
}
private String hashToString(byte[] hash)
@ -122,7 +132,8 @@ public class ProtoNSEC3
public void setOptOutFlag(boolean optOutFlag)
{
if (optOutFlag) this.flags |= NSEC3Record.Flags.OPT_OUT;
if (optOutFlag)
this.flags |= NSEC3Record.Flags.OPT_OUT;
else
this.flags &= ~NSEC3Record.Flags.OPT_OUT;
}
@ -185,9 +196,9 @@ public class ProtoNSEC3
public NSEC3Record getNSEC3Record()
{
String comment = (originalOwner == null) ? "(unknown original ownername)"
: originalOwner.toString();
return new NSEC3Record(getName(), dclass, ttl, hashAlg, flags, iterations,
salt, next, getTypes(), comment);
: originalOwner.toString();
return new NSEC3Record(getName(), dclass, ttl, hashAlg, flags, iterations, salt,
next, getTypes(), comment);
}
public void mergeTypes(TypeMap new_types)

View File

@ -14,7 +14,8 @@ import org.xbill.DNS.Type;
/**
* This class represents the multiple type maps of the NSEC record. Currently it
* is just used to convert the wire format type map to the int array that
* org.xbill.DNS.NSECRecord uses.
* org.xbill.DNS.NSECRecord uses. Note that there is now a very similar class in
* DNSjava: {@link org.xbill.DNS.TypeBitmap}.
*/
public class TypeMap

View File

@ -109,7 +109,7 @@ public class ZoneUtils
* @param records
* a list of {@link org.xbill.DNS.Record} or
* {@link org.xbill.DNS.RRset} objects.
* @return the zone name, if found. null if one couldn't be found.q
* @return the zone name, if found. null if one couldn't be found.
*/
public static Name findZoneName(List records)
{