update to dnsjava-2.0.0; refactor command line parseing a bit; switch to java.util.logging

git-svn-id: https://svn.verisignlabs.com/jdnssec/tools/trunk@16 4cbd57fe-54e5-0310-bd9a-f30fe5ea5e6e
This commit is contained in:
David Blacka
2005-08-14 02:08:48 +00:00
parent 0d5aed62b6
commit 4b84bbf4db
18 changed files with 1899 additions and 1860 deletions

View File

@@ -1,4 +1,4 @@
// $Id: BINDKeyUtils.java,v 1.5 2004/02/25 20:46:14 davidb Exp $
// $Id$
//
// Copyright (C) 2001-2003 VeriSign, Inc.
//
@@ -19,22 +19,35 @@
package com.verisignlabs.dnssec.security;
import java.io.*;
import java.security.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.text.NumberFormat;
import org.xbill.DNS.*;
import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.Master;
import org.xbill.DNS.Name;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
import org.xbill.DNS.utils.base64;
/** This class contains a series of static methods used for
* manipulating BIND 9.x.x-style DNSSEC key files.
*
* In this class, the "base" key path or name is the file name
* without the trailing ".key" or ".private".
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 1.5 $
/**
* This class contains a series of static methods used for manipulating BIND
* 9.x.x-style DNSSEC key files.
*
* In this class, the "base" key path or name is the file name without the
* trailing ".key" or ".private".
*
* @author David Blacka (original)
* @author $Author$
* @version $Revision$
*/
public class BINDKeyUtils
{
@@ -42,10 +55,11 @@ public class BINDKeyUtils
private static NumberFormat mAlgNumberFormatter;
private static NumberFormat mKeyIdNumberFormatter;
/** Calculate the BIND9 key file base name (i.e., without the ".key"
* or ".private" extensions) */
private static String getKeyFileBase(Name signer, int algorithm,
int keyid)
/**
* Calculate the BIND9 key file base name (i.e., without the ".key" or
* ".private" extensions)
*/
private static String getKeyFileBase(Name signer, int algorithm, int keyid)
{
if (mAlgNumberFormatter == null)
{
@@ -64,24 +78,22 @@ public class BINDKeyUtils
keyid &= 0xFFFF;
String fn = "K" + signer + "+" +
mAlgNumberFormatter.format(algorithm) +
"+" +
mKeyIdNumberFormatter.format(keyid);
String fn = "K" + signer + "+" + mAlgNumberFormatter.format(algorithm)
+ "+" + mKeyIdNumberFormatter.format(keyid);
return fn;
}
/** Reads in the KEYRecord from the public key file */
/** Reads in the DNSKEYRecord from the public key file */
private static DNSKEYRecord loadPublicKeyFile(File publicKeyFile)
throws IOException
throws IOException
{
Master m = new Master(publicKeyFile.getAbsolutePath(), null, 600);
Record r;
DNSKEYRecord result = null;
while ( (r = m.nextRecord()) != null )
while ((r = m.nextRecord()) != null)
{
if (r.getType() == Type.DNSKEY)
{
@@ -94,14 +106,14 @@ public class BINDKeyUtils
/** Reads in the private key verbatim from the private key file */
private static String loadPrivateKeyFile(File privateKeyFile)
throws IOException
throws IOException
{
BufferedReader in = new BufferedReader(new FileReader(privateKeyFile));
StringBuffer key_buf = new StringBuffer();
StringBuffer key_buf = new StringBuffer();
String line;
while ( (line = in.readLine()) != null)
while ((line = in.readLine()) != null)
{
key_buf.append(line);
key_buf.append('\n');
@@ -110,57 +122,56 @@ public class BINDKeyUtils
return key_buf.toString().trim();
}
/** Given an actual path for one of the key files, return the base
* name */
/**
* Given an actual path for one of the key files, return the base name
*/
private static String fixKeyFileBasePath(String basePath)
{
if (basePath == null) throw new IllegalArgumentException();
if (basePath.endsWith(".key") ||
basePath.endsWith(".private"))
if (basePath.endsWith(".key") || basePath.endsWith(".private"))
{
basePath = basePath.substring
(0, basePath.lastIndexOf("."));
basePath = basePath.substring(0, basePath.lastIndexOf("."));
}
return basePath;
}
/** Given the information necessary to construct the path to a BIND9
* generated key pair, load the key pair.
*
* @param signer the DNS name of the key.
* @param algorithm the DNSSEC algorithm of the key.
* @param keyid the DNSSEC key footprint.
* @param inDirectory the directory to look for the files (may be
* null).
* @return the loaded key pair.
* @throws IOException if there was a problem reading the BIND9
* files. */
public static DnsKeyPair loadKeyPair(Name signer, int algorithm,
int keyid, File inDirectory)
throws IOException
/**
* Given the information necessary to construct the path to a BIND9
* generated key pair, load the key pair.
*
* @param signer the DNS name of the key.
* @param algorithm the DNSSEC algorithm of the key.
* @param keyid the DNSSEC key footprint.
* @param inDirectory the directory to look for the files (may be null).
* @return the loaded key pair.
* @throws IOException if there was a problem reading the BIND9 files.
*/
public static DnsKeyPair loadKeyPair(Name signer, int algorithm, int keyid,
File inDirectory) throws IOException
{
String keyFileBase = getKeyFileBase(signer, algorithm, keyid);
return loadKeyPair(keyFileBase, inDirectory);
}
/** Given a base path to a BIND9 key pair, load the key pair.
*
* @param keyFileBasePath the base filename (or real filename for
* either the public or private key) of the key.
* @param inDirectory the directory to look in, if the
* keyFileBasePath is relative.
* @return the loaded key pair.
* @throws IOException if there was a problem reading the files */
/**
* Given a base path to a BIND9 key pair, load the key pair.
*
* @param keyFileBasePath the base filename (or real filename for either the
* public or private key) of the key.
* @param inDirectory the directory to look in, if the keyFileBasePath is
* relative.
* @return the loaded key pair.
* @throws IOException if there was a problem reading the files
*/
public static DnsKeyPair loadKeyPair(String keyFileBasePath,
File inDirectory)
throws IOException
File inDirectory) throws IOException
{
keyFileBasePath = fixKeyFileBasePath(keyFileBasePath);
// FIXME: should we throw the IOException when one of the files
// cannot be found, or just when both cannot be found?
File publicKeyFile = new File(inDirectory, keyFileBasePath + ".key");
File publicKeyFile = new File(inDirectory, keyFileBasePath + ".key");
File privateKeyFile = new File(inDirectory, keyFileBasePath + ".private");
DnsKeyPair kp = new DnsKeyPair();
@@ -174,23 +185,22 @@ public class BINDKeyUtils
return kp;
}
/** Given a base path to a BIND9 key pair, load the public part
* (only) of the key pair
*
* @param keyFileBasePath the base or real path to the public part
* of a key pair.
* @param inDirectory the directory to look in if the path is
* relative (may be null).
* @return a {@link DnsKeyPair} containing just the public key
* information.
* @throws IOException if there was a problem reading the public
* key file.
/**
* Given a base path to a BIND9 key pair, load the public part (only) of the
* key pair
*
* @param keyFileBasePath the base or real path to the public part of a key
* pair.
* @param inDirectory the directory to look in if the path is relative (may
* be null).
* @return a {@link DnsKeyPair} containing just the public key information.
* @throws IOException if there was a problem reading the public key file.
*/
public static DnsKeyPair loadKey(String keyFileBasePath, File inDirectory)
throws IOException
throws IOException
{
keyFileBasePath = fixKeyFileBasePath(keyFileBasePath);
File publicKeyFile = new File(inDirectory, keyFileBasePath + ".key");
File publicKeyFile = new File(inDirectory, keyFileBasePath + ".key");
DnsKeyPair kp = new DnsKeyPair();
@@ -200,21 +210,19 @@ public class BINDKeyUtils
return kp;
}
/** Load a BIND keyset file. The BIND 9 dnssec tools typically call
* these files "keyset-[signer]." where [signer] is the DNS owner
* name of the key. The keyset may be signed, but doesn't have to
* be.
*
* @param keysetFileName the name of the keyset file.
* @param inDirectory the directory to look in if the path is
* relative (may be null, defaults to the current working
* directory).
* @return a RRset contain the KEY records and any associated SIG records.
* @throws IOException if there was a problem reading the keyset
* file.
/**
* Load a BIND keyset file. The BIND 9 dnssec tools typically call these
* files "keyset-[signer]." where [signer] is the DNS owner name of the key.
* The keyset may be signed, but doesn't have to be.
*
* @param keysetFileName the name of the keyset file.
* @param inDirectory the directory to look in if the path is relative (may
* be null, defaults to the current working directory).
* @return a RRset contain the KEY records and any associated SIG records.
* @throws IOException if there was a problem reading the keyset file.
*/
public static RRset loadKeySet(String keysetFileName, File inDirectory)
throws IOException
throws IOException
{
File keysetFile = new File(inDirectory, keysetFileName);
@@ -222,7 +230,7 @@ public class BINDKeyUtils
Record r;
RRset keyset = new RRset();
while ( (r = m.nextRecord()) != null )
while ((r = m.nextRecord()) != null)
{
keyset.addRR(r);
}
@@ -230,11 +238,12 @@ public class BINDKeyUtils
return keyset;
}
/** Calculate the key file base for this key pair.
*
* @param pair the {@link DnsKeyPair} to work from. It only needs a public
* key.
* @return the base name of the key files.
/**
* Calculate the key file base for this key pair.
*
* @param pair the {@link DnsKeyPair} to work from. It only needs a public
* key.
* @return the base name of the key files.
*/
public static String keyFileBase(DnsKeyPair pair)
{
@@ -242,13 +251,14 @@ public class BINDKeyUtils
if (keyrec == null) return null;
return getKeyFileBase(keyrec.getName(),
keyrec.getAlgorithm(),
keyrec.getFootprint());
keyrec.getAlgorithm(),
keyrec.getFootprint());
}
/** @return a {@link java.io.File} object representing the BIND9
* public key file. */
/**
* @return a {@link java.io.File} object representing the BIND9 public key
* file.
*/
public static File getPublicKeyFile(DnsKeyPair pair, File inDirectory)
{
String keyfilebase = keyFileBase(pair);
@@ -257,8 +267,10 @@ public class BINDKeyUtils
return new File(inDirectory, keyfilebase + ".key");
}
/** @return a {@link java.io.File} object representing the BIND9
* private key file */
/**
* @return a {@link java.io.File} object representing the BIND9 private key
* file
*/
public static File getPrivateKeyFile(DnsKeyPair pair, File inDirectory)
{
String keyfilebase = keyFileBase(pair);
@@ -267,11 +279,12 @@ public class BINDKeyUtils
return new File(inDirectory, keyfilebase + ".private");
}
/** Given a the contents of a BIND9 private key file, convert it
* into a native {@link java.security.PrivateKey} object.
* @param privateKeyString the contents of a BIND9 key file in
* string form.
* @return a {@link java.security.PrivateKey}
/**
* Given a the contents of a BIND9 private key file, convert it into a
* native {@link java.security.PrivateKey} object.
*
* @param privateKeyString the contents of a BIND9 key file in string form.
* @return a {@link java.security.PrivateKey}
*/
public static PrivateKey convertPrivateKeyString(String privateKeyString)
{
@@ -296,24 +309,24 @@ public class BINDKeyUtils
return null;
}
/** Given a native private key, convert it into a BIND9 private key
* file format.
* @param priv the private key to convert.
* @param pub the private key's corresponding public key. Some
* algorithms require information from both.
* @return a string containing the contents of a BIND9 private key
* file.
/**
* Given a native private key, convert it into a BIND9 private key file
* format.
*
* @param priv the private key to convert.
* @param pub the private key's corresponding public key. Some algorithms
* require information from both.
* @return a string containing the contents of a BIND9 private key file.
*/
public static String convertPrivateKey(PrivateKey priv, PublicKey pub,
int alg)
int alg)
{
if (priv != null)
{
// debug
// System.out.println("converting from privatekey to bind9 string");
DnsKeyConverter keyconv = new DnsKeyConverter();
String priv_string
= keyconv.generatePrivateKeyString(priv, pub, alg);
String priv_string = keyconv.generatePrivateKeyString(priv, pub, alg);
return priv_string;
}
@@ -321,11 +334,12 @@ public class BINDKeyUtils
return null;
}
/** Convert the KEY record to the exact string format that the
* dnssec-* routines need. Currently, the DNSJAVA package uses a
* multiline mode for its record formatting. The BIND9 tools
* require everything on a single line. */
/**
* Convert the KEY record to the exact string format that the dnssec-*
* routines need. Currently, the DNSJAVA package uses a multiline mode for
* its record formatting. The BIND9 tools require everything on a single
* line.
*/
private static String DNSKEYtoString(DNSKEYRecord rec)
{
StringBuffer buf = new StringBuffer();
@@ -343,34 +357,33 @@ public class BINDKeyUtils
return buf.toString();
}
/** This routine will write out the BIND9 dnssec-* tool compatible
* files.
*
* @param baseFileName use this base file name. If null, the
* standard BIND9 base file name will be computed.
* @param pair the keypair in question.
* @param inDirectory the directory to write to (may be null).
* @throws IOException if there is a problem writing the files.
/**
* This routine will write out the BIND9 dnssec-* tool compatible files.
*
* @param baseFileName use this base file name. If null, the standard BIND9
* base file name will be computed.
* @param pair the keypair in question.
* @param inDirectory the directory to write to (may be null).
* @throws IOException if there is a problem writing the files.
*/
public static void writeKeyFiles(String baseFileName, DnsKeyPair pair,
File inDirectory)
throws IOException
File inDirectory) throws IOException
{
DNSKEYRecord pub = pair.getDNSKEYRecord();
String priv = pair.getPrivateKeyString();
DNSKEYRecord pub = pair.getDNSKEYRecord();
String priv = pair.getPrivateKeyString();
if (priv == null)
{
priv = convertPrivateKey(pair.getPrivate(), pair.getPublic(),
pair.getDNSKEYAlgorithm());
priv = convertPrivateKey(pair.getPrivate(),
pair.getPublic(),
pair.getDNSKEYAlgorithm());
}
if (pub == null || priv == null) return;
// Write the public key file
File pubkeyfile = new File(inDirectory, baseFileName + ".key");
PrintWriter out
= new PrintWriter(new FileWriter(pubkeyfile));
PrintWriter out = new PrintWriter(new FileWriter(pubkeyfile));
out.println(DNSKEYtoString(pub));
out.close();
@@ -382,14 +395,15 @@ public class BINDKeyUtils
}
/** This routine will write out the BIND9 dnssec-* tool compatible
* files to the standard file names.
*
* @param pair the key pair in question.
* @param inDirectory the directory to write to (may be null).
/**
* This routine will write out the BIND9 dnssec-* tool compatible files to
* the standard file names.
*
* @param pair the key pair in question.
* @param inDirectory the directory to write to (may be null).
*/
public static void writeKeyFiles(DnsKeyPair pair, File inDirectory)
throws IOException
throws IOException
{
String base = keyFileBase(pair);
writeKeyFiles(base, pair, inDirectory);

View File

@@ -1,4 +1,4 @@
// $Id: ByteArrayComparator.java,v 1.2 2004/02/25 20:46:14 davidb Exp $
// $Id$
//
// Copyright (C) 2001-2003 VeriSign, Inc.
//
@@ -18,31 +18,32 @@
package com.verisignlabs.dnssec.security;
import java.util.*;
import java.util.Comparator;
/** This class implements a basic comparitor for byte arrays. It is
* primarily useful for comparing RDATA portions of DNS records in
* doing DNSSEC canonical ordering.
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 1.2 $
/**
* This class implements a basic comparitor for byte arrays. It is primarily
* useful for comparing RDATA portions of DNS records in doing DNSSEC
* canonical ordering.
*
* @author David Blacka (original)
* @author $Author$
* @version $Revision$
*/
public class ByteArrayComparator implements Comparator
{
private int mOffset = 0;
private boolean mDebug = false;
private int mOffset = 0;
private boolean mDebug = false;
public ByteArrayComparator()
{}
{
}
public ByteArrayComparator(int offset, boolean debug)
{
mOffset = offset;
mDebug = debug;
}
public int compare(Object o1, Object o2) throws ClassCastException
{
byte[] b1 = (byte[]) o1;
@@ -52,12 +53,12 @@ public class ByteArrayComparator implements Comparator
{
if (b1[i] != b2[i])
{
if (mDebug)
{
System.out.println("offset " + i + " differs (this is " +
(i - mOffset) +" bytes in from our offset.)");
}
return (b1[i] & 0xFF) - (b2[i] & 0xFF);
if (mDebug)
{
System.out.println("offset " + i + " differs (this is "
+ (i - mOffset) + " bytes in from our offset.)");
}
return (b1[i] & 0xFF) - (b2[i] & 0xFF);
}
}

View File

@@ -1,4 +1,4 @@
// $Id: DnsKeyConverter.java,v 1.4 2004/02/23 15:06:15 davidb Exp $
// $Id$
//
// Copyright (C) 2001-2003 VeriSign, Inc.
//
@@ -18,33 +18,51 @@
package com.verisignlabs.dnssec.security;
import java.io.*;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import javax.crypto.spec.DHPrivateKeySpec;
import javax.crypto.spec.DHParameterSpec;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.StringTokenizer;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import java.security.interfaces.*;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPrivateKeySpec;
import org.xbill.DNS.*;
import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.DNSSEC;
import org.xbill.DNS.KEYRecord;
import org.xbill.DNS.Name;
import org.xbill.DNS.security.KEYConverter;
import org.xbill.DNS.utils.base64;
/** This class handles conversions between JCA key formats and DNSSEC
* and BIND9 key formats.
*
* @author David Blacka (original)
* @author $Author: davidb $ (latest)
* @version $Revision: 1.4 $
/**
* This class handles conversions between JCA key formats and DNSSEC and BIND9
* key formats.
*
* @author David Blacka (original)
* @author $Author$ (latest)
* @version $Revision$
*/
public class DnsKeyConverter
{
private KeyFactory mRSAKeyFactory;
private KeyFactory mDSAKeyFactory;
private KeyFactory mDHKeyFactory;
private KeyFactory mRSAKeyFactory;
private KeyFactory mDSAKeyFactory;
private KeyFactory mDHKeyFactory;
public DnsKeyConverter()
{
@@ -54,35 +72,35 @@ public class DnsKeyConverter
public PublicKey parseDNSKEYRecord(DNSKEYRecord pKeyRecord)
{
if (pKeyRecord.getKey() == null) return null;
return KEYConverter.parseRecord(pKeyRecord);
}
/** Given a JCA public key and the ancillary data, generate a DNSKEY
* record. */
public DNSKEYRecord generateDNSKEYRecord(Name name,
int dclass,
long ttl,
int flags,
int alg,
PublicKey key)
/**
* Given a JCA public key and the ancillary data, generate a DNSKEY record.
*/
public DNSKEYRecord generateDNSKEYRecord(Name name, int dclass, long ttl,
int flags, int alg, PublicKey key)
{
// FIXME: currenty org.xbill.DNS.security.KEYConverter will only
// convert to KEYRecords, and even then, assume that an RSA
// PublicKey means alg 1.
KEYRecord kr = KEYConverter.buildRecord(name, dclass, ttl, flags,
KEYRecord.PROTOCOL_DNSSEC, key);
KEYRecord kr = KEYConverter.buildRecord(name,
dclass,
ttl,
flags,
KEYRecord.PROTOCOL_DNSSEC,
key);
return new DNSKEYRecord(name, dclass, ttl, flags,
DNSKEYRecord.Protocol.DNSSEC, alg,
kr.getKey());
DNSKEYRecord.Protocol.DNSSEC, alg, kr.getKey());
}
// Private Key Specific Parsing routines
/** Convert a PKCS#8 encoded private key into a PrivateKey
* object. */
/**
* Convert a PKCS#8 encoded private key into a PrivateKey object.
*/
public PrivateKey convertEncodedPrivateKey(byte[] key, int algorithm)
{
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key);
@@ -91,24 +109,24 @@ public class DnsKeyConverter
{
switch (algorithm)
{
case DNSSEC.RSAMD5:
case DNSSEC.RSASHA1:
return mRSAKeyFactory.generatePrivate(spec);
case DNSSEC.DSA:
return mDSAKeyFactory.generatePrivate(spec);
case DNSSEC.RSAMD5 :
case DNSSEC.RSASHA1 :
return mRSAKeyFactory.generatePrivate(spec);
case DNSSEC.DSA :
return mDSAKeyFactory.generatePrivate(spec);
}
}
catch (GeneralSecurityException e)
{
}
{}
return null;
}
/** @return a JCA private key, given a BIND9-style textual
* encoding */
public PrivateKey parsePrivateKeyString(String key)
throws IOException, NoSuchAlgorithmException
/**
* @return a JCA private key, given a BIND9-style textual encoding
*/
public PrivateKey parsePrivateKeyString(String key) throws IOException,
NoSuchAlgorithmException
{
StringTokenizer lines = new StringTokenizer(key, "\n");
@@ -124,7 +142,7 @@ public class DnsKeyConverter
if (line.startsWith("Private-key-format: "))
{
if (! val.equals("v1.2"))
if (!val.equals("v1.2"))
{
throw new IOException("unsupported private key format: " + val);
}
@@ -141,8 +159,10 @@ public class DnsKeyConverter
return null;
}
/** @return the value part of an "attribute:value" pair. The value
* is trimmed. */
/**
* @return the value part of an "attribute:value" pair. The value is
* trimmed.
*/
private String value(String av)
{
if (av == null) return null;
@@ -155,41 +175,23 @@ public class DnsKeyConverter
return av.substring(pos + 1).trim();
}
/** prints the bytes of an original byte array and the BigInteger
* copy */
private void printBigIntCompare(byte[] orig, BigInteger copy)
{
byte[] copy_bytes = copy.toByteArray();
for (int i = 0; i < 10 && i < orig.length; i++) {
System.err.print((int) orig[i] & 0xFF);
System.err.print(" ");
}
System.err.println();
for (int i = 0; i < 10 && i < copy_bytes.length; i++) {
System.err.print((int) copy_bytes[i] & 0xFF);
System.err.print(" ");
}
System.err.println();
}
/** Given the rest of the RSA BIND9 string format private key, parse
* and translate into a JCA private key
*
* @throws NoSuchAlgorithmException if the RSA algorithm is not
* available. */
/**
* Given the rest of the RSA BIND9 string format private key, parse and
* translate into a JCA private key
*
* @throws NoSuchAlgorithmException if the RSA algorithm is not available.
*/
private PrivateKey parsePrivateRSA(StringTokenizer lines)
throws NoSuchAlgorithmException
throws NoSuchAlgorithmException
{
BigInteger modulus = null;
BigInteger public_exponent = null;
BigInteger modulus = null;
BigInteger public_exponent = null;
BigInteger private_exponent = null;
BigInteger prime_p = null;
BigInteger prime_q = null;
BigInteger prime_p = null;
BigInteger prime_q = null;
BigInteger prime_p_exponent = null;
BigInteger prime_q_exponent = null;
BigInteger coefficient = null;
BigInteger coefficient = null;
while (lines.hasMoreTokens())
{
@@ -203,26 +205,41 @@ public class DnsKeyConverter
byte[] data = base64.fromString(val);
if (line.startsWith("Modulus: ")) {
if (line.startsWith("Modulus: "))
{
modulus = new BigInteger(1, data);
// printBigIntCompare(data, modulus);
} else if (line.startsWith("PublicExponent: ")) {
}
else if (line.startsWith("PublicExponent: "))
{
public_exponent = new BigInteger(1, data);
// printBigIntCompare(data, public_exponent);
} else if (line.startsWith("PrivateExponent: ")) {
}
else if (line.startsWith("PrivateExponent: "))
{
private_exponent = new BigInteger(1, data);
// printBigIntCompare(data, private_exponent);
} else if (line.startsWith("Prime1: ")) {
}
else if (line.startsWith("Prime1: "))
{
prime_p = new BigInteger(1, data);
// printBigIntCompare(data, prime_p);
} else if (line.startsWith("Prime2: ")) {
}
else if (line.startsWith("Prime2: "))
{
prime_q = new BigInteger(1, data);
// printBigIntCompare(data, prime_q);
} else if (line.startsWith("Exponent1: ")) {
}
else if (line.startsWith("Exponent1: "))
{
prime_p_exponent = new BigInteger(1, data);
} else if (line.startsWith("Exponent2: ")) {
}
else if (line.startsWith("Exponent2: "))
{
prime_q_exponent = new BigInteger(1, data);
} else if (line.startsWith("Coefficient: ")) {
}
else if (line.startsWith("Coefficient: "))
{
coefficient = new BigInteger(1, data);
}
}
@@ -230,9 +247,8 @@ public class DnsKeyConverter
try
{
KeySpec spec = new RSAPrivateCrtKeySpec(modulus, public_exponent,
private_exponent, prime_p,
prime_q, prime_p_exponent,
prime_q_exponent, coefficient);
private_exponent, prime_p, prime_q, prime_p_exponent,
prime_q_exponent, coefficient);
if (mRSAKeyFactory == null)
{
mRSAKeyFactory = KeyFactory.getInstance("RSA");
@@ -246,13 +262,14 @@ public class DnsKeyConverter
}
}
/** Given the remaining lines in a BIND9 style DH private key, parse
* the key info and translate it into a JCA private key.
*
* @throws NoSuchAlgorithmException if the DH algorithm is not
* available. */
/**
* Given the remaining lines in a BIND9 style DH private key, parse the key
* info and translate it into a JCA private key.
*
* @throws NoSuchAlgorithmException if the DH algorithm is not available.
*/
private PrivateKey parsePrivateDH(StringTokenizer lines)
throws NoSuchAlgorithmException
throws NoSuchAlgorithmException
{
BigInteger p = null;
BigInteger x = null;
@@ -270,11 +287,16 @@ public class DnsKeyConverter
byte[] data = base64.fromString(val);
if (line.startsWith("Prime(p): ")) {
if (line.startsWith("Prime(p): "))
{
p = new BigInteger(1, data);
} else if (line.startsWith("Generator(g): ")) {
}
else if (line.startsWith("Generator(g): "))
{
g = new BigInteger(1, data);
} else if (line.startsWith("Private_value(x): ")) {
}
else if (line.startsWith("Private_value(x): "))
{
x = new BigInteger(1, data);
}
}
@@ -295,13 +317,14 @@ public class DnsKeyConverter
}
}
/** Given the remaining lines in a BIND9 style DSA private key,
* parse the key info and translate it into a JCA private key.
*
* @throws NoSuchAlgorithmException if the DSA algorithm is not
* available. */
/**
* Given the remaining lines in a BIND9 style DSA private key, parse the key
* info and translate it into a JCA private key.
*
* @throws NoSuchAlgorithmException if the DSA algorithm is not available.
*/
private PrivateKey parsePrivateDSA(StringTokenizer lines)
throws NoSuchAlgorithmException
throws NoSuchAlgorithmException
{
BigInteger p = null;
BigInteger q = null;
@@ -320,13 +343,20 @@ public class DnsKeyConverter
byte[] data = base64.fromString(val);
if (line.startsWith("Prime(p): ")) {
if (line.startsWith("Prime(p): "))
{
p = new BigInteger(1, data);
} else if (line.startsWith("Subprime(q): ")) {
}
else if (line.startsWith("Subprime(q): "))
{
q = new BigInteger(1, data);
} else if (line.startsWith("Base(g): ")) {
}
else if (line.startsWith("Base(g): "))
{
g = new BigInteger(1, data);
} else if (line.startsWith("Private_value(x): ")) {
}
else if (line.startsWith("Private_value(x): "))
{
x = new BigInteger(1, data);
}
}
@@ -347,22 +377,22 @@ public class DnsKeyConverter
}
}
/** Given a private key and public key, generate the BIND9 style
* private key format. */
/**
* Given a private key and public key, generate the BIND9 style private key
* format.
*/
public String generatePrivateKeyString(PrivateKey priv, PublicKey pub,
int alg)
int alg)
{
if (priv instanceof RSAPrivateCrtKey)
{
return generatePrivateRSA((RSAPrivateCrtKey) priv, alg);
}
else if (priv instanceof DSAPrivateKey &&
pub instanceof DSAPublicKey)
else if (priv instanceof DSAPrivateKey && pub instanceof DSAPublicKey)
{
return generatePrivateDSA((DSAPrivateKey) priv, (DSAPublicKey) pub);
}
else if (priv instanceof DHPrivateKey &&
pub instanceof DHPublicKey)
else if (priv instanceof DHPrivateKey && pub instanceof DHPublicKey)
{
return generatePrivateDH((DHPrivateKey) priv, (DHPublicKey) pub);
}
@@ -370,8 +400,9 @@ public class DnsKeyConverter
return null;
}
/** Convert from 'unsigned' big integer to original 'signed format'
* in Base64 */
/**
* Convert from 'unsigned' big integer to original 'signed format' in Base64
*/
private String b64BigInt(BigInteger i)
{
byte[] orig_bytes = i.toByteArray();
@@ -387,8 +418,10 @@ public class DnsKeyConverter
return base64.toString(signed_bytes);
}
/** Given a RSA private key (in Crt format), return the BIND9-style
* text encoding. */
/**
* Given a RSA private key (in Crt format), return the BIND9-style text
* encoding.
*/
private String generatePrivateRSA(RSAPrivateCrtKey key, int algorithm)
{
StringWriter sw = new StringWriter();

View File

@@ -1,4 +1,4 @@
// $Id: DnsKeyPair.java,v 1.3 2004/01/16 21:07:09 davidb Exp $
// $Id$
//
// Copyright (C) 2001-2003 VeriSign, Inc.
//
@@ -20,73 +20,74 @@ package com.verisignlabs.dnssec.security;
import java.security.*;
import java.security.interfaces.*;
import java.util.logging.Logger;
import org.xbill.DNS.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** This class forms the basis for representing public/private key
* pairs in a DNSSEC context. It is possible to get a JCA public and
* private key from this object, as well as a KEYRecord encoding of
* the public key. This class is implemented as a UNION of all the
* functionality needed for handing native java, BIND, and possibly
* other underlying KEY engines.
*
* JCA == Java Cryptography Architecture.
*
* @author David Blacka (orig)
* @author $Author: davidb $ (latest)
* @version $Revision: 1.3 $
/**
* This class forms the basis for representing public/private key pairs in a
* DNSSEC context. It is possible to get a JCA public and private key from
* this object, as well as a DNSKEYRecord encoding of the public key. This
* class is implemented as a UNION of all the functionality needed for handing
* native java, BIND, and possibly other underlying DNSKEY engines.
*
* JCA == Java Cryptography Architecture.
*
* @author David Blacka (orig)
* @author $Author$ (latest)
* @version $Revision$
*/
// FIXME: this class is not a generic DnsKeyPair at all. It is really
// a JCEDnsKeyPair. We probably need to reexamine the class design here.
// NOTE: this class is designed to do "lazy" evaluation of it's
// various cached objects and format conversions, so methods should
// avoid direct access to the member variables.
public class DnsKeyPair
{
/** This is the real (base) encoding of the public key. */
protected DNSKEYRecord mPublicKeyRecord;
protected DNSKEYRecord mPublicKeyRecord;
/** This is a precalcuated cache of the KEYRecord converted into a
* JCA public key. */
private PublicKey mPublicKey;
/**
* This is a precalcuated cache of the KEYRecord converted into a JCA public
* key.
*/
private PublicKey mPublicKey;
/** The private key in Base64 encoded format. This version is
* presumed to be opaque, so no attempts will be made to convert it
* to a JCA private key. */
protected String mPrivateKeyString;
/** The private key in JCA format. This is the base encoding for
* instances were JCA private keys are used. */
protected PrivateKey mPrivateKey;
/**
* The private key in Base64 encoded format. This version is presumed to be
* opaque, so no attempts will be made to convert it to a JCA private key.
*/
protected String mPrivateKeyString;
/**
* The private key in JCA format. This is the base encoding for instances
* were JCA private keys are used.
*/
protected PrivateKey mPrivateKey;
/** The local key converter. */
protected DnsKeyConverter mKeyConverter;
/** a cached Signature used for signing (initialized with the
* private key) */
protected Signature mSigner;
/**
* a cached Signature used for signing (initialized with the private key)
*/
protected Signature mSigner;
/** a caches Signature used for verifying (intialized with the
* public key) */
protected Signature mVerifier;
/**
* a caches Signature used for verifying (intialized with the public key)
*/
protected Signature mVerifier;
private Logger log;
private Log log;
public DnsKeyPair()
{
log = LogFactory.getLog(this.getClass());
log = Logger.getLogger(this.getClass().toString());
}
public DnsKeyPair(DNSKEYRecord keyRecord, PrivateKey privateKey)
{
this();
setDNSKEYRecord(keyRecord);
setPrivate(privateKey);
}
@@ -94,19 +95,23 @@ public class DnsKeyPair
public DnsKeyPair(DNSKEYRecord keyRecord, String privateKeyString)
{
this();
setDNSKEYRecord(keyRecord);
setPrivateKeyString(privateKeyString);
}
public DnsKeyPair(Name keyName, int algorithm, PublicKey publicKey,
PrivateKey privateKey)
PrivateKey privateKey)
{
this();
DnsKeyConverter conv = new DnsKeyConverter();
DNSKEYRecord keyrec = conv.generateDNSKEYRecord(keyName, DClass.IN, 0, 0,
algorithm, publicKey);
DNSKEYRecord keyrec = conv.generateDNSKEYRecord(keyName,
DClass.IN,
0,
0,
algorithm,
publicKey);
setDNSKEYRecord(keyrec);
setPrivate(privateKey);
}
@@ -114,7 +119,7 @@ public class DnsKeyPair
public DnsKeyPair(DnsKeyPair pair)
{
this();
setDNSKEYRecord(pair.getDNSKEYRecord());
setPrivate(pair.getPrivate());
setPrivateKeyString(pair.getPrivateKeyString());
@@ -130,7 +135,7 @@ public class DnsKeyPair
return mKeyConverter;
}
/** @return the appropriate Signature object for this keypair. */
protected Signature getSignature()
{
@@ -143,30 +148,31 @@ public class DnsKeyPair
{
switch (getDNSKEYAlgorithm())
{
case DNSSEC.RSAMD5:
s = Signature.getInstance("MD5withRSA");
break;
case DNSSEC.DSA:
s = Signature.getInstance("SHA1withDSA");
break;
case DNSSEC.RSASHA1:
s = Signature.getInstance("SHA1withRSA");
break;
case -1:
s = null;
break;
case DNSSEC.RSAMD5 :
s = Signature.getInstance("MD5withRSA");
break;
case DNSSEC.DSA :
s = Signature.getInstance("SHA1withDSA");
break;
case DNSSEC.RSASHA1 :
s = Signature.getInstance("SHA1withRSA");
break;
case -1 :
s = null;
break;
}
}
catch (NoSuchAlgorithmException e)
{
log.error("error getting Signature object", e);
log.severe("error getting Signature object: " + e);
}
return s;
}
/** @return the public key, translated from the KEYRecord, if
* necessary. */
/**
* @return the public key, translated from the KEYRecord, if necessary.
*/
public PublicKey getPublic()
{
if (mPublicKey == null && getDNSKEYRecord() != null)
@@ -178,9 +184,9 @@ public class DnsKeyPair
return mPublicKey;
}
/** sets the public key. This method is generally not used
* directly. */
/**
* sets the public key. This method is generally not used directly.
*/
protected void setPublic(PublicKey k)
{
mPublicKey = k;
@@ -205,17 +211,19 @@ public class DnsKeyPair
mPrivateKey = k;
}
/** @return the opaque private key string, null if one doesn't
* exist. */
/**
* @return the opaque private key string, null if one doesn't exist.
*/
public String getPrivateKeyString()
{
if (mPrivateKeyString == null && mPrivateKey != null)
{
PublicKey pub = getPublic();
mPrivateKeyString = BINDKeyUtils.convertPrivateKey(mPrivateKey, pub,
getDNSKEYAlgorithm());
mPrivateKeyString = BINDKeyUtils.convertPrivateKey(mPrivateKey,
pub,
getDNSKEYAlgorithm());
}
return mPrivateKeyString;
}
@@ -224,7 +232,7 @@ public class DnsKeyPair
{
mPrivateKeyString = p;
}
/** @return the private key in an encoded form (normally PKCS#8). */
public byte[] getEncodedPrivate()
{
@@ -233,11 +241,13 @@ public class DnsKeyPair
return null;
}
/** Sets the private key from the encoded form (PKCS#8). This
* routine requires that the public key already be assigned.
* Currently it can only handle DSA and RSA keys. */
/**
* Sets the private key from the encoded form (PKCS#8). This routine
* requires that the public key already be assigned. Currently it can only
* handle DSA and RSA keys.
*/
public void setEncodedPrivate(byte[] encoded)
{
{
int alg = getDNSKEYAlgorithm();
if (alg >= 0)
@@ -246,15 +256,17 @@ public class DnsKeyPair
setPrivate(conv.convertEncodedPrivateKey(encoded, alg));
}
}
/** @return the public DNSKEY record */
public DNSKEYRecord getDNSKEYRecord()
{
return mPublicKeyRecord;
}
/** @return a Signature object initialized for signing, or null if
* this key pair does not have a valid private key. */
/**
* @return a Signature object initialized for signing, or null if this key
* pair does not have a valid private key.
*/
public Signature getSigner()
{
if (mSigner == null)
@@ -263,27 +275,29 @@ public class DnsKeyPair
PrivateKey priv = getPrivate();
if (mSigner != null && priv != null)
{
try
{
mSigner.initSign(priv);
}
catch (InvalidKeyException e)
{
log.error("Signature error", e);
}
try
{
mSigner.initSign(priv);
}
catch (InvalidKeyException e)
{
log.severe("Signature error: " + e);
}
}
else
{
// do not return an unitialized signer.
return null;
// do not return an unitialized signer.
return null;
}
}
return mSigner;
}
/** @return a Signature object initialized for verifying, or null if
* this key pair does not have a valid public key. */
/**
* @return a Signature object initialized for verifying, or null if this key
* pair does not have a valid public key.
*/
public Signature getVerifier()
{
if (mVerifier == null)
@@ -292,16 +306,17 @@ public class DnsKeyPair
PublicKey pk = getPublic();
if (mVerifier != null && pk != null)
{
try
{
mVerifier.initVerify(pk);
}
catch (InvalidKeyException e) {}
try
{
mVerifier.initVerify(pk);
}
catch (InvalidKeyException e)
{}
}
else
{
// do not return an unitialized verifier
return null;
// do not return an unitialized verifier
return null;
}
}
@@ -313,10 +328,9 @@ public class DnsKeyPair
{
mPublicKeyRecord = r;
// force the conversion to PublicKey:
mPublicKey = null;
mPublicKey = null;
}
public Name getDNSKEYName()
{
DNSKEYRecord kr = getDNSKEYRecord();
@@ -343,7 +357,7 @@ public class DnsKeyPair
if (priv instanceof RSAPrivateKey) return DNSSEC.RSASHA1;
if (priv instanceof DSAPrivateKey) return DNSSEC.DSA;
}
return -1;
}

View File

@@ -1,4 +1,4 @@
// $Id: DnsSecVerifier.java,v 1.5 2004/02/25 20:46:14 davidb Exp $
// $Id$
//
// Copyright (C) 2001-2003 VeriSign, Inc.
//
@@ -19,23 +19,29 @@
package com.verisignlabs.dnssec.security;
import java.util.*;
import java.io.*;
import java.security.*;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import org.xbill.DNS.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** A class for performing basic DNSSEC verification. The DNSJAVA
* package contains a similar class. This differs (for the moment,
* anyway) by allowing timing "fudge" factors and logging more
* specifically why an RRset did not validate.
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 1.5 $
/**
* A class for performing basic DNSSEC verification. The DNSJAVA package
* contains a similar class. This differs (for the moment, anyway) by allowing
* timing "fudge" factors and logging more specifically why an RRset did not
* validate.
*
* @author David Blacka (original)
* @author $Author$
* @version $Revision$
*/
public class DnsSecVerifier implements Verifier
{
@@ -58,8 +64,8 @@ public class DnsSecVerifier implements Verifier
List l = (List) mKeyMap.get(n);
if (l == null)
{
l = new ArrayList();
mKeyMap.put(n, l);
l = new ArrayList();
mKeyMap.put(n, l);
}
l.add(pair);
@@ -80,35 +86,35 @@ public class DnsSecVerifier implements Verifier
public DnsKeyPair find(Name name, int algorithm, int keyid)
{
String n = name.toString().toLowerCase();
List l = (List) mKeyMap.get(n);
List l = (List) mKeyMap.get(n);
if (l == null) return null;
// FIXME: this algorithm assumes that name+alg+footprint is
// unique, which isn't necessarily true.
for (Iterator i = l.iterator(); i.hasNext(); )
for (Iterator i = l.iterator(); i.hasNext();)
{
DnsKeyPair p = (DnsKeyPair) i.next();
if (p.getDNSKEYAlgorithm() == algorithm &&
p.getDNSKEYFootprint() == keyid)
{
return p;
}
DnsKeyPair p = (DnsKeyPair) i.next();
if (p.getDNSKEYAlgorithm() == algorithm
&& p.getDNSKEYFootprint() == keyid)
{
return p;
}
}
return null;
}
}
private TrustedKeyStore mKeyStore;
private int mStartFudge = 0;
private int mExpireFudge = 0;
private int mStartFudge = 0;
private int mExpireFudge = 0;
private boolean mVerifyAllSigs = false;
private Log log;
private Logger log;
public DnsSecVerifier()
{
log = LogFactory.getLog(this.getClass());
log = Logger.getLogger(this.getClass().toString());
mKeyStore = new TrustedKeyStore();
}
@@ -146,24 +152,24 @@ public class DnsSecVerifier implements Verifier
{
mVerifyAllSigs = v;
}
private DnsKeyPair findCachedKey(Cache cache, Name name, int algorithm,
int footprint)
int footprint)
{
RRset[] keysets = cache.findAnyRecords(name, Type.KEY);
if (keysets == null) return null;
// look for the particular key
// FIXME: this assumes that name+alg+footprint is unique.
for (Iterator i = keysets[0].rrs(); i.hasNext(); )
for (Iterator i = keysets[0].rrs(); i.hasNext();)
{
Object o = i.next();
if (! (o instanceof DNSKEYRecord)) continue;
if (!(o instanceof DNSKEYRecord)) continue;
DNSKEYRecord keyrec = (DNSKEYRecord) o;
if (keyrec.getAlgorithm() == algorithm &&
keyrec.getFootprint() == footprint)
if (keyrec.getAlgorithm() == algorithm
&& keyrec.getFootprint() == footprint)
{
return new DnsKeyPair(keyrec, (PrivateKey) null);
return new DnsKeyPair(keyrec, (PrivateKey) null);
}
}
@@ -171,7 +177,7 @@ public class DnsSecVerifier implements Verifier
}
private DnsKeyPair findKey(Cache cache, Name name, int algorithm,
int footprint)
int footprint)
{
DnsKeyPair pair = mKeyStore.find(name, algorithm, footprint);
if (pair == null && cache != null)
@@ -185,7 +191,7 @@ public class DnsSecVerifier implements Verifier
private byte validateSignature(RRset rrset, RRSIGRecord sigrec)
{
if (rrset == null || sigrec == null) return DNSSEC.Failed;
if (! rrset.getName().equals(sigrec.getName()))
if (!rrset.getName().equals(sigrec.getName()))
{
log.info("Signature name does not match RRset name");
return DNSSEC.Failed;
@@ -203,12 +209,12 @@ public class DnsSecVerifier implements Verifier
{
if (mStartFudge > 0)
{
start = new Date(start.getTime() - ((long) mStartFudge * 1000));
start = new Date(start.getTime() - ((long) mStartFudge * 1000));
}
if (now.before(start))
{
log.info("Signature is not yet valid");
return DNSSEC.Failed;
log.info("Signature is not yet valid");
return DNSSEC.Failed;
}
}
@@ -216,34 +222,37 @@ public class DnsSecVerifier implements Verifier
{
if (mExpireFudge > 0)
{
expire = new Date(expire.getTime() + ((long) mExpireFudge * 1000));
expire = new Date(expire.getTime() + ((long) mExpireFudge * 1000));
}
if (now.after(expire))
{
log.info("Signature has expired (now = " + now +
", sig expires = " + expire);
return DNSSEC.Failed;
log.info("Signature has expired (now = " + now + ", sig expires = "
+ expire);
return DNSSEC.Failed;
}
}
return DNSSEC.Secure;
}
/** 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). */
/**
* 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, Cache cache)
{
byte result = validateSignature(rrset, sigrec);
if (result != DNSSEC.Secure) return result;
DnsKeyPair keypair = findKey(cache, sigrec.getSigner(),
sigrec.getAlgorithm(),
sigrec.getFootprint());
DnsKeyPair keypair = findKey(cache,
sigrec.getSigner(),
sigrec.getAlgorithm(),
sigrec.getFootprint());
if (keypair == null)
{
log.info("could not find appropriate key");
@@ -260,41 +269,42 @@ public class DnsSecVerifier implements Verifier
byte[] sig = sigrec.getSignature();
if (sigrec.getAlgorithm() == DNSSEC.DSA)
{
sig = SignUtils.convertDSASignature(sig);
sig = SignUtils.convertDSASignature(sig);
}
if (!signer.verify(sig))
{
log.info("Signature failed to verify cryptographically");
return DNSSEC.Failed;
log.info("Signature failed to verify cryptographically");
return DNSSEC.Failed;
}
return DNSSEC.Secure;
}
catch (IOException e)
{
log.error("I/O error", e);
log.severe("I/O error: " + e);
}
catch (GeneralSecurityException e)
{
log.error("Security error", e);
log.severe("Security error: " + e);
}
log.debug("Signature failed to verify due to exception");
log.fine("Signature failed to verify due to exception");
return DNSSEC.Insecure;
}
/** Verifies an RRset. This routine does not modify the RRset.
*
* @return DNSSEC.Secure if the set verified, DNSSEC.Failed if it
* did not, and DNSSEC.Insecure if verification could not
* complete. */
/**
* Verifies an RRset. This routine does not modify the RRset.
*
* @return DNSSEC.Secure if the set verified, DNSSEC.Failed if it did not,
* and DNSSEC.Insecure if verification could not complete.
*/
public int verify(RRset rrset, Cache cache)
{
int result = mVerifyAllSigs ? DNSSEC.Secure: DNSSEC.Insecure;
int result = mVerifyAllSigs ? DNSSEC.Secure : DNSSEC.Insecure;
Iterator i = rrset.sigs();
if ( ! i.hasNext())
if (!i.hasNext())
{
log.info("RRset failed to verify due to lack of signatures");
return DNSSEC.Insecure;
@@ -307,12 +317,12 @@ public class DnsSecVerifier implements Verifier
byte res = verifySignature(rrset, sigrec, cache);
if (!mVerifyAllSigs && res == DNSSEC.Secure) return res;
if (!mVerifyAllSigs && res < result) result = res;
if (mVerifyAllSigs && res != DNSSEC.Secure && res < result)
{
result = res;
result = res;
}
}

View File

@@ -1,4 +1,4 @@
// $Id: JCEDnsSecSigner.java,v 1.3 2004/02/25 20:46:14 davidb Exp $
// $Id$
//
// Copyright (C) 2001-2003 VeriSign, Inc.
//
@@ -16,24 +16,41 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
package com.verisignlabs.dnssec.security;
import java.util.*;
import java.io.*;
import java.security.*;
import java.security.interfaces.*;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.xbill.DNS.*;
import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.DNSSEC;
import org.xbill.DNS.Name;
import org.xbill.DNS.RRSIGRecord;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
/** This class contains routines for signing DNS zones.
*
* In particular, it contains both an ability to sign an individual
* RRset and the ability to sign and entire zone. It primarily glues
* together the more basic primitives found in {@link SignUtils}.
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 1.3 $
/**
* This class contains routines for signing DNS zones.
*
* In particular, it contains both an ability to sign an individual RRset and
* the ability to sign and entire zone. It primarily glues together the more
* basic primitives found in {@link SignUtils}.
*
* @author David Blacka (original)
* @author $Author$
* @version $Revision$
*/
public class JCEDnsSecSigner
{
@@ -42,24 +59,19 @@ public class JCEDnsSecSigner
private KeyPairGenerator mRSAKeyGenerator;
private KeyPairGenerator mDSAKeyGenerator;
/** Cryptographically generate a new DNSSEC key.
*
* @param owner the KEY RR's owner name.
* @param ttl the KEY RR's TTL.
* @param dclass the KEY RR's DNS class.
* @param algorithm the DNSSEC algorithm (RSAMD5, RSASHA1, or DSA).
* @param flags any flags for the KEY RR.
* @param keysize the size of the key to generate.
* @return a DnsKeyPair with the public and private keys populated.
/**
* Cryptographically generate a new DNSSEC key.
*
* @param owner the KEY RR's owner name.
* @param ttl the KEY RR's TTL.
* @param dclass the KEY RR's DNS class.
* @param algorithm the DNSSEC algorithm (RSAMD5, RSASHA1, or DSA).
* @param flags any flags for the KEY RR.
* @param keysize the size of the key to generate.
* @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)
throws IOException, NoSuchAlgorithmException
public DnsKeyPair generateKey(Name owner, long ttl, int dclass,
int algorithm, int flags, int keysize) throws NoSuchAlgorithmException
{
KeyPair pair;
@@ -67,25 +79,25 @@ public class JCEDnsSecSigner
switch (algorithm)
{
case DNSSEC.RSAMD5:
case DNSSEC.RSASHA1:
if (mRSAKeyGenerator == null)
{
mRSAKeyGenerator = KeyPairGenerator.getInstance("RSA");
}
mRSAKeyGenerator.initialize(keysize);
pair = mRSAKeyGenerator.generateKeyPair();
break;
case DNSSEC.DSA:
if (mDSAKeyGenerator == null)
{
mDSAKeyGenerator = KeyPairGenerator.getInstance("DSA");
}
mDSAKeyGenerator.initialize(keysize);
pair = mDSAKeyGenerator.generateKeyPair();
break;
default:
throw new NoSuchAlgorithmException("Alg " + algorithm);
case DNSSEC.RSAMD5 :
case DNSSEC.RSASHA1 :
if (mRSAKeyGenerator == null)
{
mRSAKeyGenerator = KeyPairGenerator.getInstance("RSA");
}
mRSAKeyGenerator.initialize(keysize);
pair = mRSAKeyGenerator.generateKeyPair();
break;
case DNSSEC.DSA :
if (mDSAKeyGenerator == null)
{
mDSAKeyGenerator = KeyPairGenerator.getInstance("DSA");
}
mDSAKeyGenerator.initialize(keysize);
pair = mDSAKeyGenerator.generateKeyPair();
break;
default :
throw new NoSuchAlgorithmException("Alg " + algorithm);
}
if (mKeyConverter == null)
@@ -94,29 +106,30 @@ public class JCEDnsSecSigner
}
DNSKEYRecord keyrec = mKeyConverter.generateDNSKEYRecord(owner,
dclass,
ttl,
flags,
algorithm,
pair.getPublic());
dclass,
ttl,
flags,
algorithm,
pair.getPublic());
DnsKeyPair dnspair = new DnsKeyPair();
dnspair.setDNSKEYRecord(keyrec);
dnspair.setPublic(pair.getPublic()); // keep from conv. the keyrec back.
dnspair.setPublic(pair.getPublic()); // keep from conv. the keyrec back.
dnspair.setPrivate(pair.getPrivate());
return dnspair;
}
/** Sign an RRset.
*
* @param rrset the RRset to sign -- any existing signatures are ignored.
* @param keypars a list of DnsKeyPair objects containing private keys.
* @param start the inception time for the resulting RRSIG records.
* @param expire the expiration time for the resulting RRSIG records.
* @return a list of RRSIGRecord objects.
/**
* Sign an RRset.
*
* @param rrset the RRset to sign -- any existing signatures are ignored.
* @param keypars a list of DnsKeyPair objects containing private keys.
* @param start the inception time for the resulting RRSIG records.
* @param expire the expiration time for the resulting RRSIG records.
* @return a list of RRSIGRecord objects.
*/
public List signRRset(RRset rrset, List keypairs, Date start, Date expire)
throws IOException, GeneralSecurityException
throws IOException, GeneralSecurityException
{
if (rrset == null || keypairs == null) return null;
@@ -131,28 +144,31 @@ public class JCEDnsSecSigner
ArrayList sigs = new ArrayList(keypairs.size());
// for each keypair, sign the rrset.
for (Iterator i = keypairs.iterator(); i.hasNext(); )
for (Iterator i = keypairs.iterator(); i.hasNext();)
{
DnsKeyPair pair = (DnsKeyPair) i.next();
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);
Signature signer = pair.getSigner();
if (signer == null)
{
// 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)");
// 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)");
}
// sign the data.
signer.update(sign_data);
byte[] sig = signer.sign();
@@ -160,8 +176,8 @@ public class JCEDnsSecSigner
// Convert to RFC 2536 format, if necessary.
if (pair.getDNSKEYAlgorithm() == DNSSEC.DSA)
{
sig = SignUtils.convertDSASignature
(((DSAPublicKey)pair.getPublic()).getParams(), sig);
sig = SignUtils.convertDSASignature(((DSAPublicKey) pair.getPublic()).getParams(),
sig);
}
RRSIGRecord sigrec = SignUtils.generateRRSIG(sig, presig);
sigs.add(sigrec);
@@ -170,21 +186,22 @@ public class JCEDnsSecSigner
return sigs;
}
/** Create a completely self-signed KEY RRset.
*
* @param keypairs the public & private keypairs to use in the keyset.
* @param start the RRSIG inception time.
* @param expire the RRSIG expiration time.
* @return a signed RRset.
/**
* Create a completely self-signed KEY RRset.
*
* @param keypairs the public & private keypairs to use in the keyset.
* @param start the RRSIG inception time.
* @param expire the RRSIG expiration time.
* @return a signed RRset.
*/
public RRset makeKeySet(List keypairs, Date start, Date expire)
throws IOException, GeneralSecurityException
throws IOException, GeneralSecurityException
{
// Generate a KEY RR set to sign.
RRset keyset = new RRset();
for (Iterator i = keypairs.iterator(); i.hasNext(); )
for (Iterator i = keypairs.iterator(); i.hasNext();)
{
DnsKeyPair pair = (DnsKeyPair) i.next();
keyset.addRR(pair.getDNSKEYRecord());
@@ -192,42 +209,44 @@ public class JCEDnsSecSigner
List records = signRRset(keyset, keypairs, start, expire);
for (Iterator i = records.iterator(); i.hasNext(); )
for (Iterator i = records.iterator(); i.hasNext();)
{
keyset.addRR((Record) i.next());
}
return keyset;
}
/** Conditionally sign an RRset and add it to the toList.
*
* @param toList the list to which we are adding the processed RRsets.
* @param zonename the zone apex name.
* @param rrset the rrset under consideration.
* @param keysigningkeypairs the List of KSKs..
* @param zonekeypairs the List of zone keys.
* @param start the RRSIG inception time.
* @param expire the RRSIG expiration time.
* @param fullySignKeyset if true, sign the zone apex keyset with
* both KSKs and ZSKs.
* @param last_cut the name of the last delegation point encountered.
* @return the name of the new last_cut.
/**
* Conditionally sign an RRset and add it to the toList.
*
* @param toList the list to which we are adding the processed RRsets.
* @param zonename the zone apex name.
* @param rrset the rrset under consideration.
* @param keysigningkeypairs the List of KSKs..
* @param zonekeypairs the List of zone keys.
* @param start the RRSIG inception time.
* @param expire the RRSIG expiration time.
* @param fullySignKeyset if true, sign the zone apex keyset with both KSKs
* and ZSKs.
* @param last_cut the name of the last delegation point encountered.
* @return the name of the new last_cut.
*/
private Name addRRset(List toList, Name zonename, RRset rrset,
List keysigningkeypairs, List zonekeypairs,
Date start, Date expire, boolean fullySignKeyset,
Name last_cut)
throws IOException, GeneralSecurityException
List keysigningkeypairs, List zonekeypairs, Date start, Date expire,
boolean fullySignKeyset, Name last_cut) throws IOException,
GeneralSecurityException
{
// add the records themselves
for (Iterator i = rrset.rrs(); i.hasNext(); )
for (Iterator i = rrset.rrs(); i.hasNext();)
{
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).
// we also don't sign the zone key set unless we've been asked.
@@ -247,11 +266,11 @@ public class JCEDnsSecSigner
// otherwise we will just sign them with the zonesigning keys.
if (keysigningkeypairs != null && keysigningkeypairs.size() > 0)
{
List sigs = signRRset(rrset, keysigningkeypairs, start, expire);
toList.addAll(sigs);
List sigs = signRRset(rrset, keysigningkeypairs, start, expire);
toList.addAll(sigs);
// If we aren't going to sign with all the keys, bail out now.
if (!fullySignKeyset) return last_cut;
// If we aren't going to sign with all the keys, bail out now.
if (!fullySignKeyset) return last_cut;
}
}
@@ -262,46 +281,39 @@ public class JCEDnsSecSigner
return last_cut;
}
/** Given a zone, sign it.
*
* @param zonename the name of the zone.
* @param records the records comprising the zone. They do not
* have to be in any particular order, as this method will order
* them as necessary.
* @param keysigningkeypairs the key pairs that are designated as
* "key signing keys".
* @param zonekeypair this key pairs that are designated as "zone
* signing keys".
* @param start the RRSIG inception time.
* @param expire the RRSIG expiration time.
* @param useOptIn generate Opt-In style NXT records. It will
* consider any insecure delegation to be unsigned. To override
* this, include the name of the insecure delegation in the
* NXTIncludeNames list.
* @param useConservativeOptIn if true, Opt-In NXT records will
* only be generated if there are insecure, unsigned delegations in
* the span. Not effect if useOptIn is false.
* @param fullySignKeyset sign the zone apex keyset with all available keys.
* @param NXTIncludeNames names that are to be included in the NXT
* chain regardless. This may be null and is only used if useOptIn
* is true.
*
* @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone.
/**
* Given a zone, sign it.
*
* @param zonename the name of the zone.
* @param records the records comprising the zone. They do not have to be in
* any particular order, as this method will order them as
* necessary.
* @param keysigningkeypairs the key pairs that are designated as "key
* signing keys".
* @param zonekeypair this key pairs that are designated as "zone signing
* keys".
* @param start the RRSIG inception time.
* @param expire the RRSIG expiration time.
* @param useOptIn generate Opt-In style NXT records. It will consider any
* insecure delegation to be unsigned. To override this, include
* the name of the insecure delegation in the NXTIncludeNames list.
* @param useConservativeOptIn if true, Opt-In NXT records will only be
* generated if there are insecure, unsigned delegations in the
* span. Not effect if useOptIn is false.
* @param fullySignKeyset sign the zone apex keyset with all available keys.
* @param NXTIncludeNames names that are to be included in the NXT chain
* regardless. This may be null and is only used if useOptIn is
* true.
*
* @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone.
*/
public List signZone(Name zonename,
List records,
List keysigningkeypairs,
List zonekeypairs,
Date start,
Date expire,
boolean useOptIn,
boolean useConservativeOptIn,
boolean fullySignKeyset,
List NSECIncludeNames)
throws IOException, GeneralSecurityException
public List signZone(Name zonename, List records, List keysigningkeypairs,
List zonekeypairs, Date start, Date expire, boolean useOptIn,
boolean useConservativeOptIn, boolean fullySignKeyset,
List NSECIncludeNames) throws IOException, GeneralSecurityException
{
// Remove any existing DNSSEC records (NSEC, RRSIG)
SignUtils.removeGeneratedRecords(zonename, records);
// Sort the zone
@@ -312,28 +324,28 @@ public class JCEDnsSecSigner
// Generate DS records
SignUtils.generateDSRecords(zonename, records);
// Generate NXT records
if (useOptIn)
{
SignUtils.generateOptInNSECRecords(zonename, records,
NSECIncludeNames,
useConservativeOptIn);
SignUtils.generateOptInNSECRecords(zonename,
records,
NSECIncludeNames,
useConservativeOptIn);
}
else
{
SignUtils.generateNSECRecords(zonename, records);
}
// Assemble into RRsets and sign.
RRset rrset = new RRset();
ArrayList signed_records = new ArrayList();
Name last_cut = null;
for (ListIterator i = records.listIterator(); i.hasNext(); )
// Assemble into RRsets and sign.
RRset rrset = new RRset();
ArrayList signed_records = new ArrayList();
Name last_cut = null;
for (ListIterator i = records.listIterator(); i.hasNext();)
{
Record r = (Record) i.next();
Name r_name = r.getName();
// First record
if (rrset.getName() == null)
@@ -343,9 +355,9 @@ public class JCEDnsSecSigner
}
// Current record is part of the current RRset.
if (rrset.getName().equals(r.getName()) &&
rrset.getDClass() == r.getDClass() &&
rrset.getType() == r.getType())
if (rrset.getName().equals(r.getName())
&& rrset.getDClass() == r.getDClass()
&& rrset.getType() == r.getType())
{
rrset.addRR(r);
continue;
@@ -356,17 +368,30 @@ 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, keysigningkeypairs,
zonekeypairs, start, expire, fullySignKeyset,
last_cut);
last_cut = addRRset(signed_records,
zonename,
rrset,
keysigningkeypairs,
zonekeypairs,
start,
expire,
fullySignKeyset,
last_cut);
rrset.clear();
rrset.addRR(r);
}
// add the last RR set
addRRset(signed_records, zonename, rrset, keysigningkeypairs, zonekeypairs,
start, expire, fullySignKeyset, last_cut);
addRRset(signed_records,
zonename,
rrset,
keysigningkeypairs,
zonekeypairs,
start,
expire,
fullySignKeyset,
last_cut);
return signed_records;
}

View File

@@ -1,4 +1,4 @@
// $Id: RecordComparator.java,v 1.2 2004/01/16 17:54:48 davidb Exp $
// $Id$
//
// Copyright (C) 2000-2003 Network Solutions, Inc.
//
@@ -19,26 +19,33 @@
package com.verisignlabs.dnssec.security;
import java.util.*;
import java.util.Comparator;
import org.xbill.DNS.*;
import org.xbill.DNS.RRSIGRecord;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
/** This class implements a comparison operator for {@link
* org.xbill.DNS.Record} objects. It imposes a canonical order
* consistent with DNSSEC. It does not put records within a RRset
* into canonical order: see {@link ByteArrayComparator}.
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 1.2 $ */
/**
* This class implements a comparison operator for {@link
* org.xbill.DNS.Record} objects. It imposes a canonical order consistent with
* DNSSEC. It does not put records within a RRset into canonical order: see
* {@link ByteArrayComparator}.
*
* @author David Blacka (original)
* @author $Author$
* @version $Revision$
*/
public class RecordComparator implements Comparator
{
public RecordComparator()
{}
{
}
/** In general, types are compared numerically. However, SOA and NS
* are ordered before the rest. */
/**
* In general, types are compared numerically. However, SOA and NS are
* ordered before the rest.
*/
private int compareTypes(int a, int b)
{
if (a == b) return 0;
@@ -53,8 +60,7 @@ public class RecordComparator implements Comparator
return 1;
}
public int compare(Object o1, Object o2)
throws ClassCastException
public int compare(Object o1, Object o2) throws ClassCastException
{
Record a = (Record) o1;
Record b = (Record) o2;

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,28 @@
// $Id: TypeMap.java,v 1.5 2004/03/23 17:53:57 davidb Exp $
// $Id$
//
// Copyright (C) 2004 Verisign, Inc.
package com.verisignlabs.dnssec.security;
import java.util.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.xbill.DNS.Type;
import org.xbill.DNS.DNSOutput;
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. */
/**
* 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.
*/
public class TypeMap
{
private static final Integer[] integerArray = new Integer[0];
private Set typeSet;
private Set typeSet;
public TypeMap()
{
this.typeSet = new HashSet();
@@ -41,7 +45,6 @@ public class TypeMap
{
return typeSet.contains(new Integer(type));
}
public static TypeMap fromTypes(int[] types)
{
@@ -53,27 +56,29 @@ public class TypeMap
return m;
}
/** Given an array of bytes representing a wire-format type map,
* construct the TypeMap object. */
/**
* Given an array of bytes representing a wire-format type map, construct
* the TypeMap object.
*/
public static TypeMap fromBytes(byte[] map)
{
int m = 0;
int m = 0;
TypeMap typemap = new TypeMap();
int map_number;
int byte_length;
while (m < map.length)
{
map_number = map[m++];
map_number = map[m++];
byte_length = map[m++];
for (int i = 0; i < byte_length; i++)
{
for (int j = 0; j < 8; j++)
{
if ( (map[m + i] & (1 << (7 - j))) != 0 )
if ((map[m + i] & (1 << (7 - j))) != 0)
{
typemap.set(map_number * 8 + j);
}
@@ -84,15 +89,15 @@ public class TypeMap
return typemap;
}
/** @return the normal string representation of the typemap. */
public String toString()
{
int[] types = getTypes();
Arrays.sort(types);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < types.length; i++)
{
sb.append(" ");
@@ -102,8 +107,8 @@ public class TypeMap
return sb.toString();
}
protected static void mapToWire(DNSOutput out, int[] types,
int base, int start, int end)
protected static void mapToWire(DNSOutput out, int[] types, int base,
int start, int end)
{
// calculate the length of this map by looking at the largest
// typecode in this section.
@@ -121,7 +126,7 @@ public class TypeMap
// for each type in our sub-array, set its corresponding bit in the map.
for (int i = start; i < end; i++)
{
map[ (types[i] & 0xFF) / 8 ] |= ( 1 << (7 - types[i] % 8) );
map[(types[i] & 0xFF) / 8] |= (1 << (7 - types[i] % 8));
}
// write out the resulting binary bitmap.
for (int i = 0; i < map.length; i++)
@@ -129,7 +134,7 @@ public class TypeMap
out.writeU8(map[i]);
}
}
public byte[] toWire()
{
int[] types = getTypes();
@@ -140,7 +145,7 @@ public class TypeMap
int mapstart = -1;
DNSOutput out = new DNSOutput();
for (int i = 0; i < types.length; i++)
{
int base = types[i] >> 8;
@@ -156,13 +161,14 @@ public class TypeMap
return out.toByteArray();
}
public int[] getTypes()
{
Integer[] a = (Integer[]) typeSet.toArray(integerArray);
int[] res = new int[a.length];
for (int i = 0; i < res.length; i++) {
for (int i = 0; i < res.length; i++)
{
res[i] = a[i].intValue();
}
@@ -178,5 +184,5 @@ public class TypeMap
{
return TypeMap.fromTypes(types).toWire();
}
}

View File

@@ -1,4 +1,4 @@
// $Id: ZoneUtils.java,v 1.3 2004/01/15 17:32:18 davidb Exp $
// $Id$
//
// Copyright (C) 2003 VeriSign, Inc.
//
@@ -19,51 +19,50 @@
package com.verisignlabs.dnssec.security;
import java.util.*;
import java.io.*;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.xbill.DNS.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xbill.DNS.Master;
import org.xbill.DNS.Name;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
/** This class contains a bunch of utility methods that are generally
* useful in manipulating zones.
*
* @author David Blacka (original)
* @author $Author: davidb $
* @version $Revision: 1.3 $
/**
* This class contains a bunch of utility methods that are generally useful in
* manipulating zones.
*
* @author David Blacka (original)
* @author $Author$
* @version $Revision$
*/
public class ZoneUtils
{
private static Log log;
static {
log = LogFactory.getLog(ZoneUtils.class);
}
/** Load a zone file.
*
* @param zonefile the filename/path of the zonefile to read.
* @param origin the origin to use for the zonefile (may be null if
* the origin is specified in the zone file itself).
* @return a {@link java.util.List} of {@link org.xbill.DNS.Record}
* objects.
* @throws IOException if something goes wrong reading the zone
* file.
/**
* Load a zone file.
*
* @param zonefile the filename/path of the zonefile to read.
* @param origin the origin to use for the zonefile (may be null if the
* origin is specified in the zone file itself).
* @return a {@link java.util.List} of {@link org.xbill.DNS.Record} objects.
* @throws IOException if something goes wrong reading the zone file.
*/
public static List readZoneFile(String zonefile, Name origin)
throws IOException
throws IOException
{
ArrayList records = new ArrayList();
Master m = new Master(zonefile, origin);
Record r = null;
while ( (r = m.nextRecord()) != null )
while ((r = m.nextRecord()) != null)
{
records.add(r);
}
@@ -71,15 +70,16 @@ public class ZoneUtils
return records;
}
/** Write the records out into a zone file.
*
* @param records a {@link java.util.List} of {@link
* org.xbill.DNS.Record} objects forming a zone.
* @param zonefile the file to write to. If null or equal to "-",
* System.out is used.
/**
* Write the records out into a zone file.
*
* @param records a {@link java.util.List} of {@link org.xbill.DNS.Record}
* objects forming a zone.
* @param zonefile the file to write to. If null or equal to "-", System.out
* is used.
*/
public static void writeZoneFile(List records, String zonefile)
throws IOException
throws IOException
{
PrintWriter out = null;
@@ -92,8 +92,7 @@ public class ZoneUtils
out = new PrintWriter(new BufferedWriter(new FileWriter(zonefile)));
}
for (Iterator i = records.iterator(); i.hasNext(); )
for (Iterator i = records.iterator(); i.hasNext();)
{
out.println(i.next());
}
@@ -101,38 +100,38 @@ public class ZoneUtils
out.close();
}
/** Given just the list of records, determine the zone name
* (origin).
*
* @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
/**
* Given just the list of records, determine the zone name (origin).
*
* @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
*/
public static Name findZoneName(List records)
{
for (Iterator i = records.iterator(); i.hasNext(); )
for (Iterator i = records.iterator(); i.hasNext();)
{
int type = 0;
Name n = null;
int type = 0;
Name n = null;
Object o = i.next();
if (o instanceof Record)
{
Record r = (Record) o;
type = r.getType();
n = r.getName();
Record r = (Record) o;
type = r.getType();
n = r.getName();
}
else if (o instanceof RRset)
{
RRset r = (RRset) o;
type = r.getType();
n = r.getName();
RRset r = (RRset) o;
type = r.getType();
n = r.getName();
}
if (type == Type.SOA) return n;
}
return null;
}
}