add support for algorithm aliases, fix SignZone so you can specify more than one KSK

git-svn-id: https://svn.verisignlabs.com/jdnssec/tools/trunk@64 4cbd57fe-54e5-0310-bd9a-f30fe5ea5e6e
This commit is contained in:
David Blacka
2006-05-23 21:24:00 +00:00
parent 5ba24d35b1
commit 435acff6d0
9 changed files with 631 additions and 308 deletions

View File

@@ -27,10 +27,10 @@ import java.util.logging.Logger;
import org.apache.commons.cli.*;
import org.xbill.DNS.DClass;
import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.DNSSEC;
import org.xbill.DNS.Name;
import com.verisignlabs.dnssec.security.BINDKeyUtils;
import com.verisignlabs.dnssec.security.DnsKeyAlgorithm;
import com.verisignlabs.dnssec.security.DnsKeyPair;
import com.verisignlabs.dnssec.security.JCEDnsSecSigner;
@@ -66,6 +66,73 @@ public class KeyGen
setupCLI();
}
/**
* Set up the command line options.
*
* @return a set of command line options.
*/
private void setupCLI()
{
opts = new Options();
// boolean options
opts.addOption("h", "help", false, "Print this message.");
opts.addOption("k",
"kskflag",
false,
"Key is a key-signing-key (sets the SEP flag).");
// Argument options
OptionBuilder.hasArg();
OptionBuilder.withLongOpt("nametype");
OptionBuilder.withArgName("type");
OptionBuilder.withDescription("ZONE | OTHER (default ZONE)");
opts.addOption(OptionBuilder.create('n'));
OptionBuilder.hasOptionalArg();
OptionBuilder.withLongOpt("verbose");
OptionBuilder.withArgName("level");
OptionBuilder.withDescription("verbosity level -- 0 is silence, "
+ "5 is debug information, " + "6 is trace information.\n"
+ "default is level 5.");
opts.addOption(OptionBuilder.create('v'));
OptionBuilder.hasArg();
OptionBuilder.withArgName("algorithm");
OptionBuilder
.withDescription("RSA | RSASHA1 | RSAMD5 | DH | DSA | alias, "
+ "RSASHA1 is default.");
opts.addOption(OptionBuilder.create('a'));
OptionBuilder.hasArg();
OptionBuilder.withArgName("size");
OptionBuilder.withDescription("key size, in bits. (default = 1024)\n"
+ "RSA|RSASHA1|RSAMD5: [512..4096]\n"
+ "DSA: [512..1024]\n"
+ "DH: [128..4096]");
opts.addOption(OptionBuilder.create('b'));
OptionBuilder.hasArg();
OptionBuilder.withArgName("file");
OptionBuilder.withLongOpt("output-file");
OptionBuilder
.withDescription("base filename for the public/private key files");
opts.addOption(OptionBuilder.create('f'));
OptionBuilder.hasArg();
OptionBuilder.withLongOpt("keydir");
OptionBuilder.withArgName("dir");
OptionBuilder.withDescription("place generated key files in this "
+ "directory");
opts.addOption(OptionBuilder.create('d'));
OptionBuilder.hasArg();
OptionBuilder.withLongOpt("alg-alias");
OptionBuilder.withArgName("alias:original:mnemonic");
OptionBuilder.withDescription("define an alias for an algorithm");
opts.addOption(OptionBuilder.create('A'));
}
public void parseCommandLine(String[] args)
throws org.apache.commons.cli.ParseException
{
@@ -111,6 +178,16 @@ public class KeyGen
zoneKey = false;
}
}
String[] optstrs;
if ((optstrs = cli.getOptionValues('A')) != null)
{
for (int i = 0; i < optstrs.length; i++)
{
addArgAlias(optstrs[i]);
}
}
if ((optstr = cli.getOptionValue('a')) != null)
{
algorithm = parseAlg(optstr);
@@ -137,64 +214,25 @@ public class KeyGen
owner = cl_args[0];
}
/**
* Set up the command line options.
*
* @return a set of command line options.
*/
private void setupCLI()
private void addArgAlias(String s)
{
opts = new Options();
// boolean options
opts.addOption("h", "help", false, "Print this message.");
opts.addOption("k",
"kskflag",
false,
"Key is a key-signing-key (sets the SEP flag).");
// Argument options
OptionBuilder.hasArg();
OptionBuilder.withLongOpt("nametype");
OptionBuilder.withArgName("type");
OptionBuilder.withDescription("ZONE | OTHER (default ZONE)");
opts.addOption(OptionBuilder.create('n'));
OptionBuilder.hasOptionalArg();
OptionBuilder.withLongOpt("verbose");
OptionBuilder.withArgName("level");
OptionBuilder.withDescription("verbosity level -- 0 is silence, "
+ "5 is debug information, " + "6 is trace information.\n"
+ "default is level 5.");
opts.addOption(OptionBuilder.create('v'));
OptionBuilder.hasArg();
OptionBuilder.withArgName("algorithm");
OptionBuilder.withDescription("RSA | RSASHA1 | RSAMD5 | DH | DSA, "
+ "RSASHA1 is default.");
opts.addOption(OptionBuilder.create('a'));
OptionBuilder.hasArg();
OptionBuilder.withArgName("size");
OptionBuilder.withDescription("key size, in bits. (default = 1024)\n"
+ "RSA|RSASHA1|RSAMD5: [512..4096]\n"
+ "DSA: [512..1024]\n"
+ "DH: [128..4096]");
opts.addOption(OptionBuilder.create('b'));
OptionBuilder.hasArg();
OptionBuilder.withArgName("file");
OptionBuilder.withLongOpt("output-file");
OptionBuilder.withDescription("base filename for the public/private key files");
opts.addOption(OptionBuilder.create('f'));
OptionBuilder.hasArg();
OptionBuilder.withLongOpt("keydir");
OptionBuilder.withArgName("dir");
OptionBuilder.withDescription("place generated key files in this directory");
opts.addOption(OptionBuilder.create('d'));
if (s == null) return;
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
String[] v = s.split(":");
if (v.length < 2) return;
int alias = parseInt(v[0], -1);
if (alias <= 0) return;
int orig = parseInt(v[1], -1);
if (orig <= 0) return;
String mn = null;
if (v.length > 2) mn = v[2];
algs.addAlias(alias, mn, orig);
}
/** Print out the usage and help statements, then quit. */
private void usage()
{
@@ -239,34 +277,12 @@ public class KeyGen
private static int parseAlg(String s)
{
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
int alg = parseInt(s, -1);
if (alg > 0) return alg;
s = s.toUpperCase();
if (s.equals("RSA"))
{
return DNSSEC.RSASHA1;
}
else if (s.equals("RSAMD5"))
{
return DNSSEC.RSA;
}
else if (s.equals("DH"))
{
return DNSSEC.DH;
}
else if (s.equals("DSA"))
{
return DNSSEC.DSA;
}
else if (s.equals("RSASHA1"))
{
return DNSSEC.RSASHA1;
}
// default
return DNSSEC.RSASHA1;
return algs.stringToAlgorithm(s);
}
public static void execute(CLIState state) throws Exception

View File

@@ -44,13 +44,7 @@ import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
import org.xbill.DNS.utils.base16;
import com.verisignlabs.dnssec.security.BINDKeyUtils;
import com.verisignlabs.dnssec.security.DnsKeyPair;
import com.verisignlabs.dnssec.security.DnsSecVerifier;
import com.verisignlabs.dnssec.security.JCEDnsSecSigner;
import com.verisignlabs.dnssec.security.RecordComparator;
import com.verisignlabs.dnssec.security.SignUtils;
import com.verisignlabs.dnssec.security.ZoneUtils;
import com.verisignlabs.dnssec.security.*;
/**
* This class forms the command line implementation of a DNSSEC zone signer.
@@ -91,6 +85,76 @@ public class SignZone
setupCLI();
}
/**
* Set up the command line options.
*
* @return a set of command line options.
*/
private void setupCLI()
{
opts = new Options();
// boolean options
opts.addOption("h", "help", false, "Print this message.");
opts.addOption("a", "verify", false, "verify generated signatures>");
opts.addOption("F",
"fully-sign-keyset",
false,
"sign the zone apex keyset with all available keys.");
// Argument options
opts.addOption(OptionBuilder.hasOptionalArg().withLongOpt("verbose")
.withArgName("level").withDescription("verbosity level")
.create('v'));
opts.addOption(OptionBuilder.hasArg().withArgName("dir")
.withLongOpt("keyset-directory")
.withDescription("directory to find keyset files (default '.').")
.create('d'));
opts.addOption(OptionBuilder.hasArg().withArgName("dir")
.withLongOpt("key-directory")
.withDescription("directory to find key files (default '.').")
.create('D'));
opts.addOption(OptionBuilder.hasArg().withArgName("time/offset")
.withLongOpt("start-time")
.withDescription("signature starting time "
+ "(default is now - 1 hour)").create('s'));
opts.addOption(OptionBuilder.hasArg().withArgName("time/offset")
.withLongOpt("expire-time")
.withDescription("signature expiration time "
+ "(default is start-time + 30 days).").create('e'));
opts.addOption(OptionBuilder.hasArg().withArgName("outfile")
.withDescription("file the signed zone is written to "
+ "(default is <origin>.signed).").create('f'));
opts.addOption(OptionBuilder.hasArg().withArgName("KSK file")
.withLongOpt("ksk-file")
.withDescription("this key is the key signing key.").create('k'));
opts.addOption(OptionBuilder.hasArg().withArgName("file")
.withLongOpt("include-file")
.withDescription("include names in this "
+ "file in the NSEC/NSEC3 chain.").create('I'));
opts.addOption(OptionBuilder.hasArg()
.withArgName("alias:original:mnemonic").withLongOpt("alg-alias")
.withDescription("Define an alias for an algorithm").create('A'));
// NSEC3 options
opts.addOption("3", "use-nsec3", false, "use NSEC3 instead of NSEC");
opts.addOption("O",
"use-opt-in",
false,
"generate a fully Opt-In zone.");
opts.addOption(OptionBuilder.hasArg().withLongOpt("salt")
.withArgName("hex value").withDescription("supply a salt value.")
.create('S'));
opts.addOption(OptionBuilder.hasArg().withLongOpt("random-salt")
.withArgName("length").withDescription("generate a random salt.")
.create('R'));
opts.addOption(OptionBuilder.hasArg().withLongOpt("iterations")
.withArgName("value")
.withDescription("use this value for the iterations in NSEC3.")
.create());
}
public void parseCommandLine(String[] args)
throws org.apache.commons.cli.ParseException, ParseException,
IOException
@@ -99,6 +163,7 @@ public class SignZone
CommandLine cli = cli_parser.parse(opts, args);
String optstr = null;
String[] optstrs = null;
if (cli.hasOption('h')) usage();
@@ -138,6 +203,14 @@ public class SignZone
useOptIn = false;
}
if ((optstrs = cli.getOptionValues('A')) != null)
{
for (int i = 0; i < optstrs.length; i++)
{
addArgAlias(optstrs[i]);
}
}
if (cli.hasOption('F')) fullySignKeyset = true;
if ((optstr = cli.getOptionValue('d')) != null)
@@ -182,15 +255,7 @@ public class SignZone
outputfile = cli.getOptionValue('f');
// FIXME: this is a bit awkward, because we really want -k to repeat,
// but the CLI classes don't do it quite right. Instead we just convert
// our single argument to an array.
String kskFile = cli.getOptionValue('k');
if (kskFile != null)
{
kskFiles = new String[1];
kskFiles[0] = kskFile;
}
kskFiles = cli.getOptionValues('k');
if ((optstr = cli.getOptionValue('I')) != null)
{
@@ -235,74 +300,25 @@ public class SignZone
}
}
/**
* Set up the command line options.
*
* @return a set of command line options.
*/
private void setupCLI()
private void addArgAlias(String s)
{
opts = new Options();
if (s == null) return;
// boolean options
opts.addOption("h", "help", false, "Print this message.");
opts.addOption("a", "verify", false, "verify generated signatures>");
opts.addOption("F",
"fully-sign-keyset",
false,
"sign the zone apex keyset with all available keys.");
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
// Argument options
opts.addOption(OptionBuilder.hasOptionalArg().withLongOpt("verbose")
.withArgName("level").withDescription("verbosity level")
.create('v'));
opts.addOption(OptionBuilder.hasArg().withArgName("dir")
.withLongOpt("keyset-directory")
.withDescription("directory to find keyset files (default '.').")
.create('d'));
opts.addOption(OptionBuilder.hasArg().withArgName("dir")
.withLongOpt("key-directory")
.withDescription("directory to find key files (default '.').")
.create('D'));
opts.addOption(OptionBuilder.hasArg().withArgName("time/offset")
.withLongOpt("start-time")
.withDescription("signature starting time "
+ "(default is now - 1 hour)").create('s'));
opts.addOption(OptionBuilder.hasArg().withArgName("time/offset")
.withLongOpt("expire-time")
.withDescription("signature expiration time "
+ "(default is start-time + 30 days).").create('e'));
opts.addOption(OptionBuilder.hasArg().withArgName("outfile")
.withDescription("file the signed zone is written to "
+ "(default is <origin>.signed).").create('f'));
opts.addOption(OptionBuilder.hasArg()
.withArgName("KSK file").withLongOpt("ksk-file")
.withDescription("this key is the key signing key.")
.create('k'));
opts.addOption(OptionBuilder.hasArg().withArgName("file")
.withLongOpt("include-file")
.withDescription("include names in this "
+ "file in the NSEC/NSEC3 chain.").create('I'));
String[] v = s.split(":");
if (v.length < 2) return;
// NSEC3 options
opts.addOption("3", "use-nsec3", false, "use NSEC3 instead of NSEC");
opts.addOption("O",
"use-opt-in",
false,
"generate a fully Opt-In zone.");
int alias = parseInt(v[0], -1);
if (alias <= 0) return;
int orig = parseInt(v[1], -1);
if (orig <= 0) return;
String mn = null;
if (v.length > 2) mn = v[2];
opts.addOption(OptionBuilder.hasArg().withLongOpt("salt")
.withArgName("hex value").withDescription("supply a salt value.")
.create('S'));
opts.addOption(OptionBuilder.hasArg().withLongOpt("random-salt")
.withArgName("length").withDescription("generate a random salt.")
.create('R'));
opts.addOption(OptionBuilder.hasArg().withLongOpt("iterations")
.withArgName("value")
.withDescription("use this value for the iterations in NSEC3.")
.create());
algs.addAlias(alias, mn, orig);
}
/** Print out the usage and help statements, then quit. */
private void usage()
{

View File

@@ -33,12 +33,7 @@ import org.apache.commons.cli.*;
import org.apache.commons.cli.Options;
import org.xbill.DNS.*;
import com.verisignlabs.dnssec.security.BINDKeyUtils;
import com.verisignlabs.dnssec.security.DnsKeyPair;
import com.verisignlabs.dnssec.security.DnsSecVerifier;
import com.verisignlabs.dnssec.security.RecordComparator;
import com.verisignlabs.dnssec.security.SignUtils;
import com.verisignlabs.dnssec.security.ZoneUtils;
import com.verisignlabs.dnssec.security.*;
/**
* This class forms the command line implementation of a DNSSEC zone
@@ -69,6 +64,40 @@ public class VerifyZone
setupCLI();
}
/**
* Set up the command line options.
*
* @return a set of command line options.
*/
private void setupCLI()
{
opts = new Options();
// boolean options
opts.addOption("h", "help", false, "Print this message.");
opts.addOption("s",
"strict",
false,
"Zone will only be considered valid if all "
+ "signatures could be cryptographically verified");
// Argument options
opts.addOption(OptionBuilder.hasArg().withLongOpt("keydir")
.withArgName("dir").withDescription("directory to find "
+ "trusted key files").create('d'));
opts.addOption(OptionBuilder.hasOptionalArg().withLongOpt("verbose")
.withArgName("level")
.withDescription("verbosity level -- 0 is silence, "
+ "5 is debug information, 6 is trace information.\n"
+ "default is level 5.").create('v'));
opts.addOption(OptionBuilder.hasArg()
.withArgName("alias:original:mnemonic").withLongOpt("alg-alias")
.withDescription("Define an alias for an algorithm").create('A'));
}
public void parseCommandLine(String[] args)
throws org.apache.commons.cli.ParseException
{
@@ -105,6 +134,15 @@ public class VerifyZone
keydir = new File(optstr);
}
String[] optstrs = null;
if ((optstrs = cli.getOptionValues('A')) != null)
{
for (int i = 0; i < optstrs.length; i++)
{
addArgAlias(optstrs[i]);
}
}
String[] cl_args = cli.getArgs();
if (cl_args.length < 1)
@@ -122,40 +160,25 @@ public class VerifyZone
}
}
/**
* Set up the command line options.
*
* @return a set of command line options.
*/
private void setupCLI()
private void addArgAlias(String s)
{
opts = new Options();
// boolean options
opts.addOption("h", "help", false, "Print this message.");
opts.addOption("s",
"strict",
false,
"Zone will only be considered valid if all "
+ "signatures could be cryptographically verified");
// Argument options
OptionBuilder.hasArg();
OptionBuilder.withLongOpt("keydir");
OptionBuilder.withArgName("dir");
OptionBuilder.withDescription("directory to find trusted key files");
opts.addOption(OptionBuilder.create('d'));
OptionBuilder.hasOptionalArg();
OptionBuilder.withLongOpt("verbose");
OptionBuilder.withArgName("level");
OptionBuilder.withDescription("verbosity level -- 0 is silence, "
+ "5 is debug information, 6 is trace information.\n"
+ "default is level 5.");
opts.addOption(OptionBuilder.create('v'));
if (s == null) return;
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
String[] v = s.split(":");
if (v.length < 2) return;
int alias = parseInt(v[0], -1);
if (alias <= 0) return;
int orig = parseInt(v[1], -1);
if (orig <= 0) return;
String mn = null;
if (v.length > 2) mn = v[2];
algs.addAlias(alias, mn, orig);
}
/** Print out the usage and help statements, then quit. */
public void usage()
{
@@ -209,7 +232,9 @@ public class VerifyZone
for (Iterator i = keypairs.iterator(); i.hasNext();)
{
verifier.addTrustedKey((DnsKeyPair) i.next());
DnsKeyPair pair = (DnsKeyPair) i.next();
if (pair.getPublic() == null) continue;
verifier.addTrustedKey(pair);
}
List rrsets = SignUtils.assembleIntoRRsets(records);
@@ -254,16 +279,17 @@ public class VerifyZone
{
zonename = r.getName();
}
if (r.getName().equals(zonename) && r.getType() == Type.DNSKEY)
if (r.getName().equals(zonename) && r.getType() == Type.DNSKEY)
{
DnsKeyPair pair = new DnsKeyPair((DNSKEYRecord) r);
res.add(pair);
}
}
return res;
}
private static List getTrustedKeys(String[] keyfiles, File inDirectory)
throws IOException
{
@@ -283,7 +309,6 @@ public class VerifyZone
public static void execute(CLIState state) throws Exception
{
List records = ZoneUtils.readZoneFile(state.zonefile, null);
List keypairs = null;
if (state.keyfiles != null)