Fix issue where the DS digest algorithm would be ignored when converting in-zone DNSKEY RRs to DS records; formatting
git-svn-id: https://svn.verisignlabs.com/jdnssec/tools/trunk@115 4cbd57fe-54e5-0310-bd9a-f30fe5ea5e6e
This commit is contained in:
parent
09d21a1d67
commit
3f1787695d
@ -63,50 +63,67 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate from some basic information a prototype SIG RR containing
|
* Generate from some basic information a prototype RRSIG RR containing
|
||||||
* everything but the actual signature itself.
|
* everything but the actual signature itself.
|
||||||
*
|
*
|
||||||
* @param rrset the RRset being signed.
|
* @param rrset
|
||||||
* @param key the public KEY RR counterpart to the key being used to sign
|
* the RRset being signed.
|
||||||
* the RRset
|
* @param key
|
||||||
* @param start the SIG inception time.
|
* the public DNSKEY RR counterpart to the key being used to sign the
|
||||||
* @param expire the SIG expiration time.
|
* RRset
|
||||||
* @param sig_ttl the TTL of the resulting SIG record.
|
* @param start
|
||||||
|
* the RRSIG inception time.
|
||||||
|
* @param expire
|
||||||
|
* the RRSIG expiration time.
|
||||||
|
* @param sig_ttl
|
||||||
|
* the TTL of the resulting RRSIG record.
|
||||||
|
*
|
||||||
* @return a prototype signature based on the RRset and key information.
|
* @return a prototype signature based on the RRset and key information.
|
||||||
*/
|
*/
|
||||||
public static RRSIGRecord generatePreRRSIG(RRset rrset, DNSKEYRecord key,
|
public static RRSIGRecord generatePreRRSIG(RRset rrset, DNSKEYRecord key,
|
||||||
Date start, Date expire, long sig_ttl)
|
Date start, Date expire,
|
||||||
|
long sig_ttl)
|
||||||
{
|
{
|
||||||
return new RRSIGRecord(rrset.getName(), rrset.getDClass(), sig_ttl, rrset
|
return new RRSIGRecord(rrset.getName(), rrset.getDClass(), sig_ttl,
|
||||||
.getType(), key.getAlgorithm(), (int) rrset.getTTL(), expire, start,
|
rrset.getType(), key.getAlgorithm(),
|
||||||
|
(int) rrset.getTTL(), expire, start,
|
||||||
key.getFootprint(), key.getName(), null);
|
key.getFootprint(), key.getName(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate from some basic information a prototype SIG RR containing
|
* Generate from some basic information a prototype RRSIG RR containing
|
||||||
* everything but the actual signature itself.
|
* everything but the actual signature itself.
|
||||||
*
|
*
|
||||||
* @param rec the DNS record being signed (forming an entire RRset).
|
* @param rec
|
||||||
* @param key the public KEY RR counterpart to the key signing the record.
|
* the DNS record being signed (forming an entire RRset).
|
||||||
* @param start the SIG inception time.
|
* @param key
|
||||||
* @param expire the SIG expiration time.
|
* the public DNSKEY RR counterpart to the key signing the record.
|
||||||
* @param sig_ttl the TTL of the result SIG record.
|
* @param start
|
||||||
|
* the RRSIG inception time.
|
||||||
|
* @param expire
|
||||||
|
* the RRSIG expiration time.
|
||||||
|
* @param sig_ttl
|
||||||
|
* the TTL of the result RRSIG record.
|
||||||
|
*
|
||||||
* @return a prototype signature based on the Record and key information.
|
* @return a prototype signature based on the Record and key information.
|
||||||
*/
|
*/
|
||||||
public static RRSIGRecord generatePreRRSIG(Record rec, DNSKEYRecord key,
|
public static RRSIGRecord generatePreRRSIG(Record rec, DNSKEYRecord key,
|
||||||
Date start, Date expire, long sig_ttl)
|
Date start, Date expire,
|
||||||
|
long sig_ttl)
|
||||||
{
|
{
|
||||||
return new RRSIGRecord(rec.getName(), rec.getDClass(), sig_ttl, rec
|
return new RRSIGRecord(rec.getName(), rec.getDClass(), sig_ttl,
|
||||||
.getType(), key.getAlgorithm(), rec.getTTL(), expire, start, key
|
rec.getType(), key.getAlgorithm(), rec.getTTL(),
|
||||||
.getFootprint(), key.getName(), null);
|
expire, start, key.getFootprint(), key.getName(),
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the binary image of the prototype SIG RR.
|
* Generate the binary image of the prototype RRSIG RR.
|
||||||
*
|
*
|
||||||
* @param presig the SIG RR prototype.
|
* @param presig
|
||||||
* @return the RDATA portion of the prototype SIG record. This forms the
|
* the RRSIG RR prototype.
|
||||||
* first part of the data to be signed.
|
* @return the RDATA portion of the prototype RRSIG record. This forms the first
|
||||||
|
* part of the data to be signed.
|
||||||
*/
|
*/
|
||||||
private static byte[] generatePreSigRdata(RRSIGRecord presig)
|
private static byte[] generatePreSigRdata(RRSIGRecord presig)
|
||||||
{
|
{
|
||||||
@ -135,8 +152,9 @@ public class SignUtils
|
|||||||
/**
|
/**
|
||||||
* Calculate the canonical wire line format of the RRset.
|
* Calculate the canonical wire line format of the RRset.
|
||||||
*
|
*
|
||||||
* @param rrset the RRset to convert.
|
* @param rrset
|
||||||
* @return the canonical wire line format of the rrset. This is the second
|
* the RRset to convert.
|
||||||
|
* @return the canonical wire line format of the RRset. This is the second
|
||||||
* part of data to be signed.
|
* part of data to be signed.
|
||||||
*/
|
*/
|
||||||
public static byte[] generateCanonicalRRsetData(RRset rrset)
|
public static byte[] generateCanonicalRRsetData(RRset rrset)
|
||||||
@ -154,7 +172,7 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
// put the records into the correct ordering.
|
// put the records into the correct ordering.
|
||||||
// Caculate the offset where the RDATA begins (we have to skip
|
// Calculate the offset where the RDATA begins (we have to skip
|
||||||
// past the length byte)
|
// past the length byte)
|
||||||
|
|
||||||
int offset = rrset.getName().toWireCanonical().length + 10;
|
int offset = rrset.getName().toWireCanonical().length + 10;
|
||||||
@ -175,8 +193,10 @@ public class SignUtils
|
|||||||
* Given an RRset and the prototype signature, generate the canonical data
|
* Given an RRset and the prototype signature, generate the canonical data
|
||||||
* that is to be signed.
|
* that is to be signed.
|
||||||
*
|
*
|
||||||
* @param rrset the RRset to be signed.
|
* @param rrset
|
||||||
* @param presig a prototype SIG RR created using the same RRset.
|
* the RRset to be signed.
|
||||||
|
* @param presig
|
||||||
|
* a prototype SIG RR created using the same RRset.
|
||||||
* @return a block of data ready to be signed.
|
* @return a block of data ready to be signed.
|
||||||
*/
|
*/
|
||||||
public static byte[] generateSigData(RRset rrset, RRSIGRecord presig)
|
public static byte[] generateSigData(RRset rrset, RRSIGRecord presig)
|
||||||
@ -191,10 +211,12 @@ public class SignUtils
|
|||||||
* Given an RRset and the prototype signature, generate the canonical data
|
* Given an RRset and the prototype signature, generate the canonical data
|
||||||
* that is to be signed.
|
* that is to be signed.
|
||||||
*
|
*
|
||||||
* @param rrset_data the RRset converted into canonical wire line format (as
|
* @param rrset_data
|
||||||
* per the canonicalization rules in RFC 2535).
|
* the RRset converted into canonical wire line format (as per the
|
||||||
* @param presig the prototype signature based on the same RRset represented
|
* canonicalization rules in RFC 2535).
|
||||||
* in <code>rrset_data</code>.
|
* @param presig
|
||||||
|
* the prototype signature based on the same RRset represented in
|
||||||
|
* <code>rrset_data</code>.
|
||||||
* @return a block of data ready to be signed.
|
* @return a block of data ready to be signed.
|
||||||
*/
|
*/
|
||||||
public static byte[] generateSigData(byte[] rrset_data, RRSIGRecord presig)
|
public static byte[] generateSigData(byte[] rrset_data, RRSIGRecord presig)
|
||||||
@ -212,24 +234,27 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the acutal signature an the prototype signature, combine them and
|
* Given the actual signature and the prototype signature, combine them and
|
||||||
* return the fully formed SIGRecord.
|
* return the fully formed RRSIGRecord.
|
||||||
*
|
*
|
||||||
* @param signature the cryptographic signature, in DNSSEC format.
|
* @param signature
|
||||||
* @param presig the prototype SIG RR to add the signature to.
|
* the cryptographic signature, in DNSSEC format.
|
||||||
* @return the fully formed SIG RR.
|
* @param presig
|
||||||
|
* the prototype RRSIG RR to add the signature to.
|
||||||
|
* @return the fully formed RRSIG RR.
|
||||||
*/
|
*/
|
||||||
public static RRSIGRecord generateRRSIG(byte[] signature, RRSIGRecord presig)
|
public static RRSIGRecord generateRRSIG(byte[] signature, RRSIGRecord presig)
|
||||||
{
|
{
|
||||||
return new RRSIGRecord(presig.getName(), presig.getDClass(), presig
|
return new RRSIGRecord(presig.getName(), presig.getDClass(),
|
||||||
.getTTL(), presig.getTypeCovered(), presig.getAlgorithm(), presig
|
presig.getTTL(), presig.getTypeCovered(),
|
||||||
.getOrigTTL(), presig.getExpire(), presig.getTimeSigned(), presig
|
presig.getAlgorithm(), presig.getOrigTTL(),
|
||||||
.getFootprint(), presig.getSigner(), signature);
|
presig.getExpire(), presig.getTimeSigned(),
|
||||||
|
presig.getFootprint(), presig.getSigner(), signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts from a RFC 2536 formatted DSA signature to a JCE (ASN.1)
|
* Converts from a RFC 2536 formatted DSA signature to a JCE (ASN.1) formatted
|
||||||
* formatted signature.
|
* signature.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* ASN.1 format = ASN1_SEQ . seq_length . ASN1_INT . Rlength . R . ANS1_INT .
|
* ASN.1 format = ASN1_SEQ . seq_length . ASN1_INT . Rlength . R . ANS1_INT .
|
||||||
@ -239,10 +264,12 @@ public class SignUtils
|
|||||||
* The integers R and S may have a leading null byte to force the integer
|
* The integers R and S may have a leading null byte to force the integer
|
||||||
* positive.
|
* positive.
|
||||||
*
|
*
|
||||||
* @param signature the RFC 2536 formatted DSA signature.
|
* @param signature
|
||||||
|
* the RFC 2536 formatted DSA signature.
|
||||||
* @return The ASN.1 formatted DSA signature.
|
* @return The ASN.1 formatted DSA signature.
|
||||||
* @throws SignatureException if there was something wrong with the RFC 2536
|
* @throws SignatureException
|
||||||
* formatted signature.
|
* if there was something wrong with the RFC 2536 formatted
|
||||||
|
* signature.
|
||||||
*/
|
*/
|
||||||
public static byte[] convertDSASignature(byte[] signature)
|
public static byte[] convertDSASignature(byte[] signature)
|
||||||
throws SignatureException
|
throws SignatureException
|
||||||
@ -288,39 +315,36 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts from a JCE (ASN.1) formatted DSA signature to a RFC 2536
|
* Converts from a JCE (ASN.1) formatted DSA signature to a RFC 2536 compliant
|
||||||
* compliant signature.
|
* signature.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* rfc2536 format = T . R . S
|
* rfc2536 format = T . R . S
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* where T is a number between 0 and 8, which is based on the DSA key
|
* where T is a number between 0 and 8, which is based on the DSA key length,
|
||||||
* length, and R & S are formatted to be exactly 20 bytes each (no leading
|
* and R & S are formatted to be exactly 20 bytes each (no leading null
|
||||||
* null bytes).
|
* bytes).
|
||||||
*
|
*
|
||||||
* @param params the DSA parameters associated with the DSA key used to
|
* @param params
|
||||||
* generate the signature.
|
* the DSA parameters associated with the DSA key used to generate
|
||||||
* @param signature the ASN.1 formatted DSA signature.
|
* the signature.
|
||||||
|
* @param signature
|
||||||
|
* the ASN.1 formatted DSA signature.
|
||||||
* @return a RFC 2536 formatted DSA signature.
|
* @return a RFC 2536 formatted DSA signature.
|
||||||
* @throws SignatureException if something is wrong with the ASN.1 format.
|
* @throws SignatureException
|
||||||
|
* if something is wrong with the ASN.1 format.
|
||||||
*/
|
*/
|
||||||
public static byte[] convertDSASignature(DSAParams params, byte[] signature)
|
public static byte[] convertDSASignature(DSAParams params, byte[] signature)
|
||||||
throws SignatureException
|
throws SignatureException
|
||||||
{
|
{
|
||||||
if (signature[0] != ASN1_SEQ || signature[2] != ASN1_INT)
|
if (signature[0] != ASN1_SEQ || signature[2] != ASN1_INT) { throw new SignatureException(
|
||||||
{
|
"Invalid ASN.1 signature format: expected SEQ, INT"); }
|
||||||
throw new SignatureException(
|
|
||||||
"Invalid ASN.1 signature format: expected SEQ, INT");
|
|
||||||
}
|
|
||||||
|
|
||||||
byte r_pad = (byte) (signature[3] - 20);
|
byte r_pad = (byte) (signature[3] - 20);
|
||||||
|
|
||||||
if (signature[24 + r_pad] != ASN1_INT)
|
if (signature[24 + r_pad] != ASN1_INT) { throw new SignatureException(
|
||||||
{
|
"Invalid ASN.1 signature format: expected SEQ, INT, INT"); }
|
||||||
throw new SignatureException(
|
|
||||||
"Invalid ASN.1 signature format: expected SEQ, INT, INT");
|
|
||||||
}
|
|
||||||
|
|
||||||
log.finer("(start) ASN.1 DSA Sig:\n" + base64.toString(signature));
|
log.finer("(start) ASN.1 DSA Sig:\n" + base64.toString(signature));
|
||||||
|
|
||||||
@ -373,22 +397,21 @@ public class SignUtils
|
|||||||
/**
|
/**
|
||||||
* This is a convenience routine to help us classify records/RRsets.
|
* This is a convenience routine to help us classify records/RRsets.
|
||||||
*
|
*
|
||||||
* It charaterizes a record/RRset as one of the following classes:<br/>
|
* It characterizes a record/RRset as one of the following classes:<br/>
|
||||||
* <dl>
|
* <dl>
|
||||||
*
|
*
|
||||||
* <dt>NORMAL</dt>
|
* <dt>NORMAL</dt>
|
||||||
* <dd>This record/set is properly within the zone an subject to all NXT
|
* <dd>This record/set is properly within the zone an subject to all NXT and
|
||||||
* and SIG processing.</dd>
|
* SIG processing.</dd>
|
||||||
*
|
*
|
||||||
* <dt>DELEGATION</dt>
|
* <dt>DELEGATION</dt>
|
||||||
* <dd>This is a zone delegation point (or cut). It is used in NXT
|
* <dd>This is a zone delegation point (or cut). It is used in NXT processing
|
||||||
* processing but is not signed.</dd>
|
* but is not signed.</dd>
|
||||||
*
|
*
|
||||||
* <dt>GLUE</dt>
|
* <dt>GLUE</dt>
|
||||||
* <dd>This is a glue record and therefore not properly within the zone. It
|
* <dd>This is a glue record and therefore not properly within the zone. It is
|
||||||
* is not included in NXT or SIG processing. Normally glue records are A
|
* not included in NXT or SIG processing. Normally glue records are A records,
|
||||||
* records, but this routine calls anything that is below a zone delegation
|
* but this routine calls anything that is below a zone delegation glue.</dd>
|
||||||
* glue.</dd>
|
|
||||||
*
|
*
|
||||||
* <dt>INVALID</dt>
|
* <dt>INVALID</dt>
|
||||||
* <dd>This record doesn't even belong in the zone.</dd>
|
* <dd>This record doesn't even belong in the zone.</dd>
|
||||||
@ -399,11 +422,15 @@ public class SignUtils
|
|||||||
* This method must be called successively on records in the canonical name
|
* This method must be called successively on records in the canonical name
|
||||||
* ordering, and the caller must maintain the last_cut parameter.
|
* ordering, and the caller must maintain the last_cut parameter.
|
||||||
*
|
*
|
||||||
* @param zonename the name of the zone that is being processed.
|
* @param zonename
|
||||||
* @param name the name of the record/set under consideration.
|
* the name of the zone that is being processed.
|
||||||
* @param type the type of the record/set under consideration.
|
* @param name
|
||||||
* @param last_cut the name of the last DELEGATION record/set that was
|
* the name of the record/set under consideration.
|
||||||
* encountered while iterating over the zone in canonical order.
|
* @param type
|
||||||
|
* the type of the record/set under consideration.
|
||||||
|
* @param last_cut
|
||||||
|
* the name of the last DELEGATION record/set that was encountered
|
||||||
|
* while iterating over the zone in canonical order.
|
||||||
*/
|
*/
|
||||||
public static int recordSecType(Name zonename, Name name, int type,
|
public static int recordSecType(Name zonename, Name name, int type,
|
||||||
Name last_cut)
|
Name last_cut)
|
||||||
@ -436,10 +463,11 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a canonical ordered list of records from a single zone, order the
|
* Given a canonical ordered list of records from a single zone, order the raw
|
||||||
* raw records into a list of RRsets.
|
* records into a list of RRsets.
|
||||||
*
|
*
|
||||||
* @param records a list of {@link org.xbill.DNS.Record} objects, in DNSSEC
|
* @param records
|
||||||
|
* a list of {@link org.xbill.DNS.Record} objects, in DNSSEC
|
||||||
* canonical order.
|
* canonical order.
|
||||||
* @return a List of {@link org.xbill.DNS.RRset} objects.
|
* @return a List of {@link org.xbill.DNS.RRset} objects.
|
||||||
*/
|
*/
|
||||||
@ -471,8 +499,7 @@ public class SignUtils
|
|||||||
// Current record is part of the current RRset.
|
// Current record is part of the current RRset.
|
||||||
if (rrset.getName().equals(r.getName())
|
if (rrset.getName().equals(r.getName())
|
||||||
&& rrset.getDClass() == r.getDClass()
|
&& rrset.getDClass() == r.getDClass()
|
||||||
&& ((r.getType() == Type.RRSIG && rrset.getType() == ((RRSIGRecord) r)
|
&& ((r.getType() == Type.RRSIG && rrset.getType() == ((RRSIGRecord) r).getTypeCovered()) || rrset.getType() == r.getType()))
|
||||||
.getTypeCovered()) || rrset.getType() == r.getType()))
|
|
||||||
{
|
{
|
||||||
rrset.addRR(r);
|
rrset.addRR(r);
|
||||||
continue;
|
continue;
|
||||||
@ -552,16 +579,18 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a canonical (by name) ordered list of records in a zone, generate
|
* Given a canonical (by name) ordered list of records in a zone, generate the
|
||||||
* the NXT records in place.
|
* NXT records in place.
|
||||||
*
|
*
|
||||||
* Note that the list that the records are stored in must support the
|
* Note that the list that the records are stored in must support the
|
||||||
* listIterator.add() operation.
|
* listIterator.add() operation.
|
||||||
*
|
*
|
||||||
* @param zonename the name of the zone (used to distinguish between zone
|
* @param zonename
|
||||||
* apex NS RRsets and delegations).
|
* the name of the zone (used to distinguish between zone apex NS
|
||||||
* @param records a list of {@link org.xbill.DNS.Record} objects in DNSSEC
|
* RRsets and delegations).
|
||||||
* canonical order.
|
* @param records
|
||||||
|
* a list of {@link org.xbill.DNS.Record} objects in DNSSEC canonical
|
||||||
|
* order.
|
||||||
*/
|
*/
|
||||||
public static void generateNSECRecords(Name zonename, List records)
|
public static void generateNSECRecords(Name zonename, List records)
|
||||||
{
|
{
|
||||||
@ -605,7 +634,8 @@ public class SignUtils
|
|||||||
if (last_node != null)
|
if (last_node != null)
|
||||||
{
|
{
|
||||||
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
||||||
last_node.ttl, current_node.name, last_node.getTypes());
|
last_node.ttl, current_node.name,
|
||||||
|
last_node.getTypes());
|
||||||
// Note: we have to add this through the iterator, otherwise
|
// Note: we have to add this through the iterator, otherwise
|
||||||
// the next access via the iterator will generate a
|
// the next access via the iterator will generate a
|
||||||
// ConcurrencyModificationException.
|
// ConcurrencyModificationException.
|
||||||
@ -631,21 +661,24 @@ public class SignUtils
|
|||||||
if (last_node != null)
|
if (last_node != null)
|
||||||
{
|
{
|
||||||
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
||||||
last_node.ttl, current_node.name, last_node.getTypes());
|
last_node.ttl, current_node.name,
|
||||||
|
last_node.getTypes());
|
||||||
records.add(last_node.nsecIndex - 1, nsec);
|
records.add(last_node.nsecIndex - 1, nsec);
|
||||||
log.finer("Generated: " + nsec);
|
log.finer("Generated: " + nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate last NSEC
|
// Generate last NSEC
|
||||||
NSECRecord nsec = new NSECRecord(current_node.name, current_node.dclass,
|
NSECRecord nsec = new NSECRecord(current_node.name, current_node.dclass,
|
||||||
current_node.ttl, zonename, current_node.getTypes());
|
current_node.ttl, zonename,
|
||||||
|
current_node.getTypes());
|
||||||
records.add(nsec);
|
records.add(nsec);
|
||||||
|
|
||||||
log.finer("Generated: " + nsec);
|
log.finer("Generated: " + nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateNSEC3Records(Name zonename, List records,
|
public static void generateNSEC3Records(Name zonename, List records,
|
||||||
byte[] salt, int iterations) throws NoSuchAlgorithmException
|
byte[] salt, int iterations)
|
||||||
|
throws NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
List proto_nsec3s = new ArrayList();
|
List proto_nsec3s = new ArrayList();
|
||||||
NodeInfo current_node = null;
|
NodeInfo current_node = null;
|
||||||
@ -695,11 +728,7 @@ public class SignUtils
|
|||||||
// At this point, r represents the start of a new node.
|
// At this point, r represents the start of a new node.
|
||||||
// So we move current_node to last_node and generate a new current node.
|
// So we move current_node to last_node and generate a new current node.
|
||||||
// But first, we need to do something with the last node.
|
// But first, we need to do something with the last node.
|
||||||
generateNSEC3ForNode(last_node,
|
generateNSEC3ForNode(last_node, zonename, salt, iterations, false,
|
||||||
zonename,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
false,
|
|
||||||
proto_nsec3s);
|
proto_nsec3s);
|
||||||
|
|
||||||
last_node = current_node;
|
last_node = current_node;
|
||||||
@ -707,17 +736,9 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
// process last two nodes.
|
// process last two nodes.
|
||||||
generateNSEC3ForNode(last_node,
|
generateNSEC3ForNode(last_node, zonename, salt, iterations, false,
|
||||||
zonename,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
false,
|
|
||||||
proto_nsec3s);
|
proto_nsec3s);
|
||||||
generateNSEC3ForNode(current_node,
|
generateNSEC3ForNode(current_node, zonename, salt, iterations, false,
|
||||||
zonename,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
false,
|
|
||||||
proto_nsec3s);
|
proto_nsec3s);
|
||||||
|
|
||||||
List nsec3s = finishNSEC3s(proto_nsec3s, nsec3_ttl);
|
List nsec3s = finishNSEC3s(proto_nsec3s, nsec3_ttl);
|
||||||
@ -730,14 +751,20 @@ public class SignUtils
|
|||||||
// }
|
// }
|
||||||
records.addAll(nsec3s);
|
records.addAll(nsec3s);
|
||||||
|
|
||||||
NSEC3PARAMRecord nsec3param = new NSEC3PARAMRecord(zonename, DClass.IN,
|
NSEC3PARAMRecord nsec3param = new NSEC3PARAMRecord(
|
||||||
nsec3param_ttl, NSEC3Record.SHA1_DIGEST_ID, (byte) 0, iterations, salt);
|
zonename,
|
||||||
|
DClass.IN,
|
||||||
|
nsec3param_ttl,
|
||||||
|
NSEC3Record.SHA1_DIGEST_ID,
|
||||||
|
(byte) 0, iterations,
|
||||||
|
salt);
|
||||||
records.add(nsec3param);
|
records.add(nsec3param);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateOptOutNSEC3Records(Name zonename, List records,
|
public static void generateOptOutNSEC3Records(Name zonename, List records,
|
||||||
List includedNames, byte[] salt, int iterations)
|
List includedNames,
|
||||||
|
byte[] salt, int iterations)
|
||||||
throws NoSuchAlgorithmException
|
throws NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
List proto_nsec3s = new ArrayList();
|
List proto_nsec3s = new ArrayList();
|
||||||
@ -799,11 +826,7 @@ public class SignUtils
|
|||||||
// At this point, r represents the start of a new node.
|
// At this point, r represents the start of a new node.
|
||||||
// So we move current_node to last_node and generate a new current node.
|
// So we move current_node to last_node and generate a new current node.
|
||||||
// But first, we need to do something with the last node.
|
// But first, we need to do something with the last node.
|
||||||
generateNSEC3ForNode(last_node,
|
generateNSEC3ForNode(last_node, zonename, salt, iterations, true,
|
||||||
zonename,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
true,
|
|
||||||
proto_nsec3s);
|
proto_nsec3s);
|
||||||
|
|
||||||
if (current_node.isSecureNode)
|
if (current_node.isSecureNode)
|
||||||
@ -819,29 +842,27 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
// process last two nodes.
|
// process last two nodes.
|
||||||
generateNSEC3ForNode(last_node,
|
generateNSEC3ForNode(last_node, zonename, salt, iterations, true,
|
||||||
zonename,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
true,
|
|
||||||
proto_nsec3s);
|
proto_nsec3s);
|
||||||
generateNSEC3ForNode(current_node,
|
generateNSEC3ForNode(current_node, zonename, salt, iterations, true,
|
||||||
zonename,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
true,
|
|
||||||
proto_nsec3s);
|
proto_nsec3s);
|
||||||
|
|
||||||
List nsec3s = finishNSEC3s(proto_nsec3s, nsec3_ttl);
|
List nsec3s = finishNSEC3s(proto_nsec3s, nsec3_ttl);
|
||||||
records.addAll(nsec3s);
|
records.addAll(nsec3s);
|
||||||
|
|
||||||
NSEC3PARAMRecord nsec3param = new NSEC3PARAMRecord(zonename, DClass.IN,
|
NSEC3PARAMRecord nsec3param = new NSEC3PARAMRecord(
|
||||||
nsec3param_ttl, NSEC3Record.SHA1_DIGEST_ID, (byte) 0, iterations, salt);
|
zonename,
|
||||||
|
DClass.IN,
|
||||||
|
nsec3param_ttl,
|
||||||
|
NSEC3Record.SHA1_DIGEST_ID,
|
||||||
|
(byte) 0, iterations,
|
||||||
|
salt);
|
||||||
records.add(nsec3param);
|
records.add(nsec3param);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void generateNSEC3ForNode(NodeInfo node, Name zonename,
|
private static void generateNSEC3ForNode(NodeInfo node, Name zonename,
|
||||||
byte[] salt, int iterations, boolean optIn, List nsec3s)
|
byte[] salt, int iterations,
|
||||||
|
boolean optIn, List nsec3s)
|
||||||
throws NoSuchAlgorithmException
|
throws NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
if (node == null) return;
|
if (node == null) return;
|
||||||
@ -858,38 +879,28 @@ public class SignUtils
|
|||||||
{
|
{
|
||||||
Name n = new Name(node.name, i);
|
Name n = new Name(node.name, i);
|
||||||
log.fine("Generating ENT NSEC3 for " + n);
|
log.fine("Generating ENT NSEC3 for " + n);
|
||||||
ProtoNSEC3 nsec3 = generateNSEC3(n,
|
ProtoNSEC3 nsec3 = generateNSEC3(n, zonename, node.ttl, salt, iterations,
|
||||||
zonename,
|
optIn, null);
|
||||||
node.ttl,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
optIn,
|
|
||||||
null);
|
|
||||||
nsec3s.add(nsec3);
|
nsec3s.add(nsec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtoNSEC3 nsec3 = generateNSEC3(node.name,
|
ProtoNSEC3 nsec3 = generateNSEC3(node.name, zonename, node.ttl, salt,
|
||||||
zonename,
|
iterations, optIn, node.getTypes());
|
||||||
node.ttl,
|
|
||||||
salt,
|
|
||||||
iterations,
|
|
||||||
optIn,
|
|
||||||
node.getTypes());
|
|
||||||
nsec3s.add(nsec3);
|
nsec3s.add(nsec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ProtoNSEC3 generateNSEC3(Name name, Name zonename, long ttl,
|
private static ProtoNSEC3 generateNSEC3(Name name, Name zonename, long ttl,
|
||||||
byte[] salt, int iterations, boolean optIn, int[] types)
|
byte[] salt, int iterations,
|
||||||
|
boolean optIn, int[] types)
|
||||||
throws NoSuchAlgorithmException
|
throws NoSuchAlgorithmException
|
||||||
{
|
{
|
||||||
byte[] hash = NSEC3Record.hash(name,
|
byte[] hash = NSEC3Record.hash(name, NSEC3Record.SHA1_DIGEST_ID,
|
||||||
NSEC3Record.SHA1_DIGEST_ID,
|
iterations, salt);
|
||||||
iterations,
|
|
||||||
salt);
|
|
||||||
byte flags = (byte) (optIn ? 0x01 : 0x00);
|
byte flags = (byte) (optIn ? 0x01 : 0x00);
|
||||||
|
|
||||||
ProtoNSEC3 r = new ProtoNSEC3(hash, name, zonename, DClass.IN, ttl,
|
ProtoNSEC3 r = new ProtoNSEC3(hash, name, zonename, DClass.IN, ttl, flags,
|
||||||
flags, NSEC3Record.SHA1_DIGEST_ID, iterations, salt, null, types);
|
NSEC3Record.SHA1_DIGEST_ID, iterations, salt,
|
||||||
|
null, types);
|
||||||
|
|
||||||
log.finer("Generated: " + r);
|
log.finer("Generated: " + r);
|
||||||
return r;
|
return r;
|
||||||
@ -960,23 +971,27 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a canonical (by name) ordered list of records in a zone, generate
|
* Given a canonical (by name) ordered list of records in a zone, generate the
|
||||||
* the NSEC records in place.
|
* NSEC records in place.
|
||||||
*
|
*
|
||||||
* Note that the list that the records are stored in must support the
|
* Note that the list that the records are stored in must support the
|
||||||
* <code>listIterator.add</code> operation.
|
* <code>listIterator.add</code> operation.
|
||||||
*
|
*
|
||||||
* @param zonename the name of the zone apex, used to distinguish between
|
* @param zonename
|
||||||
|
* the name of the zone apex, used to distinguish between
|
||||||
* authoritative and delegation NS RRsets.
|
* authoritative and delegation NS RRsets.
|
||||||
* @param records a list of {@link org.xbill.DNS.Record}s in DNSSEC
|
* @param records
|
||||||
* canonical order.
|
* a list of {@link org.xbill.DNS.Record}s in DNSSEC canonical order.
|
||||||
* @param includeNames a list of names that should be in the NXT chain
|
* @param includeNames
|
||||||
* regardless. This may be null.
|
* a list of names that should be in the NXT chain regardless. This
|
||||||
* @param beConservative if true, then Opt-In NXTs will only be generated
|
* may be null.
|
||||||
* where there is actually a span of insecure delegations.
|
* @param beConservative
|
||||||
|
* if true, then Opt-In NXTs will only be generated where there is
|
||||||
|
* actually a span of insecure delegations.
|
||||||
*/
|
*/
|
||||||
public static void generateOptInNSECRecords(Name zonename, List records,
|
public static void generateOptInNSECRecords(Name zonename, List records,
|
||||||
List includeNames, boolean beConservative)
|
List includeNames,
|
||||||
|
boolean beConservative)
|
||||||
{
|
{
|
||||||
// This works by iterating over a known sorted list of records.
|
// This works by iterating over a known sorted list of records.
|
||||||
|
|
||||||
@ -1035,7 +1050,8 @@ public class SignUtils
|
|||||||
last_node.addType(Type.NSEC);
|
last_node.addType(Type.NSEC);
|
||||||
}
|
}
|
||||||
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
||||||
last_node.ttl, current_node.name, last_node.getTypes());
|
last_node.ttl, current_node.name,
|
||||||
|
last_node.getTypes());
|
||||||
// Note: we have to add this through the iterator, otherwise
|
// Note: we have to add this through the iterator, otherwise
|
||||||
// the next access via the iterator will generate a
|
// the next access via the iterator will generate a
|
||||||
// ConcurrencyModificationException.
|
// ConcurrencyModificationException.
|
||||||
@ -1075,7 +1091,8 @@ public class SignUtils
|
|||||||
last_node.addType(Type.NSEC);
|
last_node.addType(Type.NSEC);
|
||||||
}
|
}
|
||||||
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
NSECRecord nsec = new NSECRecord(last_node.name, last_node.dclass,
|
||||||
last_node.ttl, current_node.name, last_node.getTypes());
|
last_node.ttl, current_node.name,
|
||||||
|
last_node.getTypes());
|
||||||
records.add(last_node.nsecIndex - 1, nsec);
|
records.add(last_node.nsecIndex - 1, nsec);
|
||||||
log.finer("Generated: " + nsec);
|
log.finer("Generated: " + nsec);
|
||||||
}
|
}
|
||||||
@ -1110,12 +1127,16 @@ public class SignUtils
|
|||||||
* Given a zone with DNSKEY records at delegation points, convert those KEY
|
* Given a zone with DNSKEY records at delegation points, convert those KEY
|
||||||
* records into their corresponding DS records in place.
|
* records into their corresponding DS records in place.
|
||||||
*
|
*
|
||||||
* @param zonename the name of the zone, used to reliably distinguish the
|
* @param zonename
|
||||||
* zone apex from other records.
|
* the name of the zone, used to reliably distinguish the zone apex
|
||||||
* @param records a list of {@link org.xbill.DNS.Record} objects.
|
* from other records.
|
||||||
* @param digest_id The digest algorithm to use.
|
* @param records
|
||||||
|
* a list of {@link org.xbill.DNS.Record} objects.
|
||||||
|
* @param digest_alg
|
||||||
|
* The digest algorithm to use.
|
||||||
*/
|
*/
|
||||||
public static void generateDSRecords(Name zonename, List records, int digest_id)
|
public static void generateDSRecords(Name zonename, List records,
|
||||||
|
int digest_alg)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (ListIterator i = records.listIterator(); i.hasNext();)
|
for (ListIterator i = records.listIterator(); i.hasNext();)
|
||||||
@ -1129,8 +1150,7 @@ public class SignUtils
|
|||||||
// Convert non-zone level KEY records into DS records.
|
// Convert non-zone level KEY records into DS records.
|
||||||
if (r.getType() == Type.DNSKEY && !r_name.equals(zonename))
|
if (r.getType() == Type.DNSKEY && !r_name.equals(zonename))
|
||||||
{
|
{
|
||||||
DSRecord ds = calculateDSRecord((DNSKEYRecord) r,
|
DSRecord ds = calculateDSRecord((DNSKEYRecord) r, digest_alg,
|
||||||
DSRecord.SHA1_DIGEST_ID,
|
|
||||||
r.getTTL());
|
r.getTTL());
|
||||||
|
|
||||||
i.set(ds);
|
i.set(ds);
|
||||||
@ -1141,8 +1161,10 @@ public class SignUtils
|
|||||||
/**
|
/**
|
||||||
* Given a zone, remove all records that are generated.
|
* Given a zone, remove all records that are generated.
|
||||||
*
|
*
|
||||||
* @param zonename the name of the zone.
|
* @param zonename
|
||||||
* @param records a list of {@link org.xbill.DNS.Record} objects.
|
* the name of the zone.
|
||||||
|
* @param records
|
||||||
|
* a list of {@link org.xbill.DNS.Record} objects.
|
||||||
*/
|
*/
|
||||||
public static void removeGeneratedRecords(Name zonename, List records)
|
public static void removeGeneratedRecords(Name zonename, List records)
|
||||||
{
|
{
|
||||||
@ -1159,12 +1181,12 @@ public class SignUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove duplicate records from a list of records. This routine presumes
|
* Remove duplicate records from a list of records. This routine presumes the
|
||||||
* the list of records is in a canonical sorted order, at least on name and
|
* list of records is in a canonical sorted order, at least on name and RR
|
||||||
* RR type.
|
* type.
|
||||||
*
|
*
|
||||||
* @param records a list of {@link org.xbill.DNS.Record} object, in sorted
|
* @param records
|
||||||
* order.
|
* a list of {@link org.xbill.DNS.Record} object, in sorted order.
|
||||||
*/
|
*/
|
||||||
public static void removeDuplicateRecords(List records)
|
public static void removeDuplicateRecords(List records)
|
||||||
{
|
{
|
||||||
@ -1189,14 +1211,17 @@ public class SignUtils
|
|||||||
/**
|
/**
|
||||||
* Given a DNSKEY record, generate the DS record from it.
|
* Given a DNSKEY record, generate the DS record from it.
|
||||||
*
|
*
|
||||||
* @param keyrec the KEY record in question.
|
* @param keyrec
|
||||||
* @param digest_id The digest ID.
|
* the KEY record in question.
|
||||||
* @param ttl the desired TTL for the generated DS record. If zero, or
|
* @param digest_alg
|
||||||
* negative, the original KEY RR's TTL will be used.
|
* The digest algorithm (SHA-1, SHA-256, etc.).
|
||||||
|
* @param ttl
|
||||||
|
* the desired TTL for the generated DS record. If zero, or negative,
|
||||||
|
* the original KEY RR's TTL will be used.
|
||||||
* @return the corresponding {@link org.xbill.DNS.DSRecord}
|
* @return the corresponding {@link org.xbill.DNS.DSRecord}
|
||||||
*/
|
*/
|
||||||
public static DSRecord calculateDSRecord(DNSKEYRecord keyrec,
|
public static DSRecord calculateDSRecord(DNSKEYRecord keyrec, int digest_alg,
|
||||||
int digest_id, long ttl)
|
long ttl)
|
||||||
{
|
{
|
||||||
if (keyrec == null) return null;
|
if (keyrec == null) return null;
|
||||||
|
|
||||||
@ -1211,7 +1236,7 @@ public class SignUtils
|
|||||||
{
|
{
|
||||||
byte[] digest;
|
byte[] digest;
|
||||||
|
|
||||||
switch (digest_id)
|
switch (digest_alg)
|
||||||
{
|
{
|
||||||
case DSRecord.SHA1_DIGEST_ID:
|
case DSRecord.SHA1_DIGEST_ID:
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||||
@ -1223,12 +1248,12 @@ public class SignUtils
|
|||||||
digest = sha.getDigest();
|
digest = sha.getDigest();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown digest id: " + digest_id);
|
throw new IllegalArgumentException("Unknown digest id: " + digest_alg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DSRecord(keyrec.getName(), keyrec.getDClass(), ttl, keyrec
|
return new DSRecord(keyrec.getName(), keyrec.getDClass(), ttl,
|
||||||
.getFootprint(), keyrec.getAlgorithm(), digest_id,
|
keyrec.getFootprint(), keyrec.getAlgorithm(),
|
||||||
digest);
|
digest_alg, digest);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e)
|
catch (NoSuchAlgorithmException e)
|
||||||
|
Loading…
Reference in New Issue
Block a user